diff -u --recursive --new-file v2.5.0/linux/CREDITS linux/CREDITS --- v2.5.0/linux/CREDITS Sun Nov 11 10:09:32 2001 +++ linux/CREDITS Wed Dec 5 13:02:14 2001 @@ -140,9 +140,11 @@ D: VIA MVP-3/TX Pro III chipset IDE N: Jens Axboe -E: axboe@image.dk -D: Linux CD-ROM maintainer -D: jiffies wrap fixes + schedule timeouts depending on HZ == 100 +E: axboe@suse.de +D: Linux CD-ROM maintainer, DVD support +D: elevator + block layer rewrites +D: highmem I/O support +D: misc hacking on IDE, SCSI, block drivers, etc S: Peter Bangs Vej 258, 2TH S: 2500 Valby S: Denmark @@ -1147,6 +1149,16 @@ S: London SE16 1GD S: United Kingdom +N: Jan Harkes +E: jaharkes@cs.cmu.edu +W: http://www.coda.cs.cmu.edu/ +D: Coda file system +S: Computer Science Department +S: Carnegie Mellon University +S: 5000 Forbes Avenue +S: Pittsburgh, Pennsylvania 15213 +S: USA + N: Kai Harrekilde-Petersen E: kai.harrekilde@get2net.dk D: Original author of the ftape-HOWTO, i82078 fdc detection code. @@ -2063,7 +2075,7 @@ S: USA N: Patrick Mochel -E: pat@osdl.org +E: mochel@osdl.org E: mochelp@infinity.powertie.org D: PCI Power Management, ACPI work S: 15275 SW Koll Parkway, Suite H diff -u --recursive --new-file v2.5.0/linux/Documentation/Changes linux/Documentation/Changes --- v2.5.0/linux/Documentation/Changes Mon Sep 17 23:10:44 2001 +++ linux/Documentation/Changes Fri Nov 30 08:53:20 2001 @@ -2,13 +2,13 @@ ===== This document is designed to provide a list of the minimum levels of -software necessary to run the 2.4 kernels, as well as provide brief +software necessary to run the 2.5 kernels, as well as provide brief instructions regarding any other "Gotchas" users may encounter when -trying life on the Bleeding Edge. If upgrading from a pre-2.2.x -kernel, please consult the Changes file included with 2.2.x kernels for +trying life on the Bleeding Edge. If upgrading from a pre-2.4.x +kernel, please consult the Changes file included with 2.4.x kernels for additional information; most of that information will not be repeated here. Basically, this document assumes that your system is already -functional and running at least 2.2.x kernels. +functional and running at least 2.4.x kernels. This document is originally based on my "Changes" file for 2.0.x kernels and therefore owes credit to the same people as that file (Jared Mauch, @@ -31,7 +31,7 @@ Eine deutsche Version dieser Datei finden Sie unter . -Last updated: May 9, 2001 +Last updated: November 29, 2001 Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu). @@ -43,14 +43,14 @@ running, the suggested command should tell you. Again, keep in mind that this list assumes you are already -functionally running a Linux 2.2 kernel. Also, not all tools are +functionally running a Linux 2.4 kernel. Also, not all tools are necessary on all systems; obviously, if you don't have any PCMCIA (PC Card) hardware, for example, you probably needn't concern yourself with pcmcia-cs. o Gnu C 2.95.3 # gcc --version o Gnu make 3.77 # make --version -o binutils 2.9.1.0.25 # ld -v +o binutils 2.9.5.0.24 # ld -v o util-linux 2.10o # fdformat --version o modutils 2.4.2 # insmod -V o e2fsprogs 1.19 # tune2fs @@ -70,9 +70,9 @@ necessarily to users of other CPUs. Users of other CPUs should obtain information about their gcc version requirements from another source. -The recommended compiler for the kernel is gcc 2.95.3 or .4, and it +The recommended compiler for the kernel is gcc 2.95.x (x >= 3), and it should be used when you need absolute stability. You may use gcc 3.0.x -instead if you wish, although it may cause problems. Later versions of gcc +instead if you wish, although it may cause problems. Later versions of gcc have not received much testing for Linux kernel compilation, and there are almost certainly bugs (mainly, but not exclusively, in the kernel) that will need to be fixed in order to use these compilers. In any case, using @@ -106,12 +106,6 @@ your kernel. This change does, however, mean that you need a recent release of binutils. -If you can, upgrade to the latest 2.9.5 or 2.10 binutils release. Older -releases such as 2.8, 2.8.xx, and the FSF's 2.9.1 should be avoided if -at all possible. The later releases of 2.9.1.0.x (anything where x >= 22) -can and do compile the kernel properly, but there are many benefits in -upgrading to 2.9.5 or 2.10 if you're up to it. - System utils ============ @@ -276,7 +270,7 @@ gcc 2.95.3 ---------- -o +o Gnu Make ******** @@ -287,21 +281,14 @@ Binutils ******** - -2.9.1 series ------------- -o - -2.9.5 and 2.10 series ---------------------- -o +o System utilities **************** Util-linux ---------- -o +o Ksymoops -------- diff -u --recursive --new-file v2.5.0/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.5.0/linux/Documentation/Configure.help Thu Nov 22 10:52:44 2001 +++ linux/Documentation/Configure.help Fri Nov 30 13:25:10 2001 @@ -2,10 +2,10 @@ # Eric S. Raymond # Steven Cole # -# Merged version 2.49: Current with 2.4.15-pre1 and 2.4.13-ac8. +# Merged version 2.61: current with 2.4.16/2.5.1-pre1. # # This version of the Linux kernel configuration help texts -# corresponds to the kernel versions 2.4.x. +# corresponds to kernel versions 2.4.x and 2.5.x. # # Translations of this file available on the WWW: # @@ -14,11 +14,13 @@ # - Russian, by , at # # - French, by Pierre Tane , at -# +# # - Polish, by Dominik Mierzejewski , at # -# - German, by SuSE, at . This patch +# - German, by SuSE, at . This patch # also includes infrastructure to support different languages. +# - Catalan, by Antoni Bella , at +# # # To access a document on the WWW, you need to have a direct Internet # connection and a browser program such as netscape or lynx. If you @@ -133,8 +135,8 @@ See also the , , , - and the SMP-FAQ on the WWW at - . + and the SMP-HOWTO available at + . If you don't know what to do here, say N. @@ -577,7 +579,7 @@ To fine-tune ATA/IDE drive/interface parameters for improved performance, look for the hdparm package at - . + . If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -666,12 +668,9 @@ CD-ROM drive, you can say N to all other CD-ROM options, but be sure to say Y or M to "ISO 9660 CD-ROM file system support". - Read the CD-ROM-HOWTO, available from - and - . Note that older versions of lilo - (the Linux boot loader) cannot properly deal with IDE/ATAPI CD-ROMs, - so install lilo-16 or higher, available from - . + Note that older versions of LILO (LInux LOader) cannot properly deal + with IDE/ATAPI CD-ROMs, so install LILO 16 or higher, available from + . If you want to compile the driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -820,7 +819,7 @@ for these drives, but you can change that by saying Y to the following question "Use DMA by default when available". You can get the latest version of the hdparm utility from - . + . Read the comments at the beginning of and the file for more information. @@ -899,7 +898,7 @@ It is normally safe to answer Y; however, the default is N. -ATA Work(s) In Progress (EXPERIMENTAL)‹ +ATA Work(s) In Progress (EXPERIMENTAL) CONFIG_IDEDMA_PCI_WIP If you enable this you will be able to use and test highly developmental projects. If you say N, the configurator will @@ -914,7 +913,7 @@ Pacific Digital A-DMA support (EXPERIMENTAL) CONFIG_BLK_DEV_PDC_ADMA - Please read the comments at the top of . + Please read the comments at the top of . 3ware Hardware ATA-RAID support CONFIG_BLK_DEV_3W_XXXX_RAID @@ -1118,11 +1117,13 @@ Special UDMA Feature CONFIG_PDC202XX_BURST - For PDC20246, PDC20262, PDC20265 and PDC20267 Ultra DMA chipsets. - Designed originally for PDC20246/Ultra33 that has BIOS setup - failures when using 3 or more cards. + This option causes the pdc202xx driver to enable UDMA modes on the + PDC202xx even when the PDC202xx BIOS has not done so. - Unknown for PDC20265/PDC20267 Ultra DMA 100. + It was originally designed for the PDC20246/Ultra33, whose BIOS will + only setup UDMA on the first two PDC20246 cards. It has also been + used succesfully on a PDC20265/Ultra100, allowing use of UDMA modes + when the PDC20265 BIOS has been disabled (for faster boot up). Please read the comments at the top of . @@ -1251,15 +1252,6 @@ and files for more info. -# This is for Linus's tree. -QDI QD6580 support -CONFIG_BLK_DEV_QD6580 - This driver is enabled at runtime using the "ide0=qd6580" kernel - boot parameter. It permits faster I/O speeds to be set. See the - and for - more info. - -# This is for Alan's tree. Note the name difference. QDI QD65XX support CONFIG_BLK_DEV_QD65XX This driver is enabled at runtime using the "ide0=qd65xx" kernel @@ -1488,7 +1480,7 @@ CONFIG_PARIDE_PG This option enables a special high-level driver for generic ATAPI devices connected through a parallel port. The driver allows user - programs, such as cdrecord, to send ATAPI commands directly to a + programs, such as cdrtools, to send ATAPI commands directly to a device. If you chose to build PARIDE support into your kernel, you may @@ -1502,7 +1494,7 @@ This driver implements an API loosely related to the generic SCSI driver. See . for details. - You can obtain the most recent version of cdrecord from + You can obtain the most recent version of cdrtools from . Versions 1.6.1a3 and later fully support this driver. @@ -1716,9 +1708,9 @@ controller, you do not need to say Y here. More information about Software RAID on Linux is contained in the - Software-RAID mini-HOWTO, available from - . There you will also - learn where to get the supporting user space utilities raidtools. + Software RAID mini-HOWTO, available from + . There you will also learn + where to get the supporting user space utilities raidtools. If unsure, say N. @@ -1811,7 +1803,6 @@ If unsure, say N. -# AC tree only Support for IDE Raid controllers CONFIG_BLK_DEV_ATARAID Say Y or M if you have an IDE Raid controller and want linux @@ -1824,7 +1815,6 @@ has its own Raid drivers, which you should use if you need better performance. -# AC tree only Support Promise software RAID (Fasttrak(tm)) CONFIG_BLK_DEV_ATARAID_PDC Say Y or M if you have a Promise Fasttrak (tm) Raid controller @@ -1835,7 +1825,6 @@ If you choose to compile this as a module, the module will be called pdcraid.o. -# AC tree only Highpoint 370 software RAID CONFIG_BLK_DEV_ATARAID_HPT Say Y or M if you have a Highpoint HPT 370 Raid controller @@ -1851,19 +1840,19 @@ This is a machine with a R4400 133/150 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - . + . Support for Algorithmics P4032 (EXPERIMENTAL) CONFIG_ALGOR_P4032 This is an evaluation board of the British company Algorithmics. The board uses the R4300 and a R5230 CPUs. For more information - about this board see . + about this board see . Support for BAGET MIPS series CONFIG_BAGET_MIPS This enables support for the Baget, a Russian embedded system. For more details about the Baget see the Linux/MIPS FAQ on - . + . Baget AMD LANCE support CONFIG_BAGETLANCE @@ -1874,8 +1863,8 @@ Support for DECstations CONFIG_DECSTATION This enables support for DEC's MIPS based workstations. For details - see the Linux/MIPS FAQ on and the - DECstation porting pages on . + see the Linux/MIPS FAQ on and the + DECstation porting pages on . If you have one of the following DECstation Models you definitely want to choose R4xx0 for the CPU Type: @@ -1904,7 +1893,7 @@ Support for the Momentum Computer Ocelot SBC CONFIG_MOMENCO_OCELOT The Ocelot is a MIPS-based Single Board Computer (SBC) made by - Momentum Computer . + Momentum Computer . Support for NEC DDB Vrc-5074 CONFIG_DDB5074 @@ -1917,7 +1906,7 @@ evaluation board. Features : kernel debugging, serial terminal, NFS root fs, on-board - ether port (Need an additional patch at ), + ether port (Need an additional patch at ), USB, AC97, PCI, PCI VGA card & framebuffer console, IDE controller, PS2 keyboard, PS2 mouse, etc. @@ -1927,7 +1916,7 @@ evaluation board. Features : kernel debugging, serial terminal, NFS root fs, on-board - ether port (Need an additional patch at ), + ether port (Need an additional patch at ), USB, AC97, PCI, etc. Support for MIPS Atlas board @@ -1953,7 +1942,7 @@ This is a machine with a R4000 100 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - . + . Enable Qtronix 990P Keyboard Support CONFIG_QTRONIX_KEYBOARD @@ -1965,7 +1954,7 @@ This is a machine with a R4000 100 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - . + . Support for SNI RM200 PCI CONFIG_SNI_RM200_PCI @@ -2072,7 +2061,7 @@ CONFIG_PCMCIA_NINJA_SCSI If you intend to attach this type of PCMCIA SCSI host adapter to your computer, say Y here and read - . + . This driver is also available as a module called nsp_cs.o ( = code which can be inserted in and removed from the running kernel @@ -2263,7 +2252,7 @@ of which are given in . For a general introduction to Linux networking, it is highly - recommended to read the NET-3-HOWTO, available from + recommended to read the NET-HOWTO, available from . Socket filtering @@ -2658,6 +2647,23 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +Multiple port match support +CONFIG_IP6_NF_MATCH_MULTIPORT + Multiport matching allows you to match TCP or UDP packets based on + a series of source or destination ports: normally a rule can only + match a single range of ports. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + +Owner match support +CONFIG_IP6_NF_MATCH_OWNER + Packet owner matching allows you to match locally-generated packets + based on who created them: the user, group, process or session. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + Packet filtering CONFIG_IP6_NF_FILTER Packet filtering defines a table `filter', which has a series of @@ -2724,6 +2730,14 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +LOG target support +CONFIG_IP6_NF_TARGET_LOG + This option adds a `LOG' target, which allows you to create rules in + any iptables table which records the packet header to the syslog. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + SYN flood protection CONFIG_SYN_COOKIES Normal TCP/IP networking is open to an attack known as "SYN @@ -2776,7 +2790,7 @@ To find out what type of Alpha system you have, you may want to check out the Linux/Alpha FAQ, accessible on the WWW from - . In summary: + . In summary: Alcor/Alpha-XLT AS 600 Alpha-XL XL-233, XL-266 @@ -2961,7 +2975,7 @@ which is command line driven, and ARC, which uses menus and arrow keys. Details about the Linux/Alpha booting process are contained in the Linux/Alpha FAQ, accessible on the WWW from - . + . The usual way to load Linux on an Alpha machine is to use MILO (a bootloader that lets you pass command line parameters to the @@ -3130,7 +3144,7 @@ The user level application needed to use this driver can be found at the IBM Linux Technology Center (LTC) web site: - http://www.ibm.com/linux/ltc/ + . If you own one of the above IBM Thinkpads which has the Mwave chipset in it, say Y. @@ -3505,7 +3519,7 @@ example, used on modern desktops as well as laptops, is USB. Enable HOTPLUG and KMOD, and build a modular kernel. Get agent - software (at ) and install it. + software (at ) and install it. Then your kernel will automatically call out to a user mode "policy agent" (/sbin/hotplug) to load modules and set up software needed to use devices as you hotplug them. @@ -3547,6 +3561,12 @@ If unsure, say Y. +i82092 compatible bridge support +CONFIG_I82092 + This provides support for the Intel I82092AA PCI-to-PCMCIA bridge device, + found in some older laptops and more commonly in evaluation boards for the + chip. + i82365 compatible host bridge support CONFIG_I82365 Say Y here to include support for ISA-bus PCMCIA host bridges that @@ -3821,7 +3841,7 @@ The program SVGATextMode can be used to utilize SVGA video cards to their full potential in text mode. Download it from - . + . Say Y. @@ -4053,21 +4073,18 @@ module will be called aty128fb.o. If you want to compile it as a module, say M here and read . -# AC tree only Maxine (Personal DECstation) onboard framebuffer support CONFIG_FB_MAXINE Say Y here to directly support the on-board framebuffer in the Maxine (5000/20, /25, /33) version of the DECstation. There is a page dedicated to Linux on DECstations at . -# AC tree only PMAG-BA TURBOchannel framebuffer support CONFIG_FB_PMAG_BA Say Y here to directly support the on-board PMAG-BA framebuffer in the 5000/1xx versions of the DECstation. There is a page dedicated to Linux on DECstations at . -# AC tree only PMAGB-B TURBOchannel framebuffer support CONFIG_FB_PMAGB_B Say Y here to directly support the on-board PMAGB-B framebuffer in @@ -4079,10 +4096,32 @@ Say Y here if you intend to run this kernel on a FutureTV (nee Nexus Electronics) StrongARM PCI card. -P720T -CONFIG_ARCH_P720T - Say Y here if you intend to run this kernel on the ARM Prospector - 720T. +ANAKIN Vehicle Telematics Platform +CONFIG_ARCH_ANAKIN + The Anakin is a StrongArm based SA110 - 2 DIN Vehicle Telematics Platform. + 64MB SDRAM - 4 Mb Flash - Compact Flash Interface - 1 MB VRAM + + On board peripherals: + * Front display: 400x234 16 bit TFT touchscreen + * External independent second screen interface + * CAN controller SJA1000 + * USB host controller + * 6 channel video codec with hardware overlay + * Smartcard reader + * IrDa + + Modules interfaced over the Multi Media Extension slots: + * A communication card + Wavecom GPRS modem + uBlock GPS + Bosch DAB module + * An audio card ( 4 * 40W, AC97 Codec, I2S) + +Altera Excalibur XA10 Dev Board +ARCH_CAMELOT + This enables support for Altera's Excalibur XA10 development board. + If you would like to build your kernel to run on one of these boards + then you must say 'Y' here. Otherwise say 'N' Link-Up Systems LCD support CONFIG_FB_L7200 @@ -4306,10 +4345,8 @@ a module, say M here and read . You can pass several parameters to the driver at boot time or at - module load time. The parameters look like "video=matrox:XXX", where - the meaning of XXX can be found at the end of the main source file - (). Please see - . + module load time. The parameters look like "video=matrox:XXX", and + are described in . Matrox Millennium I/II support CONFIG_FB_MATROX_MILLENIUM @@ -4372,7 +4409,7 @@ The driver starts in monitor mode and you must use the matroxset tool (available at - ) to switch it to + ) to switch it to PAL or NTSC or to swap primary and secondary head outputs. Secondary head driver also always start in 640x480 resolution, you must use fbset to change it. @@ -4394,7 +4431,7 @@ The driver starts in monitor mode and currently does not support output in TV modes. You must use the matroxset tool (available - at ) to swap + at ) to swap primary and secondary head outputs. Secondary head driver always start in 640x480 resolution and you must use fbset to change it. @@ -4509,14 +4546,12 @@ This is the frame buffer device driver for the SiS 630 and 640 Super Socket 7 UMA cards. Specs available at . -# AC tree only SIS 630/540/730 support CONFIG_FB_SIS_300 This is the frame buffer device driver for the SiS 630 and related Super Socket 7 UMA cards. Specs available at . -# AC tree only SIS 315H/315 support CONFIG_FB_SIS_315 This is the frame buffer device driver for the SiS 315 graphics @@ -4570,7 +4605,6 @@ is at . -# AC tree only ATI Radeon display support CONFIG_FB_RADEON Choose this option if you want to use an ATI Radeon graphics card as @@ -4697,7 +4731,8 @@ drive, PLIP link (Parallel Line Internet Protocol is mainly used to create a mini network by connecting the parallel ports of two local machines) etc., then you need to say Y here; please read - and drivers/parport/BUGS-parport. + and + . For extensive information about drivers for many devices attaching to the parallel port see on @@ -5186,7 +5221,7 @@ used for local networks of Windows machines. You need it if you want to access Novell NetWare file or print servers using the Linux Novell client ncpfs (available from - ) or from + ) or from within the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from ). In order to do the former, you'll also have to say Y to "NCP file system @@ -5198,8 +5233,8 @@ To turn your Linux box into a fully featured NetWare file server and IPX router, say Y here and fetch either lwared from - or - mars_nwe from . For more + or + mars_nwe from . For more information, read the IPX-HOWTO available from . @@ -5235,7 +5270,7 @@ 'special' sockets to sockets listening on the primary network is disabled. This might break existing applications, especially RIP/SAP daemons. A RIP/SAP daemon that works well with the full internal net - can be found on . + can be found on . If you don't know what you are doing, say N. @@ -5303,7 +5338,7 @@ network link driver", "Routing messages" and "Network packet filtering". The first two are required to allow configuration via rtnetlink (currently you need Alexey Kuznetsov's iproute2 package - from ). The "Network packet filtering" option + from ). The "Network packet filtering" option will be required for the forthcoming routing daemon to work. See for more information. @@ -5424,9 +5459,8 @@ Amateur Radio support CONFIG_HAMRADIO If you want to connect your Linux box to an amateur radio, answer Y - here. You want to read - and the HAM-HOWTO and the AX25-HOWTO, both available from - . + here. You want to read and + the AX25-HOWTO, available from . Note that the answer to this question won't directly affect the kernel: saying N will just cause the configurator to skip all @@ -5633,7 +5667,7 @@ connect to a parallel interface. The driver supports the picpar and par96 designs. To configure the driver, use the sethdlc utility available in the standard ax25 utilities package. For information on - the modems, see and the file + the modems, see and the file . If you want to compile this driver as a module ( = code which can be @@ -5647,7 +5681,7 @@ connect to a parallel interface. The driver supports the EPP designs. To configure the driver, use the sethdlc utility available in the standard ax25 utilities package. For information on the - modems, see and the file + modems, see and the file . If you want to compile this driver as a module ( = code which can be @@ -5666,7 +5700,7 @@ driver and still provided in case this driver does not work with your serial interface chip. To configure the driver, use the sethdlc utility available in the standard ax25 utilities package. For - information on the modems, see and + information on the modems, see and . If you want to compile this driver as a module ( = code which can be @@ -5683,7 +5717,7 @@ the full-duplex driver. This driver is depreciated. To configure the driver, use the sethdlc utility available in the standard ax25 utilities package. For information on the modems, see - and + and . If you want to compile this driver as a module ( = code which can be @@ -5860,7 +5894,7 @@ - etc... For more informations, please refer to: - + If unsure, say N. @@ -5921,8 +5955,7 @@ user processes. It does so by creating a new socket family, PF_NETLINK. Over this socket, the kernel can send and receive datagrams carrying information. It is documented on many systems in - netlink(7), a HOWTO is provided as well, for example on - . + netlink(7). So far, the kernel uses this feature to publish some network related information if you say Y to "Routing messages", below. You also need @@ -5938,7 +5971,7 @@ CONFIG_RTNETLINK If you say Y here, user space programs can receive some network related routing information over the netlink. 'rtmon', supplied - with the iproute2 package (), can read and + with the iproute2 package (), can read and interpret this data. Information sent to the kernel over this link is ignored. @@ -6225,7 +6258,7 @@ control memory (128K-1KVC, 512K-4KVC), the size of the packet memory (128K, 512K, 1M), and the PHY type (Single/Multi mode OC3, UTP155, UTP25, DS3 and E3). Go to: - www.iphase.com/products/ClassSheet.cfm?ClassID=ATM + for more info about the cards. Say Y (or M to compile as a module named iphase.o) here if you have one of these cards. @@ -6238,7 +6271,7 @@ messages is controlled by a bitmap. This may be specified as a module argument (kernel command line argument as well?), changed dynamically using an ioctl (Get the debug utility, iadbg, from - ). + ). See the file for the meanings of the bits in the mask. @@ -6490,12 +6523,6 @@ You also need to say Y here if you want support for the parallel port version of the 100 MB IOMEGA ZIP drive. - Please read the SCSI-HOWTO, available from - . The - SCSI-Programming-HOWTO contains information about how to add or - remove an SCSI device from a running Linux machine without - rebooting. - This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). The module will be called scsi_mod.o. If you want to compile it as @@ -6573,7 +6600,7 @@ tape drives (ADR-x0) that supports the standard SCSI-2 commands for tapes (QIC-157) and can be driven by the standard driver st. For more information, you may have a look at the SCSI-HOWTO - and + and in the kernel source. More info on the OnStream driver may be found on @@ -6628,12 +6655,12 @@ directly, so you need some additional software which knows how to talk to these devices using the SCSI protocol: - For scanners, look at SANE (). For CD - writer software look at cdrecord + For scanners, look at SANE (). For CD + writer software look at Cdrtools () - and for burning a "disk at once": cdrdao - (). Cdparanoia is a high - quality digital reader of audio CDs (). + and for burning a "disk at once": CDRDAO + (). Cdparanoia is a high + quality digital reader of audio CDs (). For other devices, it's possible that you'll have to write the driver software yourself. Please read the file for more information. @@ -6644,17 +6671,6 @@ . The module will be called sg.o. If unsure, say N. -Enable extra checks in SCSI queueing code -CONFIG_SCSI_DEBUG_QUEUES - This option turns on a lot of additional consistency checking for - the new queueing code. This will adversely affect performance, but - it is likely that bugs will be caught sooner if this is turned on. - This will typically cause the kernel to panic if an error is - detected, but it would have probably crashed if the panic weren't - there. Comments/questions/problems to linux-scsi mailing list - please. See for more - up-to-date information. - Probe all LUNs on each SCSI device CONFIG_SCSI_MULTI_LUN If you have a SCSI device that supports more than one LUN (Logical @@ -6941,10 +6957,10 @@ This is support for BusLogic MultiMaster and FlashPoint SCSI Host Adapters. Consult the SCSI-HOWTO, available from , and the files - README.BusLogic and README.FlashPoint in drivers/scsi for more - information. If this driver does not work correctly without - modification, please contact the author, Leonard N. Zubkoff, by - email to lnz@dandelion.com. + and + for more information. If this + driver does not work correctly without modification, please contact + the author, Leonard N. Zubkoff, by email to lnz@dandelion.com. You can also build this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -7186,7 +7202,7 @@ If your system has problems using this new major version of the SYM53C8XX driver, you may switch back to driver version 1. - Please read drivers/scsi/sym53c8xx_2/Documentation.txt for more + Please read for more information. PCI DMA addressing mode @@ -7727,7 +7743,7 @@ NCR53c406a SCSI support CONFIG_SCSI_NCR53C406A This is support for the NCR53c406a SCSI host adapter. For user - configurable parameters, check out + configurable parameters, check out in the kernel source. Also read the SCSI-HOWTO, available from . @@ -7839,7 +7855,8 @@ This is a driver for RAID/SCSI Disk Array Controllers (EISA/ISA/PCI) manufactured by Intel/ICP vortex (an Intel Company). It is documented - in the kernel source in drivers/scsi/gdth.c and drivers/scsi/gdth.h. + in the kernel source in and + This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -8252,8 +8269,8 @@ Normally, your access provider has to support SLIP in order for you to be able to use it, but there is now a SLIP emulator called SLiRP - around (available via FTP (user: anonymous) from - ) which + around (available from + ) which allows you to use SLIP over a regular dial up shell connection. If you plan to use SLiRP, make sure to say Y to CSLIP, below. The NET-3-HOWTO, available from @@ -8278,7 +8295,7 @@ on both ends. Ask your access provider if you are not sure and answer Y, just in case. You will still be able to use plain SLIP. If you plan to use SLiRP, the SLIP emulator (available from - ) which + ) which allows you to use SLIP over a regular dial up shell connection, you definitely want to say Y here. The NET-3-HOWTO, available from , explains how to configure @@ -8415,7 +8432,7 @@ This driver requires a specially patched pppd daemon. The patch to pppd, along with binaries of a patched pppd package can be found at: - . + . Wireless LAN (non-hamradio) CONFIG_NET_RADIO @@ -8437,7 +8454,7 @@ Some user-level drivers for scarab devices which don't require special kernel support are available from - . + . STRIP (Metricom Starmode radio IP) CONFIG_STRIP @@ -8783,12 +8800,6 @@ configure your card and that /etc/pcmcia/wireless.opts works : -Apple Airport support (built-in) -CONFIG_APPLE_AIRPORT - Enable support for the Apple Airport card (which is essentially a - Lucent Orinoco card with a non-standard interface) built into some - newer Apple Macintosh machines. - Hermes 802.11b in PLX9052 based PCI adaptor support CONFIG_PLX_HERMES Enable support for PCMCIA cards supported by the "Hermes" (aka @@ -8870,7 +8881,8 @@ CONFIG_APPLE_AIRPORT Say Y here to support the Airport 802.11b wireless Ethernet hardware built into the Macintosh iBook and other recent PowerPC-based - Macintosh machines. + Macintosh machines. This is essentially a Lucent Orinoco card with + a non-standard interface Xircom Netwave AirSurfer wireless support CONFIG_PCMCIA_NETWAVE @@ -9118,7 +9130,7 @@ the price of an external router. If you have one of those cards and wish to use your Linux box as a WAN router, say Y here and also to the WAN driver for your card, below. You will then need the - wan-tools package which is available from . + wan-tools package which is available from . Read for more information. @@ -9500,7 +9512,7 @@ up. Look at the for more information about the cards (including the pointer to the user-space utilities). You can also read the comment at the top of the - for details about the cards and the driver + for details about the cards and the driver itself. The driver will be compiled as a module ( = code which can be @@ -9512,7 +9524,7 @@ CONFIG_DSCC4 This is a driver for Etinc PCISYNC boards based on the Infineon (ex. Siemens) DSCC4 chipset. It is supposed to work with the four - ports card. Take a look at + ports card. Take a look at for further informations about the driver and his configuration. The driver will be compiled as a module ( = code which can be @@ -9539,7 +9551,7 @@ additional external hardware. To change setting such as syncPPP vs cisco HDLC or clock source you - will need lmcctl. It is available at . + will need lmcctl. It is available at . This code is also available as a module called lmc.o ( = code which can be inserted in and removed from the running kernel @@ -9584,7 +9596,7 @@ module will be called sbni.o). You can find more information and last versions of drivers and - utilities at . If you have any question you + utilities at . If you have any question you can send email to sbni@granch.ru. Say N if unsure. @@ -9607,7 +9619,7 @@ Router". You will need the wan-tools package which is available from - . Read + . Read for more information. Note that the answer to this question won't directly affect the @@ -9616,7 +9628,7 @@ Sangoma WANPIPE(tm) multiprotocol cards CONFIG_VENDOR_SANGOMA - WANPIPE from Sangoma Technologies Inc. () + WANPIPE from Sangoma Technologies Inc. () is a family of intelligent multiprotocol WAN adapters with data transfer rates up to 4Mbps. They are also known as Synchronous Data Link Adapters (SDLA) and are designated as S514-PCI or @@ -9704,7 +9716,7 @@ Read for help on configuring and using COMX interfaces. Further info on these cards - can be found at or . + can be found at or . You must say Y to "/proc file system support" (CONFIG_PROC_FS) to use this driver. @@ -9798,8 +9810,8 @@ Cyclom 2X(tm) multiprotocol cards CONFIG_CYCLADES_SYNC - Cyclom 2X from Cyclades Corporation ( and - is an intelligent multiprotocol WAN + Cyclom 2X from Cyclades Corporation ( and + ) is an intelligent multiprotocol WAN adapter with data transfer rates up to 512 Kbps. These cards support the X.25 and SNA related protocols. If you have one or more of these cards, say Y to this option. The next questions will ask you about @@ -9808,10 +9820,10 @@ While no documentation is available at this time please grab the wanconfig tarball in - (with minor changes + (with minor changes to make it compile with the current wanrouter include files; efforts are being made to use the original package available at - ). + ). Feel free to contact me or the cycsyn-devel mailing list at acme@conectiva.com.br and cycsyn-devel@bazar.conectiva.com.br for @@ -10288,15 +10300,7 @@ is a 10Mbit/sec Ethernet controller. Product overview and specs at . -CompactFlash Connection Area -CONFIG_CF_AREA5 - If your board has "Directly Connected" CompactFlash, You should - select the area where your CF is connected to. - - - "Area5" if CompactFlash is connected to Area 5 (0x14000000) - - "Area6" if it is connected to Area 6 (0x18000000) - - "Area6" will work for most boards. For ADX, select "Area5". + If unsure, say N. 3COM cards CONFIG_NET_VENDOR_3COM @@ -10643,7 +10647,7 @@ module, say M here and read as well as . -EtherExpressPro support/EtherExpress 10 (i82595) support +EtherExpressPro and EtherExpress 10 (i82595) support CONFIG_EEXPRESS_PRO If you have a network (Ethernet) card of this type, say Y. This driver supports intel i82595{FX,TX} based boards. Note however @@ -10787,10 +10791,7 @@ driver and as a module ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read - as well as . - If you plan to use more than one network card under linux, read the - Multiple-Ethernet-mini-HOWTO, available from - . The only + as well as . The only currently supported card is the IBM LAN Adapter/A for Ethernet. It will both support 16K and 32K memory windows, however a 32K window gives a better security against packet losses. Usage of multiple @@ -10957,7 +10958,7 @@ CONFIG_FEALNX Say Y here to support the Mysom MTD-800 family of PCI-based Ethernet cards. Specifications and data at - . + . ICL EtherTeam 16i/32 support CONFIG_ETH16I @@ -11004,7 +11005,7 @@ Davicom DM910x/DM980x support CONFIG_DM9102 This driver is for DM9102(A)/DM9132/DM9801 compatible PCI cards from - Davicom (). If you have such a network + Davicom (). If you have such a network (Ethernet) card, say Y. Some information is contained in the file . @@ -11189,8 +11190,7 @@ Wake On Lan, and PCI 100/16/4 adapters. If you have such an adapter, say Y and read the Token-Ring - mini-HOWTO, available from - . + mini-HOWTO, available from . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -11199,15 +11199,14 @@ Also read or check the Linux Token Ring Project site for the latest information at - . + . IBM Lanstreamer chipset PCI adapter support CONFIG_IBMLS This is support for IBM Lanstreamer PCI Token Ring Cards. If you have such an adapter, say Y and read the Token-Ring - mini-HOWTO available via FTP (user:anonymous) from - . + mini-HOWTO, available from . This driver is also available as a modules ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -11358,7 +11357,7 @@ say Y to "QoS and/or fair queueing" above. To set up and configure shaper devices, you need the shapecfg - program, available from in the + program, available from in the shaper package. This driver is also available as a module ( = code which can be @@ -11619,7 +11618,7 @@ Say Y here only if you have two CD-ROM controller cards of this type (usually only if you have more than four drives). You should enter the parameters for the second, third and fourth interface card into - before compiling the new kernel. Read + before compiling the new kernel. Read the file . Matsushita/Panasonic, ... third CD-ROM controller support @@ -12394,6 +12393,100 @@ NVRAM on the Momenco Ocelot board. If you have one of these boards and would like access to either of these, say 'Y'. +Support for absent chips in bus mapping +CONFIG_MTD_ABSENT + This option enables support for a dummy probing driver used to + allocated placeholder MTD devices on systems that have socketed + or removable media. Use of this driver as a fallback chip probe + preserves the expected registration order of MTD device nodes on + the system regardless of media presence. Device nodes created + with this driver will return -ENODEV upon access. + +MTD Emulation using block device +CONFIG_MTD_BLKMTD + This driver allows a block device to appear as an MTD. It would + generally be used in the following cases: + + Using Compact Flash as an MTD, these usually present themselves to + the system as an ATA drive. + Testing MTD users (eg JFFS2) on large media and media that might + be removed during a write (using the floppy drive). + +Cirrus CDB89712 evaluation board mappings +CONFIG_MTD_CDB89712 + This enables access to the flash or ROM chips on the CDB89712 board. + If you have such a board, say 'Y'. + +Detect non-CFI AMD/JEDEC-compatible flash chips +CONFIG_MTD_JEDECPROBE + This option enables JEDEC-style probing of flash chips which are not + compatible with the Common Flash Interface, but will use the common + CFI-targetted flash drivers for any chips which are identified which + are in fact compatible in all but the probe method. This actually + covers most AMD/Fujitsu-compatible chips, and will shortly cover also + non-CFI Intel chips (that code is in MTD CVS and should shortly be sent + for inclusion in Linus' tree) + +BIOS flash chip on Intel L440GX boards +CONFIG_MTD_L440GX + Support for treating the BIOS flash chip on Intel L440GX motherboards + as an MTD device - with this you can reprogram your BIOS. + + BE VERY CAREFUL. + +28F160xx flash driver for LART +CONFIG_MTD_LART + This enables the flash driver for LART. Please note that you do + not need any mapping/chip driver for LART. This one does it all + for you, so go disable all of those if you enabled some of them (: + +Older (theoretically obsoleted now) drivers for non-CFI chips +CONFIG_MTD_OBSOLETE_CHIPS + This option does not enable any code directly, but will allow you to + select some other chip drivers which are now considered obsolete, + because the generic CONFIG_JEDEC_PROBE code above should now detect + the chips which are supported by these drivers, and allow the generic + CFI-compatible drivers to drive the chips. Say 'N' here unless you have + already tried the CONFIG_JEDEC_PROBE method and reported its failure + to the MTD mailing list at + +CFI Flash device mapped on Hitachi SolutionEngine +CONFIG_MTD_SOLUTIONENGINE + This enables access to the flash chips on the Hitachi SolutionEngine and + similar boards. Say 'Y' if you are building a kernel for such a board. + +Flash chip mapping on TQM8xxL PPC board +CONFIG_MTD_TQM8XXL + The TQM8xxL PowerPC board has up to two banks of CFI-compliant + chips, currently uses AMD one. This 'mapping' driver supports + that arrangement, allowing the CFI probe and command set driver + code to communicate with the chips on the TQM8xxL board. More at + . + +Darkness +CONFIG_MEMORY_SET + This is an option about which you will never be asked a question. + Therefore, I conclude that you do not exist - go away. + + There is a grue here. + +Physical memory size +CONFIG_MEMORY_SIZE + This sets the default memory size assumed by your SH kernel. It can + be overridden as normal by the 'mem=' argument on the kernel command + line. If unsure, consult your board specifications or just leave it + as 0x00400000 which was the default value before this became + configurable. + +Cache and PCI noncoherent +CONFIG_SH_PCIDMA_NONCOHERENT + Enable this option if your platform does not have a CPU cache which + remains coherent with PCI DMA. It is safest to say 'Y', although you + will see better performance if you can say 'N', because the PCI DMA + code will not have to flush the CPU's caches. If you have a PCI host + bridge integrated with your SH CPU, refer carefully to the chip specs + to see if you can say 'N' here. Otherwise, leave it as 'Y'. + USB (Universal Serial Bus) support CONFIG_USB Universal Serial Bus (USB) is a specification for a serial bus @@ -12579,7 +12672,7 @@ This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). The module will be called aiptek.o. If you want to compile it as a - module, say M here and read Documentation/modules.txt. + module, say M here and read . Use input layer for ADB devices CONFIG_INPUT_ADBHID @@ -12740,7 +12833,7 @@ CONFIG_USB_SERIAL_VISOR Say Y here if you want to connect to your HandSpring Visor, Palm m500 or m505 through its USB docking station. See - for more information on using this + for more information on using this driver. This code is also available as a module ( = code which can be @@ -12759,6 +12852,17 @@ The module will be called ir-usb.o. If you want to compile it as a module, say M here and read . +USB IR Dongle Serial Driver +CONFIG_USB_SERIAL_IR + Say Y here if you want to enable simple serial support for USB IrDA + devices. This is useful if you do not want to use the full IrDA + stack. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called ir-usb.o. If you want to compile it as a + module, say M here and read . + USB Belkin and Paracom Single Port Serial Driver CONFIG_USB_SERIAL_BELKIN Say Y here if you want to use a Belkin USB Serial single port @@ -12776,7 +12880,7 @@ converter device. The implementation I have is called the USC-1000. This driver has also be tested with the 245 and 232 devices. - See http://ftdi-usb-sio.sourceforge.net for more + See for more information on this driver and the device. This code is also available as a module ( = code which can be @@ -13013,7 +13117,7 @@ This driver supports devices conforming to the Communication Device Class Ethernet Control Model. This is used in some cable modems. For more details on the specification, get the Communication Device - Class specification from . + Class specification from . This driver should work with the following devices: * Ericsson PipeRider (all variants) @@ -13140,7 +13244,7 @@ Say Y here if you want to connect this type of still camera to your computer's USB port. See for more information; some non-Kodak cameras may also work with this - driver, given application support (such as ). + driver, given application support (such as ). This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -13151,7 +13255,7 @@ CONFIG_USB_MDC800 Say Y here if you want to connect this type of still camera to your computer's USB port. This driver can be used with gphoto 0.4.3 - and higher (look at ). + and higher (look at ). To use it create a device node with "mknod /dev/mustek c 180 32" and configure it in your software. @@ -13255,7 +13359,7 @@ DABUSB driver CONFIG_USB_DABUSB A Digital Audio Broadcasting (DAB) Receiver for USB and Linux - brought to you by the DAB-Team (). This + brought to you by the DAB-Team (). This driver can be taken as an example for URB-based bulk, control, and isochronous transactions. URB's are explained in . @@ -13493,7 +13597,7 @@ running UML to exchange packets with its host over one of the host's Ethertap devices, such as /dev/tap0. Additional running UMLs can use additional Ethertap devices, one per running UML. - While the UML believes its on a (multi-device, broadcast) virtual + While the UML believes it's on a (multi-device, broadcast) virtual Ethernet network, it's in fact communicating over a point-to-point link with the host. @@ -13588,7 +13692,7 @@ CONFIG_USB_BLUETOOTH Say Y here if you want to connect a USB Bluetooth device to your computer's USB port. You will need the Bluetooth stack (available - at to fully use + at ) to fully use the device. This code is also available as a module ( = code which can be @@ -13624,7 +13728,7 @@ In general, ReiserFS is as fast as ext2, but is very efficient with large directories and small files. Additional patches are needed - for NFS and quotas, please see for links. + for NFS and quotas, please see for links. It is more easily extended to have features currently found in database and keyword search systems than block allocation based file @@ -13632,7 +13736,7 @@ plugins consistent with our motto ``It takes more than a license to make source code open.'' - Read to learn more about reiserfs. + Read to learn more about reiserfs. Sponsored by Threshold Networks, Emusic.com, and Bigstorage.com. @@ -13660,15 +13764,6 @@ everyone but ReiserFS developers and people fine-tuning reiserfs or tracing problems should say N. -Publish some reiserfs-specific info under /proc/fs/reiserfs -CONFIG_REISERFS_PROC_INFO - Create under /proc/fs/reiserfs hierarchy of files, displaying - various ReiserFS statistics and internal data on the expense of - making your kernel or module slightly larger (+8K). This also increases - amount of kernel memory required for each mount. Almost everyone - but ReiserFS developers and people fine-tuning reiserfs or tracing - problems should say NO. - Second extended fs support CONFIG_EXT2_FS This is the de facto standard Linux file system (method to organize @@ -13698,10 +13793,10 @@ directories on ext2 file systems, use chattr ("man chattr"). Ext2fs partitions can be read from within DOS using the ext2tool - command line tool package (available via FTP (user: anonymous) from - ) and from + command line tool package (available from + ) and from within Windows NT using the ext2nt command line tool package from - . Explore2fs is a + . Explore2fs is a graphical explorer for ext2fs partitions which runs on Windows 95 and Windows NT and includes experimental write support; it is available from @@ -13901,7 +13996,7 @@ which allows for long filenames in unicode format (unicode is the new 16 bit character code, successor to ASCII, which encodes the characters of almost all languages of the world; see - for more information). Say Y here if you + for more information). Say Y here if you want to be able to read Joliet CD-ROMs under Linux. Transparent decompression extension @@ -13986,7 +14081,7 @@ Linux, you can either use the DOS emulator DOSEMU, described in the DOSEMU-HOWTO, available from , or try dmsdosfs in - . If you + . If you intend to use dosemu with a non-compressed MSDOS partition, say Y here) and MSDOS floppies. This means that file access becomes transparent, i.e. the MSDOS files look and behave just like all @@ -14161,8 +14256,9 @@ level IP autoconfiguration" above and to "Root file system on NFS" below. You cannot compile this driver as a module in this case. There are two packages designed for booting diskless machines over - the net: netboot and etherboot, both available via FTP from - . + the net: netboot, available from + , and Etherboot, + available from . If you don't know what all this is about, say N. @@ -14285,7 +14381,7 @@ a set of kernel modules that lets you run SCO, Xenix, Wyse, UnixWare, Dell Unix and System V programs under Linux. It is available via FTP (user: ftp) from - ). + ). NOTE: that will work only for binaries from Intel-based systems; PDP ones will have to wait until somebody ports Linux to -11 ;-) @@ -14414,7 +14510,7 @@ automounter (amd), which is a pure user space daemon. To use the automounter you need the user-space tools from - ; you also + ; you also want to answer Y to "NFS file system support", below. If you want to compile this as a module ( = code which can be @@ -14478,6 +14574,11 @@ If reporting bugs, please try to have available a full dump of the messages at debug level 1 while the misbehaviour was occurring. +JFFS stats available in /proc filesystem +CONFIG_JFFS_PROC_FS + Enabling this option will cause statistics from mounted JFFS file systems + to be made available to the user in the /proc/fs/jffs/ directory. + UFS file system support (read-only) CONFIG_UFS_FS BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD, @@ -14578,7 +14679,7 @@ XP. Technical documentation to accompany this driver is available from: - . + . If unsure, say N. @@ -14706,7 +14807,6 @@ Note that the experimental "/dev file system support" (CONFIG_DEVFS_FS) is a more general facility. -# This is for Linus's tree FreeVxFS file system support (VERITAS VxFS(TM) compatible) CONFIG_VXFS_FS FreeVxFS is a file system driver that support the VERITAS VxFS(TM) @@ -14725,25 +14825,6 @@ module, say M here and read . If unsure, say N. -# This is for Alan's tree. Note the name difference. -FreeVxFS file system support (VERITAS VxFS(TM) compatible) -CONFIG_FREEVXFS_FS - FreeVxFS is a file system driver that support the VERITAS VxFS(TM) - file system format. VERITAS VxFS(TM) is the standard file system - of SCO UnixWare (and possibly others) and optionally available - for Sunsoft Solaris, HP-UX and many other operating systems. - Currently only readonly access is supported. - - NOTE: the file system type as used by mount(1), mount(2) and - fstab(5) is 'vxfs' as it describes the filesystem format, not - the actual driver. - - This file system is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module is called freevxfs.o. If you want to compile it as a - module, say M here and read . If - unsure, say N. - UnixWare slices support CONFIG_UNIXWARE_DISKLABEL Like some systems, UnixWare uses its own slice table inside a @@ -14777,8 +14858,8 @@ Note: if you just want your box to act as an SMB *server* and make files and printing services available to Windows clients (which need to have a TCP/IP stack), you don't need to say Y here; you can use - the program samba (available via FTP (user: anonymous) in - ) for that. + the program SAMBA (available from ) + for that. General information about how to connect Linux, Windows machines and Macs is on the WWW at . @@ -14827,7 +14908,7 @@ client and server. Servers are currently user level, i.e. they need no kernel support. Please read and check out the Coda - home page . + home page . If you want to compile the coda client support as a module ( = code which can be inserted in and removed from the running kernel @@ -14843,7 +14924,7 @@ If you say Y or M your kernel or module will provide InterMezzo support. You will also need a file server daemon, which you can get - from . + from . NCP file system support (to mount NetWare volumes) CONFIG_NCP_FS @@ -15495,7 +15576,7 @@ CONFIG_ADB_IOP The I/O Processor (IOP) is an Apple custom IC designed to provide intelligent support for I/O controllers. It is described at - to enable direct + to enable direct support for it, say 'Y' here. Mac II style Apple Desktop Bus support @@ -16204,9 +16285,7 @@ Say Y here if your machine has a bus mouse as opposed to a serial mouse. Most people have a regular serial MouseSystem or Microsoft mouse (made by Logitech) that plugs into a COM port - (rectangular with 9 or 25 pins). These people say N here. If you - have something else, read the Busmouse-HOWTO, available from - , and say Y here. + (rectangular with 9 or 25 pins). These people say N here. If you have a laptop, you either have to check the documentation or experiment a bit to find out whether the trackball is a serial mouse @@ -16271,8 +16350,8 @@ When using a PS/2 mouse, you can get problems if you want to use the mouse both on the Linux console and under X. Using the "-R" option of the Linux mouse managing program gpm (available from - ) solves this - problem, or you can get the "mconv2" utility from the same location. + ) solves this problem, or you can get + the "mconv2" utility from . C&T 82C710 mouse port support (as on TI Travelmate) CONFIG_82C710_MOUSE @@ -16391,7 +16470,7 @@ Note that the Ftape-HOWTO is out of date (sorry) and documents the older version 2.08 of this software but still contains useful information. There is a web page with more recent documentation at - . This page + . This page always contains the latest release of the ftape driver and useful information (backup software, ftape related patches and documentation, FAQ). Note that the file system interface has @@ -16427,7 +16506,7 @@ file contains a short description of the most important changes in the file system interface compared to previous versions of ftape. The ftape home page - contains + contains further information. IMPORTANT NOTE: zftape can read archives created by previous @@ -16670,7 +16749,7 @@ introduced in XFree86 4.0. If you say Y here, you need to select the module that's right for your graphics card from the list below. These modules provide support for synchronization, security, and - DMA transfers. Please see for more + DMA transfers. Please see for more details. You should also select and configure AGP (/dev/agpgart) support. @@ -16925,8 +17004,8 @@ can be downloaded from: . - The ACPI mailing list may also be of interest: - . + The ACPI Sourceforge project may also be of interest: + Enable ACPI 2.0 with errata 1.3 CONFIG_ACPI20 @@ -17136,9 +17215,9 @@ in the kernel source. The watchdog is usually used together with the watchdog daemon - which is available via FTP (user: anonymous) from - . This daemon can also - monitor NFS connections and can reboot the machine when the process + which is available from + . This daemon can + also monitor NFS connections and can reboot the machine when the process table is full. If unsure, say N. @@ -17212,7 +17291,7 @@ and if it does, it reboots your computer after a certain amount of time. This driver is like the WDT501 driver but for different hardware. Please read . The PC - watchdog cards can be ordered from . + watchdog cards can be ordered from . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17446,7 +17525,6 @@ The module will be called nvram.o. If you want to compile it as a module, say M here and read . -# Linus tree only Joystick support CONFIG_JOYSTICK If you have a joystick, 6dof controller, gamepad, steering wheel, @@ -17454,18 +17532,17 @@ enable generic support for these controllers. You will also need to say Y or M to at least one of the hardware specific drivers. This will make the controllers available as /dev/input/jsX devices. - Please read the file which + Please read the file which contains more information and the location of the joystick package that you'll need. -# AC tree only Game port support CONFIG_INPUT_GAMEPORT Gameport support is for the standard 15-pin PC gameport. If you have a joystick, gamepad, gameport card, a soundcard with a gameport or anything else that uses the gameport, say Y or M here and also to at least one of the hardware specific drivers. - Please read the file which + Please read the file which contains more information and the location of the joystick package that you'll need if you use the gameport with a joystick. @@ -17478,7 +17555,7 @@ CONFIG_INPUT_NS558 Say Y here if you have an ISA or PnP gameport. For more information on how to use the driver please read - . + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17489,7 +17566,7 @@ CONFIG_INPUT_LIGHTNING Say Y here if you have a PDPI Lightning 4 gamecard. For more information on how to use the driver please read - . + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17511,7 +17588,7 @@ CONFIG_INPUT_PCIGAME Say Y here if you have a Trident 4DWave DX/NX or Aureal Vortex 1/2 card. For more information on how to use the driver please read - . + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17522,7 +17599,7 @@ CONFIG_INPUT_EMU10K1 Say Y here if you have a SoundBlaster Live! card and want to use its gameport. For more information on how to use the driver - please read . + please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17537,7 +17614,7 @@ additional hats and buttons compatible with CH Flightstick Pro, ThrustMaster FCS, 6 and 8 button gamepads, or Saitek Cyborg joysticks. For more information on how to use the driver please - read . + read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17548,7 +17625,7 @@ CONFIG_INPUT_A3D Say Y here if you have an FPGaming or MadCatz controller using the A3D protocol over the PC gameport. For more information on how to - use the driver please read . + use the driver please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17559,7 +17636,7 @@ CONFIG_INPUT_ADI Say Y here if you have a Logitech controller using the ADI protocol over the PC gameport. For more information on how to use - the driver please read . + the driver please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17570,7 +17647,7 @@ CONFIG_INPUT_COBRA Say Y here if you have a Creative Labs Blaster Cobra gamepad. For more information on how to use the driver please read - . + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17581,7 +17658,7 @@ CONFIG_INPUT_GF2K Say Y here if you have a Genius Flight2000 or MaxFighter digitally communicating joystick or gamepad. For more information on how to - use the driver please read . + use the driver please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17592,7 +17669,7 @@ CONFIG_INPUT_GRIP Say Y here if you have a Gravis controller using the GrIP protocol over the PC gameport. For more information on how to use the driver - please read . + please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17603,7 +17680,7 @@ CONFIG_INPUT_INTERACT Say Y hereif you have an InterAct gameport or joystick communicating digitally over the gameport. For more information on - how to use the driver please read . + how to use the driver please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17615,7 +17692,7 @@ Say Y here if you have a ThrustMaster controller using the DirectConnect (BSP) protocol over the PC gameport. For more information on how to use the driver please read - . + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17626,7 +17703,7 @@ CONFIG_INPUT_SIDEWINDER Say Y here if you have a Microsoft controller using the Digital Overdrive protocol over PC gameport. For more information on how to - use the driver please read . + use the driver please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17638,7 +17715,7 @@ Say Y here and to the Serial port input line discipline option if you plan to use a joystick that communicates over the serial (COM) port. For more information on how to use the driver please read - . + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17649,7 +17726,7 @@ CONFIG_INPUT_SERPORT Say Y here if you plan to use a joystick that communicates over the serial (COM) port. For more information on how to use the driver - please read . + please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17660,7 +17737,7 @@ CONFIG_INPUT_WARRIOR Say Y here if you have a Logitech WingMan Warrior joystick connected to your computer's serial port. For more information on how to use - the driver please read . + the driver please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17671,7 +17748,7 @@ CONFIG_INPUT_MAGELLAN Say Y here if you have a Magellan or Space Mouse 6DOF controller connected to your computer's serial port. For more information on - how to use the driver please read . + how to use the driver please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17683,7 +17760,7 @@ Say Y here if you have a SpaceOrb 360 or SpaceBall Avenger 6DOF controller connected to your computer's serial port. For more information on how to use the driver please read - . + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17694,7 +17771,7 @@ CONFIG_INPUT_SPACEBALL Say Y here if you have a SpaceTec SpaceBall 4000 FLX controller connected to your computer's serial port. For more information on - how to use the driver please read . + how to use the driver please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17705,7 +17782,7 @@ CONFIG_INPUT_STINGER Say Y here if you have a Gravis Stinger connected to one of your serial ports. For more information on how to use the driver please - read . + read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17716,7 +17793,7 @@ CONFIG_INPUT_IFORCE_232 Say Y here if you have an I-Force joystick or steering wheel connected to your serial (COM) port. For more information on how - to use the driver please read . + to use the driver please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17727,7 +17804,7 @@ CONFIG_INPUT_IFORCE_USB Say Y here if you have an I-Force joystick or steering wheel connected to your USB port. For more information on how to use the - driver please read . + driver please read . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17740,8 +17817,8 @@ gamepad, Sega Saturn gamepad, or a Multisystem -- Atari, Amiga, Commodore, Amstrad CPC joystick connected to your parallel port. For more information on how to use the driver please read - and - . + and + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17755,8 +17832,8 @@ Sony PlayStation gamepad or a Multisystem -- Atari, Amiga, Commodore, Amstrad CPC joystick connected to your parallel port. For more information on how to use the driver please read - and - . + and + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17768,8 +17845,8 @@ Say Y here if you have the TurboGraFX interface by Steffen Schwenke, and want to use it with Multisystem -- Atari, Amiga, Commodore, Amstrad CPC joystick. For more information on how to use the driver - please read and - . + please read and + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -17780,7 +17857,7 @@ CONFIG_INPUT_AMIJOY Say Y here if you have an Amiga with a digital joystick connected to it. For more information on how to use the driver please read - . + . This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -18353,7 +18430,7 @@ questions. Read the file and the head of - as well as + as well as to get more information about this driver and its configuration. @@ -18412,12 +18489,20 @@ or the CMI8378 chipset. Data on these chips are available at . + A userspace utility to control some internal registers of these + chips is available at + . + Support CMI8738 based audio cards CONFIG_SOUND_CMPCI_CM8738 Say Y or M if you have a PCI sound card using the CMI8338 or the CMI8378 chipset. Data on this chip is available at . + A userspace utility to control some internal registers of these + chips is available at + . + Enable joystick CONFIG_SOUND_CMPCI_JOYSTICK Say here in order to enable the joystick port on a sound crd using @@ -18435,13 +18520,19 @@ "The 8738 Audio SPDIF In/Out Technical Data" on the technical support page at . + A userspace utility to control even more internal registers of these + chips is available at + . + This package will among other things help you enable SPDIF + out/in/loop/monitor. + Creative SBLive! (EMU10K1) based PCI sound cards CONFIG_SOUND_EMU10K1 Say Y or M if you have a PCI sound card using the EMU10K1 chipset, such as the Creative SBLive!, SB PCI512 or Emu-APS. For more information on this driver and the degree of support for the - different card models please check . + different card models please check . It is now possible to load dsp microcode patches into the EMU10K1 chip. These patches are used to implement real time sound @@ -18674,7 +18765,7 @@ Support for ITE 8172G board CONFIG_MIPS_ITE8172 - Ths is an evaluation board made by ITE (http://www.ite.com.tw/) + Ths is an evaluation board made by ITE with ATX form factor that utilizes a MIPS R5000 to work with its ITE8172G companion internet appliance chip. The MIPS core can be either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build @@ -19188,7 +19279,7 @@ can be inserted in and removed from the running kernel whenever you want, details in ); the module will be called sc.o. See and - for more information. + for more information. Eicon active card support CONFIG_ISDN_DRV_EICON @@ -19330,7 +19421,7 @@ This enables support for the Auvertech TurboPAM ISDN-card. For running this card, additional firmware is necessary, which has to be downloaded into the card using a utility which is distributed - separately from the Auvertech's web site: . + separately from the Auvertech's web site: . Please redirect all support questions to support@auvertech.fr. @@ -19525,7 +19616,7 @@ It was designed as a replacement for cables and other short-range technologies like IrDA. Bluetooth operates in personal area range that typically extends up to 10 meters. More information about - Bluetooth can be found at . + Bluetooth can be found at . Linux Bluetooth subsystem consist of several layers: HCI Core (device and connection manager, scheduler) @@ -19538,7 +19629,7 @@ To use Linux Bluetooth subsystem, you will need several user-space utilities like hciconfig and hcid. These utilities and updates to Bluetooth kernel modules are provided in the BlueZ package. - For more information, see . + For more information, see . If you want to compile HCI Core as module (hci.o) say M here. @@ -19580,62 +19671,6 @@ # The following options are for Linux when running on the Hitachi # SuperH family of RISC microprocessors. -CPU Selection -CONFIG_CPU_SUBTYPE_SH7707 - This is the type of your Hitachi SuperH processor. This information is - used for optimizing and configuration purposes. - - - "SH7707" for SH7707 - - "SH7708" for SH7708, SH7708S, SH7708R - - "SH7709" for SH7707, SH7709, SH7709A, and SH7729. - - "SH7750" for SH7750, SH7750S - - "SH7751" for SH7751 - - "ST40STB1" for ST40STB1 - -Target machine selection -CONFIG_SH_GENERIC - This is machine type of your target. - - - "Generic" for Generic kernel which might support all of them - - "SolutionEngine" for Hitachi SolutionEngine (7709A, 7750, 7750S) - - "SolutionEngine7751" for Hitachi SolutionEngine (7751) - - "STB1_Harp" for STMicroelectronics HARP - - "STB1_Overdrive" for STMicroelectronics Overdrive - - "HP620" for HP 'Jornada' 620 - - "HP680" for HP 'Jornada' 680 - - "HP690" for HP 'Jornada' 690 - - "CqREEK" for CQ Publishing CqREEK SH-4 - - "DMIDA" for DMIDA, industrial data assistant - - "EC3104" for Compaq Aero 8000 - - "Dreamcast" for SEGA Dreamcast - - "CAT68701" for CAT 68701 Evaluation Board (SH7708) - - "BigSur" for Big Sur Evaluation Board - - "SH2000" for SH2000 Evaluation Board (SH7709A) - - "ADX" for A&D ADX - - "BareCPU" for Bare CPU board such as CqREEK SH-3 - - If unsure, select "BareCPU". - -Physical memory start address -CONFIG_MEMORY_START - Computers built with Hitachi SuperH processors always - map the ROM starting at address zero. But the processor - does not specify the range that RAM takes. RAM is usually - mapped starting at 0c000000, but it may be elsewhere. - - You should set this value to the address of the lowest - RAM location. - - A value of 0c000000 will work for most boards. - -Directly Connected Compact Flash support -CONFIG_CF_ENABLER - If your board has "Directly Connected" CompactFlash at area 5 or 6, - you may want to enable this option. Then, you can use CF as - primary IDE drive (only tested for SanDisk). - - If in doubt, press "n". - SuperH RTC support CONFIG_SH_RTC Selecting this option will allow the Linux kernel to emulate @@ -19650,38 +19685,7 @@ If unsure, say N. -SuperH SCI (serial) support -CONFIG_SH_SCI - Selecting this option will allow the Linux kernel to transfer - data over SCI (Serial Communication Interface) and/or SCIF - which are built into the Hitachi SuperH processor. - - If unsure, say N. - -Use LinuxSH standard BIOS -CONFIG_SH_STANDARD_BIOS - Say Y here if your target has the gdb-sh-stub package from - www.m17n.org (or any conforming standard LinuxSH BIOS) in FLASH - or EPROM. The kernel will use standard BIOS calls during boot - for various housekeeping tasks. Note this does not work with - WindowsCE machines. If unsure, say N. - -Early printk support -CONFIG_SH_EARLY_PRINTK - If you say Y here, the kernel printk routine will begin output to - the console much earlier in the boot process, before the serial - console is initialised, instead of buffering output. Standard - LinuxSH BIOS calls are used for the output. This helps when - debugging fatal problems early in the boot sequence. This is only - useful for kernel hackers. If unsure, say N. - -National Semiconductor DP83902AV 'ST-NIC' support -CONFIG_STNIC - If you have a network adaptor with National Semiconductor DP83902AV, - say Y or M (for module). - - If unsure, say N. - +# Choice: cf_area CompactFlash Connection Area CONFIG_CF_AREA5 If your board has "Directly Connected" CompactFlash, You should @@ -20483,7 +20487,7 @@ . Select APUS if configuring for a PowerUP Amiga. More information is - available at: . + available at: . Synergy-Gemini CONFIG_GEMINI @@ -20495,122 +20499,7 @@ CONFIG_APUS Select APUS if configuring for a PowerUP Amiga. More information is available at: - . - -Embedded 8xx Board Type -CONFIG_RPXLITE - RPX-Lite: - Embedded Planet RPX Lite - - RPX-Classic: - Embedded Planet RPX Classic Low-fat. - - BSE-IP: - Bright Star Engineering ip-Engine. - - TQM823L: - TQM850L: - TQM855L: - TQM860L: - MPC8xx based family of mini modules, half credit card size, - up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports, - 2 x CAN bus interface, ... - Manufacturer: TQ Components, www.tq-group.de - Date of Release: October (?) 1999 - End of Life: not yet :-) - URL: - - module: http://www.denx.de/PDF/TQM8xxLHWM201.pdf - - starter kit: http://www.denx.de/PDF/STK8xxLHWM201.pdf - - images: http://www.denx.de/embedded-ppc-en.html - - FPS850L: - FingerPrint Sensor System (based on TQM850L) - Manufacturer: IKENDI AG, http://www.ikendi.com/ - Date of Release: November 1999 - End of life: end 2000 ? - URL: see TQM850L - - SPD823TS: - MPC823 based board used in the "Tele Server" product - Manufacturer: Speech Design, http://www.speech-design.de/ - Date of Release: Mid 2000 (?) - End of life: - - URL: http://www.speech-design.de/ - select "English", then "Teleteam Solutions", then "TeleServer" - - IVMS8: - MPC860 based board used in the "Integrated Voice Mail System", - Small Version (8 voice channels) - Manufacturer: Speech Design, http://www.speech-design.de/ - Date of Release: December 2000 (?) - End of life: - - URL: http://www.speech-design.de/ - - IVML24: - MPC860 based board used in the "Integrated Voice Mail System", - Large Version (24 voice channels) - Manufacturer: Speech Design, http://www.speech-design.de/ - Date of Release: March 2001 (?) - End of life: - - URL: http://www.speech-design.de/ - - SM850: - Service Module (based on TQM850L) - Manufacturer: Dependable Computer Systems, http://www.decomsys.com/ - Date of Release: end 2000 (?) - End of life: mid 2001 (?) - URL: http://www.tz-mikroelektronik.de/ServiceModule/index.html - - HERMES: - Hermes-Pro ISDN/LAN router with integrated 8 x hub - Manufacturer: Multidata Gesellschaft für Datentechnik und Informatik - http://www.multidata.de/ - Date of Release: 2000 (?) - End of life: - - URL: http://www.multidata.de/english/products/hpro.htm - - IP860: - VMEBus IP (Industry Pack) carrier board with MPC860 - Manufacturer: MicroSys GmbH, http://www.microsys.de/ - Date of Release: ? - End of life: - - URL: http://www.microsys.de/html/ip860.html - - PCU_E: - PCU = Peripheral Controller Unit, Extended - Manufacturer: Siemens AG, ICN (Information and Communication Networks) - http://www.siemens.de/page/1,3771,224315-1-999_2_226207-0,00.html - Date of Release: April 2001 - End of life: August 2001 - URL: n. a. - -Embedded 82xx Board Type -CONFIG_EST8260 - EST8260: Wind River System, Inc. EST SBC8260 - - TQM8260: - MPC8260 based module, little larger than credit card, - up to 128 MB global + 64 MB local RAM, 32 MB Flash, - 32 kB EEPROM, 256 kB L@ Cache, 10baseT + 100baseT Ethernet, - 2 x serial ports, ... - Manufacturer: TQ Components, www.tq-group.de - Date of Release: June 2001 - End of Life: not yet :-) - URL: http://www.denx.de/PDF/TQM82xx_SPEC_Rev005.pdf - - PM826: - Modular system with MPC8260 CPU - Manufacturer: MicroSys GmbH, http://www.microsys.de/ - Date of Release: mid 2001 - End of life: - - URL: http://www.microsys.de/html/pm826.html - - CU824: - VMEBus Board with PCI extension with MPC8240 CPU - Manufacturer: MicroSys GmbH, http://www.microsys.de/ - Date of Release: early 2001 (?) - End of life: - - URL: http://www.microsys.de/html/cu824.html + . AltiVec Kernel Support CONFIG_ALTIVEC @@ -20684,26 +20573,97 @@ change the screen brightness. # Choice: ppc8xxtype -RPX-Lite +Embedded 8xx Board Type CONFIG_RPXLITE Single-board computers based around the PowerPC MPC8xx chips and intended for embedded applications. The following types are supported: - RPX-Lite -- PC104 form-factor SBC based on the MPC823 - RPX-Classic -- Credit-card-size SBC based on the MPC 860 - BSE-IP -- Bright Star Engineering BSE-IP SBC - TQM823L -- TQM823L SBC from TQ Components - TQM850L -- TQM850L SBC from TQ Components - TQM855L -- TQM855L SBC from TQ Components - TQM860L -- TQM860L SBC from TQ Components - FPS850L -- FingerPrint Sensor from TQ Components - TQM860 -- TQM860 SBC from IKENDI AG - SPD823TS -- Speech Design TeleServer from Speech Design - IVMS8 -- Integrated VoiceMail SBC from Speech Design - SM850 -- Service Module 850 from Dependable Computer Systems - MBX -- MBX821 and MBX860 SBCs - Wincept -- Wincept SBCs for thin-client machines + RPX-Lite: + Embedded Planet RPX Lite. PC104 form-factor SBC based on the MPC823. + + RPX-Classic: + Embedded Planet RPX Classic Low-fat. Credit-card-size SBC based on + the MPC 860 + + BSE-IP: + Bright Star Engineering ip-Engine. + + TQM823L: + TQM850L: + TQM855L: + TQM860L: + MPC8xx based family of mini modules, half credit card size, + up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports, + 2 x CAN bus interface, ... + Manufacturer: TQ Components, www.tq-group.de + Date of Release: October (?) 1999 + End of Life: not yet :-) + URL: + - module: + - starter kit: + - images: + + FPS850L: + FingerPrint Sensor System (based on TQM850L) + Manufacturer: IKENDI AG, + Date of Release: November 1999 + End of life: end 2000 ? + URL: see TQM850L + + SPD823TS: + MPC823 based board used in the "Tele Server" product + Manufacturer: Speech Design, + Date of Release: Mid 2000 (?) + End of life: - + URL: + select "English", then "Teleteam Solutions", then "TeleServer" + + IVMS8: + MPC860 based board used in the "Integrated Voice Mail System", + Small Version (8 voice channels) + Manufacturer: Speech Design, + Date of Release: December 2000 (?) + End of life: - + URL: + + IVML24: + MPC860 based board used in the "Integrated Voice Mail System", + Large Version (24 voice channels) + Manufacturer: Speech Design, + Date of Release: March 2001 (?) + End of life: - + URL: + + SM850: + Service Module (based on TQM850L) + Manufacturer: Dependable Computer Systems, + Date of Release: end 2000 (?) + End of life: mid 2001 (?) + URL: + + HERMES: + Hermes-Pro ISDN/LAN router with integrated 8 x hub + Manufacturer: Multidata Gesellschaft für Datentechnik und Informatik + + Date of Release: 2000 (?) + End of life: - + URL: + + IP860: + VMEBus IP (Industry Pack) carrier board with MPC860 + Manufacturer: MicroSys GmbH, + Date of Release: ? + End of life: - + URL: + + PCU_E: + PCU = Peripheral Controller Unit, Extended + Manufacturer: Siemens AG, ICN (Information and Communication Networks) + + Date of Release: April 2001 + End of life: August 2001 + URL: n. a. RPX-Classic CONFIG_RPXCLASSIC @@ -20831,7 +20791,7 @@ # Manufacturer: MicroSys GmbH, # Date of Release: early 2001 (?) # End of life: - -# URL: # # PM826: # Modular system with MPC8260 CPU @@ -20850,13 +20810,39 @@ # End of life: - # URL: n. a.o -Support for EST8260 +# Choice: ppc82xxtype +Embedded 82xx Board Type CONFIG_EST8260 - The EST8260 is a single-board computer manufactured by Wind River - Systems, Inc. (formerly Embedded Support Tools Corp.) and based on - the MPC8260. Wind River Systems has a website at - , but the EST8260 cannot be found on it - and has probably been discontinued or rebadged. + EST8260: + The EST8260 is a single-board computer manufactured by Wind River + Systems, Inc. (formerly Embedded Support Tools Corp.) and based on + the MPC8260. Wind River Systems has a website at + , but the EST8260 cannot be found on it + and has probably been discontinued or rebadged. + + TQM8260: + MPC8260 based module, little larger than credit card, + up to 128 MB global + 64 MB local RAM, 32 MB Flash, + 32 kB EEPROM, 256 kB L@ Cache, 10baseT + 100baseT Ethernet, + 2 x serial ports, ... + Manufacturer: TQ Components, www.tq-group.de + Date of Release: June 2001 + End of Life: not yet :-) + URL: + + PM826: + Modular system with MPC8260 CPU + Manufacturer: MicroSys GmbH, + Date of Release: mid 2001 + End of life: - + URL: + + CU824: + VMEBus Board with PCI extension with MPC8240 CPU + Manufacturer: MicroSys GmbH, http://www.microsys.de/ + Date of Release: early 2001 (?) + End of life: - + URL: ADB raw keycode support CONFIG_MAC_ADBKEYCODES @@ -20870,6 +20856,13 @@ If unsure, say Y here. +I2C/SPI Microcode Patch +UCODE_PATCH + Motorola releases microcode updates for their 8xx CPM modules. The + microcode update file has updates for IIC, SMC and USB. Currently only + the USB update is available by default, if the MPC8xx USB option is + enabled. If in doubt, say 'N' here. + Mouse button 2+3 emulation support CONFIG_MAC_EMUMOUSEBTN This provides generic support for emulating the 2nd and 3rd mouse @@ -21013,7 +21006,7 @@ Support for audio/video capture and overlay devices and FM radio cards. The exact capabilities of each device vary. User tools for this are available from - . + . If you are interested in writing a driver for such an audio/video device or user software interacting with such a driver, please read @@ -21399,7 +21392,7 @@ Miro DC10 and DC30 video capture cards). Include support for Iomega Buz -CONFIG_VIDEO_BUZ +CONFIG_VIDEO_ZORAN_BUZ Say Y here to include support for the Iomega Buz video card. There is a Buz/Linux homepage at . @@ -21452,8 +21445,8 @@ otherwise say N. This driver is also available as a module (w9966.o). - Check out and - for more information. + Check out for more + information. CPiA Video For Linux CONFIG_VIDEO_CPIA @@ -21577,25 +21570,23 @@ CONFIG_IPLABE. Support for 3215 line mode terminal -CONFIG_3215 - Include support for IBM 3215 line-mode terminals. Can't be used - if 3270 console support is chosen. +CONFIG_TN3215 + Include support for IBM 3215 line-mode terminals. Support for console on 3215 line mode terminal -CONFIG_3215_CONSOLE - Include support for using an IBM 3215 line-mode terminal as the - Linux system console. Can't be used if 3270 console support is - chosen. +CONFIG_TN3215_CONSOLE + Include support for using an IBM 3215 line-mode terminal as a + Linux system console. Support for 3270 line mode terminal -CONFIG_3270 +CONFIG_TN3270 Include support for IBM 3270 line-mode terminals. Support for console on 3270 line mode terminal -CONFIG_3270_CONSOLE - Include support for using an IBM 3270 line-mode terminal as the - Linux system console. Excludes using 3215s. Available only if 3270 - support is compiled in statically. +CONFIG_TN3270_CONSOLE + Include support for using an IBM 3270 line-mode terminal as a Linux + system console. Available only if 3270 support is compiled in + statically. Support for HWC line mode terminal CONFIG_HWC @@ -21846,7 +21837,7 @@ There are no product plans beyond the current research prototypes at this time. Information is available at: - + If you have any questions or comments about the Compaq Personal Server, send e-mail to skiff@crl.dec.com. @@ -21897,6 +21888,12 @@ Say Y if configuring for an Intrinsyc CerfBoard. Say N otherwise. +FlexaNet +CONFIG_SA1100_FLEXANET + Say Y here if you intend to run this kernel on the FlexaNet + handheld instruments. Information about this machine can be + found at: . + nanoEngine CONFIG_SA1100_NANOENGINE The nanoEngine is a StrongARM 1110-based single board computer @@ -22284,11 +22281,6 @@ no management frames, simple fixed header). Ultra is available as a special socket : socket(AF_IRDA, SOCK_DGRAM, 1); -IrDA protocol options -CONFIG_IRDA_OPTIONS - Say Y here if you want to configure any of the following IrDA - options. - IrDA cache last LSAP CONFIG_IRDA_CACHE_LAST_LSAP Say Y here if you want IrLMP to cache the last LSAP used. This @@ -22300,47 +22292,35 @@ IrDA Fast RRs CONFIG_IRDA_FAST_RR Say Y here is you want IrLAP to send fast RR (Receive Ready) frames - when acting as a primary station. This will make IrLAP send out a RR - frame immediately when receiving a frame if its own transmit queue - is currently empty. This will give a lot of speed improvement when - receiving much data since the secondary station will not have to - wait the max. turn around time before it is allowed to transmit the - next time. If the transmit queue of the secondary is also empty the - primary will back off waiting longer for sending out the RR frame - until the timeout reaches the normal value. Enabling this option - will make the IR-diode burn more power and thus reduce your battery - life. + when acting as a primary station. + Disabling this option will make latency over IrDA very bad. Enabling + this option will make the IrDA stack send more packet than strictly + necessary, thus reduce your battery life (but not that much). + + Fast RR will make IrLAP send out a RR frame immediately when + receiving a frame if its own transmit queue is currently empty. This + will give a lot of speed improvement when receiving much data since + the secondary station will not have to wait the max. turn around + time (usually 500ms) before it is allowed to transmit the next time. + If the transmit queue of the secondary is also empty, the primary will + start backing-off before sending another RR frame, waiting longer + each time until the back-off reaches the max. turn around time. + This back-off increase in controlled via + /proc/sys/net/irda/fast_poll_increase - If unsure, say N. + If unsure, say Y. IrDA debugging information CONFIG_IRDA_DEBUG Say Y here if you want the IrDA subsystem to write debug information to your syslog. You can change the debug level in /proc/sys/net/irda/debug . + When this option is enabled, the IrDA also perform many extra internal + verifications which will usually prevent the kernel to crash in case of + bugs. If unsure, say Y (since it makes it easier to find the bugs). -IrLAP compression support -CONFIG_IRDA_COMPRESSION - Compression is _not_ part of the IrDA(tm) protocol specification, - but it's working great! Linux is the first to try out compression - support at the IrLAP layer. This means that you will only benefit - from compression if you are running a Linux <-> Linux configuration. - - If you say Y here, you also need to say Y or M to a compression - protocol below. - -IrLAP Deflate compression -CONFIG_IRDA_DEFLATE - Say Y here if you want to build support for the Deflate compression - protocol. The deflate compression (GZIP) is exactly - the same as the one used by the PPP protocol. - - If you want to compile this compression support as a module, say M - here and read . The module will be - called irda_deflate.o. - IrLAN protocol CONFIG_IRLAN Say Y here if you want to build support for the IrLAN protocol. If @@ -23541,7 +23521,7 @@ this. If in doubt, say Y. /proc/efi/vars support -CONFIG_IA64_EFIVARS +CONFIG_EFI_VARS If you say Y here, you are able to get EFI (Extensible Firmware Interface) variable information in /proc/efi/vars. You may read, write, create, and destroy EFI variables through this interface. @@ -23698,7 +23678,7 @@ each of the machines below is described by a machine vector. Select SolutionEngine if configuring for a Hitachi SH7709 - or SH7750 evalutation board. + or SH7750/7750S evalutation board. Select Overdrive if configuring for a ST407750 Overdrive board. More information at @@ -23706,34 +23686,43 @@ Select HP620 if configuring for a HP Jornada HP620. More information (hardware only) at - . + . Select HP680 if configuring for a HP Jornada HP680. More information (hardware only) at - . + . Select HP690 if configuring for a HP Jornada HP690. More information (hardware only) at - . + . Select CqREEK if configuring for a CqREEK SH7708 or SH7750. More information at . Select DMIDA if configuring for a DataMyte 4000 Industrial - Digital Assistant. More information at . + Digital Assistant. More information at . Select EC3104 if configuring for a system with an Eclipse - International EC3104 chip, e.g. the Harris AD2000. + International EC3104 chip, e.g. the Harris AD2000 or Compaq Aero 8000. Select Dreamcast if configuring for a SEGA Dreamcast. More information at - . There is a + . There is a Dreamcast project is at . Select BareCPU if you know what this means, and it applies to your system. +# These may have to be merged in when we go to CML2: +# - "SolutionEngine7751" for Hitachi SolutionEngine (7751) +# - "STB1_Harp" for STMicroelectronics HARP +# - "CqREEK" for CQ Publishing CqREEK SH-4 +# - "CAT68701" for CAT 68701 Evaluation Board (SH7708) +# - "BigSur" for Big Sur Evaluation Board +# - "SH2000" for SH2000 Evaluation Board (SH7709A) +# - "ADX" for A&D ADX + SolutionEngine CONFIG_SH_SOLUTION_ENGINE Select SolutionEngine if configuring for a Hitachi SH7709 @@ -23754,19 +23743,19 @@ CONFIG_SH_HP620 Select HP620 if configuring for a HP jornada HP620. More information (hardware only) at - . + . HP680 CONFIG_SH_HP680 Select HP680 if configuring for a HP Jornada HP680. More information (hardware only) at - . + . HP690 CONFIG_SH_HP690 Select HP690 if configuring for a HP Jornada HP690. More information (hardware only) - at . + at . CqREEK CONFIG_SH_CQREEK @@ -23777,7 +23766,7 @@ DMIDA CONFIG_SH_DMIDA Select DMIDA if configuring for a DataMyte 4000 Industrial - Digital Assistant. More information at . + Digital Assistant. More information at . EC3104 CONFIG_SH_EC3104 @@ -23788,7 +23777,7 @@ CONFIG_SH_DREAMCAST Select Dreamcast if configuring for a SEGA Dreamcast. More information at - . There is a + . There is a Dreamcast project is at . BareCPU @@ -23805,7 +23794,8 @@ # Choice: superhtype SH7707 CONFIG_CPU_SUBTYPE_SH7707 - Select the type of SuperH processor you have. + Select the type of SuperH processor you have. This information is + used for optimizing and configuration purposes. Select SH7707 if you have a 60 Mhz SH-3 HD6417707 CPU. @@ -23816,6 +23806,10 @@ Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. + Select SH7751 if you have a SH7751 + + Select ST40STB1 if you have a ST40STB1 + SH7708 CONFIG_CPU_SUBTYPE_SH7708 Select SH7708 if you have a 60 Mhz SH-3 HD6417708S or @@ -23831,7 +23825,11 @@ Physical memory start address CONFIG_MEMORY_START - The physical memory start address will be automatically + Computers built with Hitachi SuperH processors always + map the ROM starting at address zero. But the processor + does not specify the range that RAM takes. + + The physical memory (RAM) start address will be automatically set to 08000000, unless you selected one of the following processor types: SolutionEngine, Overdrive, HP620, HP680, HP690, in which case the start address will be set to 0c000000. @@ -23889,15 +23887,15 @@ The default setting of the HD64465 IO base address is 0xb0000000. Do not change this unless you know what you are doing. - + Early printk support CONFIG_SH_EARLY_PRINTK - Say Y here to redirect kernel messages to the serial port + Say Y here to redirect kernel printk messages to the serial port used by the SH-IPL bootloader, starting very early in the boot process and ending when the kernel's serial console is initialised. This option is only useful porting the kernel to a new machine, when the kernel may crash or hang before the serial console is - initialised. + initialised. If unsure, say N. SuperH SCI (serial) support CONFIG_SH_SCI @@ -23951,7 +23949,7 @@ # # This is used by Emacs' spell checker ispell.el: # -# LocalWords: CONFIG coprocessor DX Pentium SX lilo loadlin HOWTO ftp metalab +# LocalWords: CONFIG coprocessor DX Pentium SX lilo loadlin HOWTO ftp ibiblio # LocalWords: unc edu docs emu README kB BLK DEV FD Thinkpad fd MFM RLL IDE gz # LocalWords: cdrom diskless netboot nfs xzvf ATAPI MB ide pavia rubini pl pd # LocalWords: HD CD-ROMs IDECD NEC MITSUMI filesystem XT XD PCI BIOS cezar ATEN @@ -23997,7 +23995,7 @@ # LocalWords: bsd comp SPARCstation le SunOS ie Gracilis PackeTwin PT pt LU FX # LocalWords: FX TEAC CR LCS mS ramdisk IDETAPE cmd fperllo encis tcfs unisa # LocalWords: Vertos Genoa Funai hsfs NCP NetWare tgz APM apm ioctls UltraLite -# LocalWords: TravelMate CDT LCD backlight VC RPC Mips AXP barlow cdrecord pg +# LocalWords: TravelMate CDT LCD backlight VC RPC Mips AXP barlow cdrtools pg # LocalWords: PMAX MILO Alphas Multia Tseng linuxelf endian mipsel mips drv HT # LocalWords: kerneld callouts AdvanSys advansys Admin WDT DataStor EP verden # LocalWords: wdt hdb hdc bugfix SiS vlb Acculogic CSA DTC dtc Holtek ht QDI diff -u --recursive --new-file v2.5.0/linux/Documentation/DocBook/Makefile linux/Documentation/DocBook/Makefile --- v2.5.0/linux/Documentation/DocBook/Makefile Fri Nov 2 17:13:53 2001 +++ linux/Documentation/DocBook/Makefile Thu Nov 29 13:45:52 2001 @@ -108,7 +108,9 @@ $(TOPDIR)/drivers/video/modedb.c \ $(TOPDIR)/fs/devfs/base.c \ $(TOPDIR)/fs/locks.c \ + $(TOPDIR)/fs/bio.c \ $(TOPDIR)/include/asm-i386/bitops.h \ + $(TOPDIR)/include/linux/usb.h \ $(TOPDIR)/kernel/pm.c \ $(TOPDIR)/kernel/ksyms.c \ $(TOPDIR)/kernel/kmod.c \ diff -u --recursive --new-file v2.5.0/linux/Documentation/DocBook/kernel-api.tmpl linux/Documentation/DocBook/kernel-api.tmpl --- v2.5.0/linux/Documentation/DocBook/kernel-api.tmpl Fri Oct 5 12:06:51 2001 +++ linux/Documentation/DocBook/kernel-api.tmpl Thu Nov 29 13:45:52 2001 @@ -204,8 +204,83 @@ - USB Devices + USB Devices + + Drivers for USB devices talk to the "usbcore" APIs, and are + exposed through driver frameworks such as block, character, + or network devices. + There are two types of public "usbcore" APIs: those intended for + general driver use, and those which are only public to drivers that + are part of the core. + The drivers that are part of the core are involved in managing a USB bus. + They include the "hub" driver, which manages trees of USB devices, and + several different kinds of "host controller" driver (HCD), which control + individual busses. + + + The device model seen by USB drivers is relatively complex. + + + + + USB supports four kinds of data transfer + (control, bulk, interrupt, and isochronous). Two transfer + types use bandwidth as it's available (control and bulk), + while the other two types of transfer (interrupt and isochronous) + are scheduled to provide guaranteed bandwidth. + + + The device description model includes one or more + "configurations" per device, only one of which is active at a time. + + + Configurations have one or more "interface", each + of which may have "alternate settings". Interfaces may be + standardized by USB "Class" specifications, or may be specific to + a vendor or device. + + USB device drivers actually bind to interfaces, not devices. + Think of them as "interface drivers", though you + may not see many devices where the distinction is important. + Most USB devices are simple, with only one configuration, + one interface, and one alternate setting. + + + Interfaces have one or more "endpoints", each of + which supports one type and direction of data transfer such as + "bulk out" or "interrupt in". The entire configuration may have + up to sixteen endpoints in each direction, allocated as needed + among all the interfaces. + + + Data transfer on USB is packetized; each endpoint + has a maximum packet size. + Drivers must often be aware of conventions such as flagging the end + of bulk transfers using "short" (including zero length) packets. + + + The Linux USB API supports synchronous calls for + control and bulk messaging. + It also supports asynchnous calls for all kinds of data transfer, + using request structures called "URBs" (USB Request Blocks). + + + + + Accordingly, the USB Core API exposed to device drivers + covers quite a lot of territory. You'll probably need to consult + the USB 2.0 specification, available online from www.usb.org at + no cost, as well as class or device specifications. + + + Data Types and Macros +!Iinclude/linux/usb.h + + + USB Core APIs !Edrivers/usb/usb.c + + diff -u --recursive --new-file v2.5.0/linux/Documentation/DocBook/via-audio.tmpl linux/Documentation/DocBook/via-audio.tmpl --- v2.5.0/linux/Documentation/DocBook/via-audio.tmpl Fri Nov 9 13:45:35 2001 +++ linux/Documentation/DocBook/via-audio.tmpl Mon Dec 10 10:39:20 2001 @@ -8,11 +8,6 @@ Jeff Garzik - -
- jgarzik@mandrakesoft.com -
-
@@ -115,7 +110,7 @@ Diagnostic output Obtain the via-audio-diag diagnostics program from - http://gtf.org/garzik/drivers/via82cxxx/ and provide a dump of the + http://sf.net/projects/gkernel/ and provide a dump of the audio chip's registers while the problem is occurring. Sample command line: diff -u --recursive --new-file v2.5.0/linux/Documentation/driver-model.txt linux/Documentation/driver-model.txt --- v2.5.0/linux/Documentation/driver-model.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/driver-model.txt Tue Dec 11 15:44:50 2001 @@ -0,0 +1,598 @@ +The (New) Linux Kernel Driver Model + +Version 0.04 + +Patrick Mochel + +03 December 2001 + + +Overview +~~~~~~~~ + +This driver model is a unification of all the current, disparate driver models +that are currently in the kernel. It is intended is to augment the +bus-specific drivers for bridges and devices by consolidating a set of data +and operations into globally accessible data structures. + +Current driver models implement some sort of tree-like structure (sometimes +just a list) for the devices they control. But, there is no linkage between +the different bus types. + +A common data structure can provide this linkage with little overhead: when a +bus driver discovers a particular device, it can insert it into the global +tree as well as its local tree. In fact, the local tree becomes just a subset +of the global tree. + +Common data fields can also be moved out of the local bus models into the +global model. Some of the manipulation of these fields can also be +consolidated. Most likely, manipulation functions will become a set +of helper functions, which the bus drivers wrap around to include any +bus-specific items. + +The common device and bridge interface currently reflects the goals of the +modern PC: namely the ability to do seamless Plug and Play, power management, +and hot plug. (The model dictated by Intel and Microsoft (read: ACPI) ensures +us that any device in the system may fit any of these criteria.) + +In reality, not every bus will be able to support such operations. But, most +buses will support a majority of those operations, and all future buses will. +In other words, a bus that doesn't support an operation is the exception, +instead of the other way around. + + +Drivers +~~~~~~~ + +The callbacks for bridges and devices are intended to be singular for a +particular type of bus. For each type of bus that has support compiled in the +kernel, there should be one statically allocated structure with the +appropriate callbacks that each device (or bridge) of that type share. + +Each bus layer should implement the callbacks for these drivers. It then +forwards the calls on to the device-specific callbacks. This means that +device-specific drivers must still implement callbacks for each operation. +But, they are not called from the top level driver layer. + +This does add another layer of indirection for calling one of these functions, +but there are benefits that are believed to outweigh this slowdown. + +First, it prevents device-specific drivers from having to know about the +global device layer. This speeds up integration time incredibly. It also +allows drivers to be more portable across kernel versions. Note that the +former was intentional, the latter is an added bonus. + +Second, this added indirection allows the bus to perform any additional logic +necessary for its child devices. A bus layer may add additional information to +the call, or translate it into something meaningful for its children. + +This could be done in the driver, but if it happens for every object of a +particular type, it is best done at a higher level. + +Recap +~~~~~ + +Instances of devices and bridges are allocated dynamically as the system +discovers their existence. Their fields describe the individual object. +Drivers - in the global sense - are statically allocated and singular for a +particular type of bus. They describe a set of operations that every type of +bus could implement, the implementation following the bus's semantics. + + +Downstream Access +~~~~~~~~~~~~~~~~~ + +Common data fields have been moved out of individual bus layers into a common +data structure. But, these fields must still be accessed by the bus layers, +and sometimes by the device-specific drivers. + +Other bus layers are encouraged to do what has been done for the PCI layer. +struct pci_dev now looks like this: + +struct pci_dev { + ... + + struct device device; +}; + +Note first that it is statically allocated. This means only one allocation on +device discovery. Note also that it is at the _end_ of struct pci_dev. This is +to make people think about what they're doing when switching between the bus +driver and the global driver; and to prevent against mindless casts between +the two. + +The PCI bus layer freely accesses the fields of struct device. It knows about +the structure of struct pci_dev, and it should know the structure of struct +device. PCI devices that have been converted generally do not touch the fields +of struct device. More precisely, device-specific drivers should not touch +fields of struct device unless there is a strong compelling reason to do so. + +This abstraction is prevention of unnecessary pain during transitional phases. +If the name of the field changes or is removed, then every downstream driver +will break. On the other hand, if only the bus layer (and not the device +layer) accesses struct device, it is only those that need to change. + + +User Interface +~~~~~~~~~~~~~~ + +By virtue of having a complete hierarchical view of all the devices in the +system, exporting a complete hierarchical view to userspace becomes relatively +easy. + +Whenever a device is inserted into the tree, a directory is created for it. +This directory may be populated at each layer of discovery - the global layer, +the bus layer, or the device layer. + +The global layer currently creates two files - 'status' and 'power'. The +former only reports the name of the device and its bus ID. The latter reports +the current power state of the device. It also be used to set the current +power state. + +The bus layer may also create files for the devices it finds while probing the +bus. For example, the PCI layer currently creates 'wake' and 'resource' files +for each PCI device. + +A device-specific driver may also export files in its directory to expose +device-specific data or tunable interfaces. + +These features were initially implemented using procfs. However, after one +conversation with Linus, a new filesystem - driverfs - was created to +implement these features. It is an in-memory filesystem, based heavily off of +ramfs, though it uses procfs as inspiration for its callback functionality. + +Each struct device has a 'struct driver_dir_entry' which encapsulates the +device's directory and the files within. + +Device Structures +~~~~~~~~~~~~~~~~~ + +struct device { + struct list_head bus_list; + struct iobus *parent; + struct iobus *subordinate; + + char name[DEVICE_NAME_SIZE]; + char bus_id[BUS_ID_SIZE]; + + struct driver_dir_entry * dir; + + spinlock_t lock; + atomic_t refcount; + + struct device_driver *driver; + void *driver_data; + void *platform_data; + + u32 current_state; + unsigned char *saved_state; +}; + +bus_list: + List of all devices on a particular bus; i.e. the device's siblings + +parent: + The parent bridge for the device. + +subordinate: + If the device is a bridge itself, this points to the struct io_bus that is + created for it. + +name: + Human readable (descriptive) name of device. E.g. "Intel EEPro 100" + +bus_id: + Parsable (yet ASCII) bus id. E.g. "00:04.00" (PCI Bus 0, Device 4, Function + 0). It is necessary to have a searchable bus id for each device; making it + ASCII allows us to use it for its directory name without translating it. + +dir: + Driver's driverfs directory. + +lock: + Driver specific lock. + +refcount: + Driver's usage count. + When this goes to 0, the device is assumed to be removed. It will be removed + from its parent's list of children. It's remove() callback will be called to + inform the driver to clean up after itself. + +driver: + Pointer to a struct device_driver, the common operations for each device. See + next section. + +driver_data: + Private data for the driver. + Much like the PCI implementation of this field, this allows device-specific + drivers to keep a pointer to a device-specific data. + +platform_data: + Data that the platform (firmware) provides about the device. + For example, the ACPI BIOS or EFI may have additional information about the + device that is not directly mappable to any existing kernel data structure. + It also allows the platform driver (e.g. ACPI) to a driver without the driver + having to have explicit knowledge of (atrocities like) ACPI. + + +current_state: + Current power state of the device. For PCI and other modern devices, this is + 0-3, though it's not necessarily limited to those values. + +saved_state: + Pointer to driver-specific set of saved state. + Having it here allows modules to be unloaded on system suspend and reloaded + on resume and maintain state across transitions. + It also allows generic drivers to maintain state across system state + transitions. + (I've implemented a generic PCI driver for devices that don't have a + device-specific driver. Instead of managing some vector of saved state + for each device the generic driver supports, it can simply store it here.) + + + +struct device_driver { + int (*probe) (struct device *dev); + int (*remove) (struct device *dev); + + int (*suspend) (struct device *dev, u32 state, u32 level); + int (*resume) (struct device *dev, u32 level); +} + +probe: + Check for device existence and associate driver with it. + +remove: + Dissociate driver with device. Releases device so that it could be used by + another driver. Also, if it is a hotplug device (hotplug PCI, Cardbus), an + ejection event could take place here. + +suspend: + Perform one step of the device suspend process. + +resume: + Perform one step of the device resume process. + +The probe() and remove() callbacks are intended to be much simpler than the +current PCI correspondents. + +probe() should do the following only: + +- Check if hardware is present +- Register device interface +- Disable DMA/interrupts, etc, just in case. + +Some device initialisation was done in probe(). This should not be the case +anymore. All initialisation should take place in the open() call for the +device. + +Breaking initialisation code out must also be done for the resume() callback, +as most devices will have to be completely reinitialised when coming back from +a suspend state. + +remove() should simply unregister the device interface. + + +Device power management can be quite complicated, based exactly what is +desired to be done. Four operations sum up most of it: + +- OS directed power management. + The OS takes care of notifying all drivers that a suspend is requested, + saving device state, and powering devices down. +- Firmware controlled power management. + The OS only wants to notify devices that a suspend is requested. +- Device power management. + A user wants to place only one device in a low power state, and maybe save + state. +- System reboot. + The system wants to place devices in a quiescent state before the system is + reset. + +In an attempt to please all of these scenarios, the power management +transition for any device is broken up into several stages - notify, save +state, and power down. The disable stage, which should happen after notify and +before save state has been considered and may be implemented in the future. + +Depending on what the system-wide policy is (usually dictated by the power +management scheme present), each driver's suspend callback may be called +multiple times, each with a different stage. + +On all power management transitions, the stages should be called sequentially +(notify before save state; save state before power down). However, drivers +should not assume that any stage was called before hand. (If a driver gets a +power down call, it shouldn't assume notify or save state was called first.) +This allows the framework to be used seamlessly by all power management +actions. Hopefully. + +Resume transitions happen in a similar manner. They are broken up into two +stages currently (power on and restore state), though a third stage (enable) +may be added later. + +For suspend and resume transitions, the following values are defined to denote +the stage: + +enum{ + SUSPEND_NOTIFY, + SUSPEND_SAVE_STATE, + SUSPEND_POWER_DOWN, +}; + +enum { + RESUME_POWER_ON, + RESUME_RESTORE_STATE, +}; + + +During a system power transition, the device tree must be walked in order, +calling the suspend() or resume() callback for each node. This may happen +several times. + +Initially, this was done in kernel space. However, it has occurred to me that +doing recursion to a non-bounded depth is dangerous, and that there are a lot +of inherent race conditions in such an operation. + +Non-recursive walking of the device tree is possible. However, this makes for +convoluted code. + +No matter what, if the transition happens in kernel space, it is difficult to +gracefully recover from errors or to implement a policy that prevents one from +shutting down the device(s) you want to save state to. + +Instead, the walking of the device tree has been moved to userspace. When a +user requests the system to suspend, it will walk the device tree, as exported +via driverfs, and tell each device to go to sleep. It will do this multiple +times based on what the system policy is. + +Device resume should happen in the same manner when the system awakens. + +Each suspend stage is described below: + +SUSPEND_NOTIFY: + +This level to notify the driver that it is going to sleep. If it knows that it +cannot resume the hardware from the requested level, or it feels that it is +too important to be put to sleep, it should return an error from this function. + +It does not have to stop I/O requests or actually save state at this point. + +SUSPEND_DISABLE: + +The driver should stop taking I/O requests at this stage. Because the save +state stage happens afterwards, the driver may not want to physically disable +the device; only mark itself unavailable if possible. + +SUSPEND_SAVE_STATE: + +The driver should allocate memory and save any device state that is relevant +for the state it is going to enter. + +SUSPEND_POWER_DOWN: + +The driver should place the device in the power state requested. + + +For resume, the stages are defined as follows: + +RESUME_POWER_ON: + +Devices should be powered on and reinitialised to some known working state. + +RESUME_RESTORE_STATE: + +The driver should restore device state to its pre-suspend state and free any +memory allocated for its saved state. + +RESUME_ENABLE: + +The device should start taking I/O requests again. + + +Each driver does not have to implement each stage. But, it if it does +implemente a stage, it should do what is described above. It should not assume +that it performed any stage previously, or that it will perform any stage +later. + +It is quite possible that a driver can fail during the suspend process, for +whatever reason. In this event, the calling process must gracefully recover +and restore everything to their states before the suspend transition began. + +If a driver knows that it cannot suspend or resume properly, it should fail +during the notify stage. Properly implemented power management schemes should +make sure that this is the first stage that is called. + +If a driver gets a power down request, it should obey it, as it may very +likely be during a reboot. + + +Bus Structures +~~~~~~~~~~~~~~ + +struct iobus { + struct list_head node; + struct iobus *parent; + struct list_head children; + struct list_head devices; + + struct list_head bus_list; + + spinlock_t lock; + atomic_t refcount; + + struct device *self; + struct driver_dir_entry * dir; + + char name[DEVICE_NAME_SIZE]; + char bus_id[BUS_ID_SIZE]; + + struct bus_driver *driver; +}; + +node: + Bus's node in sibling list (its parent's list of child buses). + +parent: + Pointer to parent bridge. + +children: + List of subordinate buses. + In the children, this correlates to their 'node' field. + +devices: + List of devices on the bus this bridge controls. + This field corresponds to the 'bus_list' field in each child device. + +bus_list: + Each type of bus keeps a list of all bridges that it finds. This is the + bridges entry in that list. + +self: + Pointer to the struct device for this bridge. + +lock: + Lock for the bus. + +refcount: + Usage count for the bus. + +dir: + Driverfs directory. + +name: + Human readable ASCII name of bus. + +bus_id: + Machine readable (though ASCII) description of position on parent bus. + +driver: + Pointer to operations for bus. + + +struct iobus_driver { + char name[16]; + struct list_head node; + + int (*scan) (struct io_bus*); + int (*add_device) (struct io_bus*, char*); +}; + +name: + ASCII name of bus. + +node: + List of buses of this type in system. + +scan: + Search the bus for new devices. This may happen either at boot - where every + device discovered will be new - or later on - in which there may only be a few + (or no) new devices. + +add_device: + Trigger a device insertion at a particular location. + + + +The API +~~~~~~~ + +There are several functions exported by the global device layer, including +several optional helper functions, written solely to try and make your life +easier. + +void device_init_dev(struct device * dev); + +Initialise a device structure. It first zeros the device, the initialises all +of the lists. (Note that this would have been called device_init(), but that +name was already taken. :/) + + +struct device * device_alloc(void) + +Allocate memory for a device structure and initialise it. +First, allocates memory, then calls device_init_dev() with the new pointer. + + +int device_register(struct device * dev); + +Register a device with the global device layer. +The bus layer should call this function upon device discovery, e.g. when +probing the bus. +dev should be fully initialised when this is called. +If dev->parent is not set, it sets its parent to be the device root. +It then does the following: + - inserts it into its parent's list of children + - creates a driverfs directory for it + - creates a set of default files for the device in its directory + - calls platform_notify() to notify the firmware driver of its existence. + + +void get_device(struct device * dev); + +Increment the refcount for a device. + + +int valid_device(struct device * dev); + +Check if reference count is positive for a device (it's not waiting to be +freed). If it is positive, it increments the reference count for the device. +It returns whether or not the device is usable. + + +void put_device(struct device * dev); + +Decrement the reference count for the device. If it hits 0, it removes the +device from its parent's list of children and calls the remove() callback for +the device. + + +void lock_device(struct device * dev); + +Take the spinlock for the device. + + +void unlock_device(struct device * dev); + +Release the spinlock for the device. + + + +void iobus_init(struct iobus * iobus); +struct iobus * iobus_alloc(void); +int iobus_register(struct iobus * iobus); +void get_iobus(struct iobus * iobus); +int valid_iobus(struct iobus * iobus); +void put_iobus(struct iobus * iobus); +void lock_iobus(struct iobus * iobus); +void unlock_iobus(struct iobus * iobus); + +These functions provide the same functionality as the device_* +counterparts, only operating on a struct iobus. One important thing to note, +though is that iobus_register() and iobus_unregister() operate recursively. It +is possible to add an entire tree in one call. + + + +int device_driver_init(void); + +Main initialisation routine. + +This makes sure driverfs is up and running and initialises the device tree. + + +void device_driver_exit(void); + +This frees up the device tree. + + + + +Credits +~~~~~~~ + +The following people have been extremely helpful in solidifying this document +and the driver model. + +Randy Dunlap rddunlap@osdl.org +Jeff Garzik jgarzik@mandrakesoft.com +Ben Herrenschmidt benh@kernel.crashing.org + + diff -u --recursive --new-file v2.5.0/linux/Documentation/filesystems/devfs/ChangeLog linux/Documentation/filesystems/devfs/ChangeLog --- v2.5.0/linux/Documentation/filesystems/devfs/ChangeLog Sat Nov 3 10:06:38 2001 +++ linux/Documentation/filesystems/devfs/ChangeLog Sat Nov 24 13:06:43 2001 @@ -1778,3 +1778,19 @@ Thanks to Kari Hurtta - Avoid deadlock in by using temporary buffer +=============================================================================== +Changes for patch v197 + +- First release of new locking code for devfs core (v1.0) + +- Fixed bug in drivers/cdrom/cdrom.c +=============================================================================== +Changes for patch v198 + +- Discard temporary buffer, now use "%s" for dentry names + +- Don't generate path in : use fake entry instead + +- Use "existing" directory in <_devfs_make_parent_for_leaf> + +- Use slab cache rather than fixed buffer for devfsd events diff -u --recursive --new-file v2.5.0/linux/Documentation/filesystems/devfs/README linux/Documentation/filesystems/devfs/README --- v2.5.0/linux/Documentation/filesystems/devfs/README Wed Oct 10 23:23:24 2001 +++ linux/Documentation/filesystems/devfs/README Sat Nov 24 13:06:43 2001 @@ -3,7 +3,7 @@ Linux Devfs (Device File System) FAQ Richard Gooch -29-SEP-2001 +9-NOV-2001 ----------------------------------------------------------------------------- @@ -11,7 +11,9 @@ http://www.atnf.csiro.au/~rgooch/linux/docs/devfs.html and looks much better than the text version distributed with the -kernel sources. +kernel sources. A mirror site is available at: + +http://www.ras.ucalgary.ca/~rgooch/linux/docs/devfs.html There is also an optional daemon that may be used with devfs. You can find out more about it at: diff -u --recursive --new-file v2.5.0/linux/Documentation/filesystems/driverfs.txt linux/Documentation/filesystems/driverfs.txt --- v2.5.0/linux/Documentation/filesystems/driverfs.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/filesystems/driverfs.txt Tue Dec 11 15:44:50 2001 @@ -0,0 +1,211 @@ + +driverfs - The Device Driver Filesystem + +Patrick Mochel + +3 December 2001 + + +What it is: +~~~~~~~~~~~ +driverfs is a unified means for device drivers to export interfaces to +userspace. + +Some drivers have a need for exporting interfaces for things like +setting device-specific parameters, or tuning the device performance. +For example, wireless networking cards export a file in procfs to set +their SSID. + +Other times, the bus on which a device resides may export other +information about the device. For example, PCI and USB both export +device information via procfs or usbdevfs. + +In these cases, the files or directories are in nearly random places +in /proc. One benefit of driverfs is that it can consolidate all of +these interfaces to one standard location. + + +Why it's better than procfs: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This of course can't happen without changing every single driver that +exports a procfs interface, and having some coordination between all +of them as to what the proper place for their files is. Or can it? + + +driverfs was developed in conjunction with the new driver model for +the 2.5 kernel. In that model, the system has one unified tree of all +the devices that are present in the system. It follows naturally that +this tree can be exported to userspace in the same order. + +So, every bus and every device gets a directory in the filesystem. +This directory is created when the device is registered in the tree; +before the driver actually gets a initialised. The dentry for this +directory is stored in the struct device for this driver, so the +driver has access to it. + +Now, every driver has one standard place to export its files. + +Granted, the location of the file is not as intuitive as it may have +been under procfs. But, I argue that with the exception of +/proc/bus/pci, none of the files had intuitive locations. I also argue +that the development of userspace tools can help cope with these +changes and inconsistencies in locations. + + +Why we're not just using procfs: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When developing the new driver model, it was initially implemented +with a procfs tree. In explaining the concept to Linus, he said "Don't +use proc." + +I was a little shocked (especially considering I had already +implemented it using procfs). "What do you mean 'don't use proc'?" + +His argument was that too many things use proc that shouldn't. And +even more things misuse proc that shouldn't. On top of that, procfs +was written before the VFS layer was written, so it doesn't use the +dcache. It reimplements many of the same features that the dcache +does, and is in general, crufty. + +So, he told me to write my own. Soon after, he pointed me at ramfs, +the simplest filesystem known to man. + +Consequently, we have a virtual fileystem based heavily on ramfs, and +borrowing some conceptual functionality from procfs. + +It may suck, but it does what it was designed to. At least so far. + + +How it works: +~~~~~~~~~~~~~ + +Directories are encapsulated like this: + +struct driver_dir_entry { + char * name; + struct dentry * dentry; + mode_t mode; + struct list_head files; +}; + +name: + Name of the directory. +dentry: + Dentry for the directory. +mode: + Permissions of the directory. +files: + Linked list of driver_file_entry's that are in the directory. + + +To create a directory, one first calls + +struct driver_dir_entry * +driverfs_create_dir_entry(const char * name, mode_t mode); + +which allocates and initialises a struct driver_dir_entry. Then to actually +create the directory: + +int driverfs_create_dir(struct driver_dir_entry *, struct driver_dir_entry *); + +To remove a directory: + +void driverfs_remove_dir(struct driver_dir_entry * entry); + + +Files are encapsulated like this: + +struct driver_file_entry { + struct driver_dir_entry * parent; + struct list_head node; + char * name; + mode_t mode; + struct dentry * dentry; + void * data; + struct driverfs_operations * ops; +}; + +struct driverfs_operations { + ssize_t (*read) (char *, size_t, loff_t, void *); + ssize_t (*write)(const char *, size_t, loff_t, void*); +}; + +node: + Node in its parent directory's list of files. + +name: + The name of the file. + +dentry: + The dentry for the file. + +data: + Caller specific data that is passed to the callbacks when they + are called. + +ops: + Operations for the file. Currently, this only contains read() and write() + callbacks for the file. + +To create a file, one first calls + +struct driver_file_entry * +driverfs_create_entry (const char * name, mode_t mode, + struct driverfs_operations * ops, void * data); + +That allocates and initialises a struct driver_file_entry. Then, to actually +create a file, one calls + +int driverfs_create_file(struct driver_file_entry * entry, + struct driver_dir_entry * parent); + + +To remove a file, one calls + +void driverfs_remove_file(struct driver_dir_entry *, const char * name); + + +The callback functionality is similar to the way procfs works. When a +user performs a read(2) or write(2) on the file, it first calls a +driverfs function. This function then checks for a non-NULL pointer in +the file->private_data field, which it assumes to be a pointer to a +struct driver_file_entry. + +It then checks for the appropriate callback and calls it. + + +What driverfs is not: +~~~~~~~~~~~~~~~~~~~~~ +It is not a replacement for either devfs or procfs. + +It does not handle device nodes, like devfs is intended to do. I think +this functionality is possible, but indeed think that integration of +the device nodes and control files should be done. Whether driverfs or +devfs, or something else, is the place to do it, I don't know. + +It is not intended to be a replacement for all of the procfs +functionality. I think that many of the driver files should be moved +out of /proc (and maybe a few other things as well ;). + + + +Limitations: +~~~~~~~~~~~~ +The driverfs functions assume that at most a page is being either read +or written each time. + + +Possible bugs: +~~~~~~~~~~~~~~ +It may not deal with offsets and/or seeks very well, especially if +they cross a page boundary. + +There may be locking issues when dynamically adding/removing files and +directories rapidly (like if you have a hot plug device). + +There are some people that believe that filesystems which add +files/directories dynamically based on the presence of devices are +inherently flawed. Though not as technically versed in this area as +some of those people, I like to believe that they can be made to work, +with the right guidance. + diff -u --recursive --new-file v2.5.0/linux/Documentation/filesystems/ntfs.txt linux/Documentation/filesystems/ntfs.txt --- v2.5.0/linux/Documentation/filesystems/ntfs.txt Sun Sep 30 11:42:44 2001 +++ linux/Documentation/filesystems/ntfs.txt Mon Dec 10 19:37:38 2001 @@ -98,6 +98,16 @@ ChangeLog ========= +NTFS 1.1.21: + - Fixed bug with reading $MFT where we try to read higher mft records + before having read the $DATA attribute of $MFT. (Note this is only a + partial solution which will only work in the case that the attribute + list is resident or non-resident but $DATA is in the first 1024 + bytes. But this should be enough in the majority of cases. I am not + going to bother fixing the general case until someone finds this to + be a problem for them, which I doubt very much will ever happen...) + - Fixed bogus BUG() call in readdir(). + NTFS 1.1.20: - Fixed two bugs in ntfs_readwrite_attr(). Thanks to Jan Kara for spotting the out of bounds one. diff -u --recursive --new-file v2.5.0/linux/Documentation/networking/tulip.txt linux/Documentation/networking/tulip.txt --- v2.5.0/linux/Documentation/networking/tulip.txt Fri Mar 2 11:02:14 2001 +++ linux/Documentation/networking/tulip.txt Wed Dec 31 16:00:00 1969 @@ -1,226 +0,0 @@ - Tulip Ethernet Card Driver - Maintained by Jeff Garzik - -The Tulip driver was developed by Donald Becker and changed by -Takashi Manabe and a cast of thousands. - -For 2.4.x and later kernels, the Linux Tulip driver is available at -http://sourceforge.net/projects/tulip/ - - This driver is for the Digital "Tulip" Ethernet adapter interface. - It should work with most DEC 21*4*-based chips/ethercards, as well as - with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and ASIX. - - The author may be reached as becker@scyld.com, or C/O - Center of Excellence in Space Data and Information Sciences - Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 - - Additional information on Donald Becker's tulip.c - is available at http://www.scyld.com/network/tulip.html - - - - - Theory of Operation - -Board Compatibility -=================== - -This device driver is designed for the DECchip "Tulip", Digital's -single-chip ethernet controllers for PCI. Supported members of the family -are the 21040, 21041, 21140, 21140A, 21142, and 21143. Similar work-alike -chips from Lite-On, Macronics, ASIX, Compex and other listed below are also -supported. - -These chips are used on at least 140 unique PCI board designs. The great -number of chips and board designs supported is the reason for the -driver size and complexity. Almost of the increasing complexity is in the -board configuration and media selection code. There is very little -increasing in the operational critical path length. - -Board-specific settings -======================= - -PCI bus devices are configured by the system at boot time, so no jumpers -need to be set on the board. The system BIOS preferably should assign the -PCI INTA signal to an otherwise unused system IRQ line. - -Some boards have EEPROMs tables with default media entry. The factory default -is usually "autoselect". This should only be overridden when using -transceiver connections without link beat e.g. 10base2 or AUI, or (rarely!) -for forcing full-duplex when used with old link partners that do not do -autonegotiation. - -Driver operation -================ - -Ring buffers ------------- - -The Tulip can use either ring buffers or lists of Tx and Rx descriptors. -This driver uses statically allocated rings of Rx and Tx descriptors, set at -compile time by RX/TX_RING_SIZE. This version of the driver allocates skbuffs -for the Rx ring buffers at open() time and passes the skb->data field to the -Tulip as receive data buffers. When an incoming frame is less than -RX_COPYBREAK bytes long, a fresh skbuff is allocated and the frame is -copied to the new skbuff. When the incoming frame is larger, the skbuff is -passed directly up the protocol stack and replaced by a newly allocated -skbuff. - -The RX_COPYBREAK value is chosen to trade-off the memory wasted by -using a full-sized skbuff for small frames vs. the copying costs of larger -frames. For small frames the copying cost is negligible (esp. considering -that we are pre-loading the cache with immediately useful header -information). For large frames the copying cost is non-trivial, and the -larger copy might flush the cache of useful data. A subtle aspect of this -choice is that the Tulip only receives into longword aligned buffers, thus -the IP header at offset 14 isn't longword aligned for further processing. -Copied frames are put into the new skbuff at an offset of "+2", thus copying -has the beneficial effect of aligning the IP header and preloading the -cache. - -Synchronization ---------------- -The driver runs as two independent, single-threaded flows of control. One -is the send-packet routine, which enforces single-threaded use by the -dev->tbusy flag. The other thread is the interrupt handler, which is single -threaded by the hardware and other software. - -The send packet thread has partial control over the Tx ring and 'dev->tbusy' -flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next -queue slot is empty, it clears the tbusy flag when finished otherwise it sets -the 'tp->tx_full' flag. - -The interrupt handler has exclusive control over the Rx ring and records stats -from the Tx ring. (The Tx-done interrupt can't be selectively turned off, so -we can't avoid the interrupt overhead by having the Tx routine reap the Tx -stats.) After reaping the stats, it marks the queue entry as empty by setting -the 'base' to zero. Iff the 'tp->tx_full' flag is set, it clears both the -tx_full and tbusy flags. - -Notes -===== - -Thanks to Duke Kamstra of SMC for long ago providing an EtherPower board. -Greg LaPolla at Linksys provided PNIC and other Linksys boards. -Znyx provided a four-port card for testing. - -References -========== - -http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html -http://www.digital.com (search for current 21*4* datasheets and "21X4 SROM") -http://www.national.com/pf/DP/DP83840A.html -http://www.asix.com.tw/pmac.htm -http://www.admtek.com.tw/ - -Errata -====== - -The old DEC databooks were light on details. -The 21040 databook claims that CSR13, CSR14, and CSR15 should each be the last -register of the set CSR12-15 written. Hmmm, now how is that possible? - -The DEC SROM format is very badly designed not precisely defined, leading to -part of the media selection junkheap below. Some boards do not have EEPROM -media tables and need to be patched up. Worse, other boards use the DEC -design kit media table when it isn't correct for their board. - -We cannot use MII interrupts because there is no defined GPIO pin to attach -them. The MII transceiver status is polled using an kernel timer. - - -Source tree tour -================ -The following is a list of files comprising the Tulip ethernet driver in -drivers/net/tulip subdirectory. - -21142.c - 21142-specific h/w interaction -eeprom.c - EEPROM reading and parsing -interrupt.c - Interrupt handler -media.c - Media selection and MII support -pnic.c - PNIC-specific h/w interaction -timer.c - Main driver timer, and misc h/w timers -tulip.h - Private driver header -tulip_core.c - Driver core (a.k.a. where "everything else" goes) - - - -Version history -=============== -0.9.14 (February 20, 2000): -* Fix PNIC problems (Manfred Spraul) -* Add new PCI id for Accton comet -* Support Davicom tulips -* Fix oops in eeprom parsing -* Enable workarounds for early PCI chipsets -* IA64, hppa csr0 support -* Support media types 5, 6 -* Interpret a bit more of the 21142 SROM extended media type 3 -* Add missing delay in eeprom reading - -0.9.11 (November 3, 2000): -* Eliminate extra bus accesses when sharing interrupts (prumpf) -* Barrier following ownership descriptor bit flip (prumpf) -* Endianness fixes for >14 addresses in setup frames (prumpf) -* Report link beat to kernel/userspace via netif_carrier_*. (kuznet) -* Better spinlocking in set_rx_mode. -* Fix I/O resource request failure error messages (DaveM catch) -* Handle DMA allocation failure. - -0.9.10 (September 6, 2000): -* Simple interrupt mitigation (via jamal) -* More PCI ids - -0.9.9 (August 11, 2000): -* More PCI ids - -0.9.8 (July 13, 2000): -* Correct signed/unsigned comparison for dummy frame index -* Remove outdated references to struct enet_statistics - -0.9.7 (June 17, 2000): -* Timer cleanups (Andrew Morton) -* Alpha compile fix (somebody?) - -0.9.6 (May 31, 2000): -* Revert 21143-related support flag patch -* Add HPPA/media-table debugging printk - -0.9.5 (May 30, 2000): -* HPPA support (willy@puffingroup) -* CSR6 bits and tulip.h cleanup (Chris Smith) -* Improve debugging messages a bit -* Add delay after CSR13 write in t21142_start_nway -* Remove unused ETHER_STATS code -* Convert 'extern inline' to 'static inline' in tulip.h (Chris Smith) -* Update DS21143 support flags in tulip_chip_info[] -* Use spin_lock_irq, not _irqsave/restore, in tulip_start_xmit() -* Add locking to set_rx_mode() -* Fix race with chip setting DescOwned bit (Hal Murray) -* Request 100% of PIO and MMIO resource space assigned to card -* Remove error message from pci_enable_device failure - -0.9.4.3 (April 14, 2000): -* mod_timer fix (Hal Murray) -* PNIC2 resuscitation (Chris Smith) - -0.9.4.2 (March 21, 2000): -* Fix 21041 CSR7, CSR13/14/15 handling -* Merge some PCI ids from tulip 0.91x -* Merge some HAS_xxx flags and flag settings from tulip 0.91x -* asm/io.h fix (submitted by many) and cleanup -* s/HAS_NWAY143/HAS_NWAY/ -* Cleanup 21041 mode reporting -* Small code cleanups - -0.9.4.1 (March 18, 2000): -* Finish PCI DMA conversion (davem) -* Do not netif_start_queue() at end of tulip_tx_timeout() (kuznet) -* PCI DMA fix (kuznet) -* eeprom.c code cleanup -* Remove Xircom Tulip crud - - -[EOF] - diff -u --recursive --new-file v2.5.0/linux/Documentation/pm.txt linux/Documentation/pm.txt --- v2.5.0/linux/Documentation/pm.txt Fri Apr 6 10:42:55 2001 +++ linux/Documentation/pm.txt Thu Nov 29 17:00:33 2001 @@ -34,7 +34,7 @@ system the associated daemon will exit gracefully. apmd: http://worldvisions.ca/~apenwarr/apmd/ - acpid: http://phobos.fs.tum.de/acpi/ + acpid: http://acpid.sf.net/ Driver Interface ---------------- @@ -260,7 +260,7 @@ Q: Who do I contact for additional information about enabling power management for my specific driver/device? -ACPI4Linux mailing list: acpi@phobos.fs.tum.de +ACPI Development mailing list: acpi-devel@lists.sourceforge.net System Interface ---------------- diff -u --recursive --new-file v2.5.0/linux/Documentation/sh/new-machine.txt linux/Documentation/sh/new-machine.txt --- v2.5.0/linux/Documentation/sh/new-machine.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/sh/new-machine.txt Tue Dec 11 10:10:18 2001 @@ -0,0 +1,77 @@ +The multiple machine support relies on redirecting all functions which will +need to be machine specific through a table of function pointers, the +machvec. These functions fall into a number of categories: + + - I/O functions to IO memory (inb etc) and PCI/main memory (readb etc). + - I/O remapping functions (ioremap etc) + - some initialisation functions + - a 'heartbeat' function + - some miscellaneous flags + +The tree can be built in two ways: + - as a fully generic build. All drivers are linked in, and all functions + go through the machvec + - as a machine specific build. In this case only the required drivers + will be linked in, and some macros may be redefined to not go through + the machvec where performance is important (in particular IO functions). + +There are three ways in which IO can be performed: + - none at all. This is really only useful for the 'unknown' machine type, + which us designed to run on a machine about which we know nothing, and + so all all IO instructions do nothing. + - fully custom. In this case all IO functions go to a machine specific + set of functions which can do what they like + - a generic set of functions. These will cope with most situations, + and rely on a single function, mv_port2addr, which is called through the + machine vector, and converts an IO address into a memory address, which + can be read from/written to directly. + +Thus adding a new machine involves the following steps (I will assume I am +adding a machine called fred): + + - add a new file include/asm-sh/io_fred.h which contains prototypes for + any machine specific IO functions prefixed with the machine name, for + example fred_inb. These will be needed when filling out the machine + vector. In addition, a section is required which defines what to do when + building a machine specific version. For example: + + #ifdef __WANT_IO_DEF + #define inb fred_inb + ... + #endif + + This is the minimum that is required, however there are ample + opportunities to optimise this. In particular, by making the prototypes + inline function definitions, it is possible to inline the function when + building machine specific versions. Note that the machine vector + functions will still be needed, so that a module built for a generic + setup can be loaded. + + - add a new file arch/sh/kernel/mach_fred.c. This contains the definition + of the machine vector. When building the machine specific version, this + will be the real machine vector (via an alias), while in the generic + version is used to initialise the machine vector, and then freed, by + making it initdata. This should be defined as: + + struct sh_machine_vector mv_fred __initmv = { + mv_name: "Fred" + } + ALIAS_MV(se) + + - finally add a file arch/sh/kernel/io_fred.c, which contains + definitions of the machine specific io functions. + +A note about initialisation functions. Three initialisation functions are +provided in the machine vector: + - mv_arch_init - called very early on from setup_arch + - mv_init_irq - called from init_IRQ, after the generic SH interrupt + initialisation + - mv_init_pci - currently not used + +Any other remaining functions which need to be called at start up can be +added to the list using the __initcalls macro (or module_init if the code +can be built as a module). Many generic drivers probe to see if the device +they are targeting is present, however this may not always be appropriate, +so a flag can be added to the machine vector which will be set on those +machines which have the hardware in question, reducing the probe to a +single conditional. diff -u --recursive --new-file v2.5.0/linux/Documentation/sonypi.txt linux/Documentation/sonypi.txt --- v2.5.0/linux/Documentation/sonypi.txt Mon Oct 15 08:38:31 2001 +++ linux/Documentation/sonypi.txt Thu Nov 29 07:53:34 2001 @@ -58,6 +58,10 @@ get enabled unless you set this parameter to 1. Do not use this option unless it's actually necessary, some Vaio models don't deal well with this option. + This option is available only if the kernel is + compiled without ACPI support (since it conflicts + with it and it shouldn't be required anyway if + ACPI is already enabled). verbose: print unknown events from the sonypi device @@ -93,7 +97,10 @@ - some users reported that the laptop speed is lower (dhrystone tested) when using the driver with the fnkeyinit parameter. I cannot reproduce it on my laptop and not all users have this problem. - Still under investigation. + This happens because the fnkeyinit parameter enables the ACPI + mode (but without additionnal ACPI control, like processor + speed handling etc). Use ACPI instead of APM if it works on your + laptop. - since all development was done by reverse engineering, there is _absolutely no guarantee_ that this driver will not crash your diff -u --recursive --new-file v2.5.0/linux/Documentation/usb/error-codes.txt linux/Documentation/usb/error-codes.txt --- v2.5.0/linux/Documentation/usb/error-codes.txt Wed Oct 17 14:34:06 2001 +++ linux/Documentation/usb/error-codes.txt Sat Dec 8 20:28:45 2001 @@ -1,14 +1,9 @@ -Revised: 2000-Dec-05. +Revised: 2001-Dec-06. This is the documentation of (hopefully) all possible error codes (and their interpretation) that can be returned from the host controller drivers and from usbcore. -NOTE: -The USB_ST_* codes are deprecated and are only listed for compatibility; -new software should use only -E* instead! - - ************************************************************************** * Error codes returned by usb_submit_urb * @@ -16,7 +11,6 @@ Non-USB-specific: -USB_ST_NOERROR 0 URB submission went fine -ENOMEM no memory for allocation of internal structures @@ -25,12 +19,10 @@ -ENODEV specified USB-device or bus doesn't exist -USB_ST_REQUEST_ERROR -ENXIO a control or interrupt URB is already queued to this endpoint; or a bulk URB is already queued to this endpoint and USB_QUEUE_BULK wasn't used (UHCI HCDs only) -USB_ST_URB_INVALID_ERROR -EINVAL a) Invalid transfer type specified (or not supported) b) Invalid interrupt interval (0<=n<256) c) more than one interrupt packet requested @@ -42,12 +34,10 @@ -EFBIG too much ISO frames requested (currently uhci>900) -USB_ST_STALL -EPIPE specified pipe-handle is already stalled -EMSGSIZE endpoint message size is zero, do interface/alternate setting -USB_ST_BANDWIDTH_ERROR -ENOSPC The host controller's bandwidth is already consumed and this request would push it past its allowed limit. @@ -60,60 +50,43 @@ * or in iso_frame_desc[n].status (for ISO) * ************************************************************************** -USB_ST_NOERROR 0 Transfer completed successfully -USB_ST_URB_KILLED -ENOENT URB was canceled by usb_unlink_urb -USB_ST_URB_PENDING -EINPROGRESS URB still pending, no results yet (actually no error until now;-) -USB_ST_BITSTUFF -USB_ST_INTERNALERROR -EPROTO a) bitstuff error b) unknown USB error -USB_ST_CRC -EILSEQ CRC mismatch -USB_ST_STALL -EPIPE endpoint stalled -USB_ST_BUFFEROVERRUN -ECOMM During an IN transfer, the host controller received data from an endpoint faster than it could be written to system memory -USB_ST_BUFFERUNDERRUN -ENOSR During an OUT transfer, the host controller could not retrieve data from system memory fast enough to keep up with the USB data rate -USB_ST_DATAOVERRUN -EOVERFLOW The amount of data returned by the endpoint was greater than either the max packet size of the endpoint or the remaining buffer size. "Babble". -USB_ST_DATAUNDERRUN -EREMOTEIO The endpoint returned less than max packet size and that amount did not fill the specified buffer -USB_ST_NORESPONSE -USB_ST_TIMEOUT -ETIMEDOUT transfer timed out, NAK -USB_ST_REMOVED -ENODEV device was removed -USB_ST_SHORT_PACKET -EREMOTEIO short packet detected -USB_ST_PARTIAL_ERROR -EXDEV ISO transfer only partially completed look at individual frame status for details -USB_ST_URB_INVALID_ERROR -EINVAL ISO madness, if this happens: Log off and go home -ECONNRESET the URB is being unlinked asynchronously diff -u --recursive --new-file v2.5.0/linux/Documentation/usb/philips.txt linux/Documentation/usb/philips.txt --- v2.5.0/linux/Documentation/usb/philips.txt Wed Oct 17 14:34:06 2001 +++ linux/Documentation/usb/philips.txt Mon Nov 26 17:09:10 2001 @@ -1,5 +1,5 @@ This file contains some additional information for the Philips webcams. -E-mail: webcam@smcc.demon.nl Last updated: 2001-07-27 +E-mail: webcam@smcc.demon.nl Last updated: 2001-09-24 The main webpage for the Philips driver is http://www.smcc.demon.nl/webcam/. It contains a lot of extra information, a FAQ, and the binary plugin @@ -13,11 +13,9 @@ the latter, since it makes troubleshooting a lot easier. The built-in microphone is supported through the USB Audio class. -(Taken from install.html) - When you load the module you can set some default settings for the -camera; some programs depend on a particular image-size or -format. The -options are: +camera; some programs depend on a particular image-size or -format and +don't know how to set it properly in the driver. The options are: size Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or @@ -99,6 +97,57 @@ This parameter works only with the ToUCam range of cameras (730, 740, 750). For other cameras this command is silently ignored, and the LED cannot be controlled. + +dev_hint + A long standing problem with USB devices is their dynamic nature: you + never know what device a camera gets assigned; it depends on module load + order, the hub configuration, the order in which devices are plugged in, + and the phase of the moon (i.e. it can be random). With this option you + can give the driver a hint as to what video device node (/dev/videoX) it + should use with a specific camera. This is also handy if you have two + cameras of the same model. + + A camera is specified by its type (the number from the camera model, + like PCA645, PCVC750VC, etc) and optionally the serial number (visible + in /proc/bus/usb/devices). A hint consists of a string with the following + format: + + [type[.serialnumber]:]node + + The square brackets mean that both the type and the serialnumber are + optional, but a serialnumber cannot be specified without a type (which + would be rather pointless). The serialnumber is separated from the type + by a '.'; the node number by a ':'. + + This somewhat cryptic syntax is best explained by a few examples: + + dev_hint=3,5 The first detected cam gets assigned + /dev/video3, the second /dev/video5. Any + other cameras will get the first free + available slot (see below). + + dev_hint=645:1,680=2 The PCA645 camera will get /dev/video1, + and a PCVC680 /dev/video2. + + dev_hint=645.0123:3,645.4567:0 The PCA645 camera with serialnumber + 0123 goes to /dev/video3, the same + camera model with the 4567 serial + gets /dev/video0. + + dev_hint=750:1,4,5,6 The PCVC750 camera will get /dev/video1, the + next 3 Philips cams will use /dev/video4 + through /dev/video6. + + Some points worth knowing: + - Serialnumbers are case sensitive and must be written full, including + leading zeroes (it's treated as a string). + - If a device node is already occupied, registration will fail and + the webcam is not available. + - You can have up to 64 video devices; be sure to make enough device + nodes in /dev if you want to spread the numbers (this does not apply + to devfs). After /dev/video9 comes /dev/video10 (not /dev/videoA). + - If a camera does not match any dev_hint, it will simply get assigned + the first available device node, just as it used to be. trace In order to better detect problems, it is now possible to turn on a diff -u --recursive --new-file v2.5.0/linux/Documentation/usb/scanner.txt linux/Documentation/usb/scanner.txt --- v2.5.0/linux/Documentation/usb/scanner.txt Sat Oct 20 19:13:11 2001 +++ linux/Documentation/usb/scanner.txt Sat Dec 8 20:28:44 2001 @@ -83,7 +83,7 @@ `mknod /dev/usbscanner1 c 180 49` . . - `mknod /dev/usbscanner15 180 63` + `mknod /dev/usbscanner15 c 180 63` If you foresee using only one scanner it is best to: diff -u --recursive --new-file v2.5.0/linux/MAINTAINERS linux/MAINTAINERS --- v2.5.0/linux/MAINTAINERS Fri Nov 16 10:03:24 2001 +++ linux/MAINTAINERS Mon Dec 10 10:39:20 2001 @@ -148,8 +148,8 @@ ACPI P: Andy Grover M: andrew.grover@intel.com -L: acpi@phobos.fs.tum.de -W: http://phobos.fs.tum.de/acpi/index.html +L: acpi-devel@lists.sourceforge.net +W: http://sf.net/projects/acpi/ S: Maintained AD1816 SOUND DRIVER @@ -285,6 +285,14 @@ M: Nils Faerber S: Maintained +CODA FILE SYSTEM +P: Jan Harkes +M: jaharkes@cs.cmu.edu +M: coda@cs.cmu.edu +L: codalist@coda.cs.cmu.edu +W: http://www.coda.cs.cmu.edu/ +S: Maintained + COMPAQ FIBRE CHANNEL 64-bit/66MHz PCI non-intelligent HBA P: Amy Vanzant-Hodge M: Amy Vanzant-Hodge (fibrechannel@compaq.com) @@ -1660,8 +1668,8 @@ W: http://misc.nu/hugh/keyspan/ USB SUBSYSTEM -P: Johannes Erdfelt -M: johannes@erdfelt.com +P: Greg Kroah-Hartman +M: greg@kroah.com L: linux-usb-users@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net W: http://www.linux-usb.org @@ -1684,10 +1692,8 @@ VIA 82Cxxx AUDIO DRIVER P: Jeff Garzik -M: jgarzik@mandrakesoft.com L: linux-via@gtf.org -W: http://sourceforge.net/projects/gkernel/ -S: Maintained +S: Odd fixes USB DIAMOND RIO500 DRIVER P: Cesar Miquel diff -u --recursive --new-file v2.5.0/linux/Makefile linux/Makefile --- v2.5.0/linux/Makefile Thu Nov 22 22:23:44 2001 +++ linux/Makefile Sun Dec 16 15:53:11 2001 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 5 -SUBLEVEL = 0 +SUBLEVEL = 1 EXTRAVERSION = KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -257,8 +257,8 @@ boot: vmlinux @$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot -vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs - $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \ +vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs + $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \ --start-group \ $(CORE_FILES) \ $(DRIVERS) \ @@ -333,6 +333,9 @@ $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(ARCH)"' -c -o init/version.o init/version.c init/main.o: init/main.c include/config/MARKER + $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $< + +init/do_mounts.o: init/do_mounts.c include/config/MARKER $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $< fs lib mm ipc kernel drivers net: dummy diff -u --recursive --new-file v2.5.0/linux/README linux/README --- v2.5.0/linux/README Fri Oct 5 12:10:00 2001 +++ linux/README Fri Nov 30 08:54:18 2001 @@ -1,9 +1,12 @@ - Linux kernel release 2.4.xx + Linux kernel release 2.5.xx -These are the release notes for Linux version 2.4. Read them carefully, +These are the release notes for Linux version 2.5. Read them carefully, as they tell you what this is all about, explain how to install the kernel, and what to do if something goes wrong. +NOTE! As with all odd-numbered releases, 2.5.x is a development kernel. +For stable kernels, see the 2.4.x maintained by Marcelo Tosatti. + WHAT IS LINUX? Linux is a Unix clone written from scratch by Linus Torvalds with @@ -52,7 +55,7 @@ directory where you have permissions (eg. your home directory) and unpack it: - gzip -cd linux-2.4.XX.tar.gz | tar xvf - + gzip -cd linux-2.5.XX.tar.gz | tar xvf - Replace "XX" with the version number of the latest kernel. @@ -61,7 +64,7 @@ files. They should match the library, and not get messed up by whatever the kernel-du-jour happens to be. - - You can also upgrade between 2.4.xx releases by patching. Patches are + - You can also upgrade between 2.5.xx releases by patching. Patches are distributed in the traditional gzip and the new bzip2 format. To install by patching, get all the newer patch files, enter the directory in which you unpacked the kernel source and execute: @@ -96,7 +99,7 @@ SOFTWARE REQUIREMENTS - Compiling and running the 2.4.xx kernels requires up-to-date + Compiling and running the 2.5.xx kernels requires up-to-date versions of various software packages. Consult ./Documentation/Changes for the minimum version numbers required and how to get updates for these packages. Beware that using @@ -150,13 +153,12 @@ COMPILING the kernel: - - Make sure you have gcc-2.91.66 (egcs-1.1.2) available. gcc 2.95.2 may + - Make sure you have gcc 2.95.3 available. gcc 2.91.66 (egcs-1.1.2) may also work but is not as safe, and *gcc 2.7.2.3 is no longer supported*. Also remember to upgrade your binutils package (for as/ld/nm and company) if necessary. For more information, refer to ./Documentation/Changes. - Please note that you can still run a.out user programs with this - kernel. + Please note that you can still run a.out user programs with this kernel. - Do a "make bzImage" to create a compressed kernel image. If you want to make a boot disk (without root filesystem or LILO), insert a floppy diff -u --recursive --new-file v2.5.0/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c --- v2.5.0/linux/arch/alpha/kernel/alpha_ksyms.c Tue Nov 20 15:49:31 2001 +++ linux/arch/alpha/kernel/alpha_ksyms.c Sun Nov 25 09:45:10 2001 @@ -109,6 +109,7 @@ EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(__memset); EXPORT_SYMBOL(__memsetw); diff -u --recursive --new-file v2.5.0/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c --- v2.5.0/linux/arch/alpha/kernel/irq.c Mon Sep 17 13:16:30 2001 +++ linux/arch/alpha/kernel/irq.c Wed Nov 28 13:22:25 2001 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -514,64 +515,63 @@ } int -get_irq_list(char *buf) +show_interrupts(struct seq_file *p, void *v) { #ifdef CONFIG_SMP int j; #endif int i; struct irqaction * action; - char *p = buf; #ifdef CONFIG_SMP - p += sprintf(p, " "); + seq_puts(p, " "); for (i = 0; i < smp_num_cpus; i++) - p += sprintf(p, "CPU%d ", i); + seq_printf(p, "CPU%d ", i); #ifdef DO_BROADCAST_INTS for (i = 0; i < smp_num_cpus; i++) - p += sprintf(p, "TRY%d ", i); + seq_printf(p, "TRY%d ", i); #endif - *p++ = '\n'; + seq_putc(p, '\n'); #endif for (i = 0; i < NR_IRQS; i++) { action = irq_desc[i].action; if (!action) continue; - p += sprintf(p, "%3d: ",i); + seq_printf(p, "%3d: ",i); #ifndef CONFIG_SMP - p += sprintf(p, "%10u ", kstat_irqs(i)); + seq_printf(p, "%10u ", kstat_irqs(i)); #else for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", kstat.irqs[cpu_logical_map(j)][i]); #ifdef DO_BROADCAST_INTS for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10lu ", + seq_printf(p, "%10lu ", irq_attempt(cpu_logical_map(j), i)); #endif #endif - p += sprintf(p, " %14s", irq_desc[i].handler->typename); - p += sprintf(p, " %c%s", + seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %c%s", (action->flags & SA_INTERRUPT)?'+':' ', action->name); for (action=action->next; action; action = action->next) { - p += sprintf(p, ", %c%s", + seq_printf(p, ", %c%s", (action->flags & SA_INTERRUPT)?'+':' ', action->name); } - *p++ = '\n'; + seq_putc(p, '\n'); } #if CONFIG_SMP - p += sprintf(p, "IPI: "); + seq_puts(p, "IPI: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10lu ", + seq_printf(p, "%10lu ", cpu_data[cpu_logical_map(j)].ipi_count); - p += sprintf(p, "\n"); + seq_putc(p, '\n'); #endif - p += sprintf(p, "ERR: %10lu\n", irq_err_count); - return p - buf; + seq_printf(p, "ERR: %10lu\n", irq_err_count); + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/alpha/kernel/irq_i8259.c linux/arch/alpha/kernel/irq_i8259.c --- v2.5.0/linux/arch/alpha/kernel/irq_i8259.c Mon Jun 19 17:59:32 2000 +++ linux/arch/alpha/kernel/irq_i8259.c Mon Dec 10 13:52:53 2001 @@ -22,7 +22,7 @@ /* Note mask bit is true for DISABLED irqs. */ static unsigned int cached_irq_mask = 0xffff; -spinlock_t i8259_irq_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t i8259_irq_lock = SPIN_LOCK_UNLOCKED; static inline void i8259_update_irq_hw(unsigned int irq, unsigned long mask) diff -u --recursive --new-file v2.5.0/linux/arch/arm/kernel/fiq.c linux/arch/arm/kernel/fiq.c --- v2.5.0/linux/arch/arm/kernel/fiq.c Wed Jun 27 14:12:04 2001 +++ linux/arch/arm/kernel/fiq.c Wed Nov 28 13:22:25 2001 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -92,15 +93,12 @@ static struct fiq_handler *current_fiq = &default_owner; -int get_fiq_list(char *buf) +int show_fiq_list(struct seq_file *p, void *v) { - char *p = buf; - if (current_fiq != &default_owner) - p += sprintf(p, "FIQ: %s\n", - current_fiq->name); + seq_printf(p, "FIQ: %s\n", current_fiq->name); - return p - buf; + return 0; } void set_fiq_handler(void *start, unsigned int length) diff -u --recursive --new-file v2.5.0/linux/arch/arm/kernel/irq.c linux/arch/arm/kernel/irq.c --- v2.5.0/linux/arch/arm/kernel/irq.c Wed Jul 4 14:56:44 2001 +++ linux/arch/arm/kernel/irq.c Wed Nov 28 13:22:25 2001 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -95,29 +96,28 @@ spin_unlock_irqrestore(&irq_controller_lock, flags); } -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { int i; struct irqaction * action; - char *p = buf; for (i = 0 ; i < NR_IRQS ; i++) { action = irq_desc[i].action; if (!action) continue; - p += sprintf(p, "%3d: %10u ", i, kstat_irqs(i)); - p += sprintf(p, " %s", action->name); + seq_printf(p, "%3d: %10u ", i, kstat_irqs(i)); + seq_printf(p, " %s", action->name); for (action = action->next; action; action = action->next) { - p += sprintf(p, ", %s", action->name); + seq_printf(p, ", %s", action->name); } - *p++ = '\n'; + seq_putc(p, '\n'); } #ifdef CONFIG_ARCH_ACORN - p += get_fiq_list(p); + show_fiq_list(p); #endif - p += sprintf(p, "Err: %10lu\n", irq_err_count); - return p - buf; + seq_printf(p, "Err: %10lu\n", irq_err_count); + return 0; } /* diff -u --recursive --new-file v2.5.0/linux/arch/cris/kernel/irq.c linux/arch/cris/kernel/irq.c --- v2.5.0/linux/arch/cris/kernel/irq.c Thu Jul 26 15:10:06 2001 +++ linux/arch/cris/kernel/irq.c Wed Nov 28 13:22:25 2001 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -223,27 +224,27 @@ NULL, NULL, NULL, NULL }; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; struct irqaction * action; for (i = 0; i < NR_IRQS; i++) { action = irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %10u %c %s", + seq_printf(p, "%2d: %10u %c %s", i, kstat.irqs[0][i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action = action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, "\n"); + seq_putc(p, '\n'); } - return len; + return 0; } /* called by the assembler IRQ entry functions defined in irq.h diff -u --recursive --new-file v2.5.0/linux/arch/i386/boot/bootsect.S linux/arch/i386/boot/bootsect.S --- v2.5.0/linux/arch/i386/boot/bootsect.S Fri Nov 9 13:58:02 2001 +++ linux/arch/i386/boot/bootsect.S Wed Nov 28 14:07:46 2001 @@ -236,7 +236,7 @@ rp_read: #ifdef __BIG_KERNEL__ # look in setup.S for bootsect_kludge bootsect_kludge = 0x220 # 0x200 + 0x20 which is the size of the - lcall bootsect_kludge # bootsector + bootsect_kludge offset + lcall *bootsect_kludge # bootsector + bootsect_kludge offset #else movw %es, %ax subw $SYSSEG, %ax diff -u --recursive --new-file v2.5.0/linux/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S --- v2.5.0/linux/arch/i386/boot/setup.S Fri Nov 9 13:58:02 2001 +++ linux/arch/i386/boot/setup.S Wed Nov 28 10:24:33 2001 @@ -539,7 +539,7 @@ cmpw $0, %cs:realmode_swtch jz rmodeswtch_normal - lcall %cs:realmode_swtch + lcall *%cs:realmode_swtch jmp rmodeswtch_end diff -u --recursive --new-file v2.5.0/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.5.0/linux/arch/i386/defconfig Mon Nov 12 11:59:03 2001 +++ linux/arch/i386/defconfig Sat Dec 8 20:30:25 2001 @@ -286,7 +286,6 @@ # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -CONFIG_SCSI_DEBUG_QUEUES=y CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -431,6 +430,7 @@ # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set diff -u --recursive --new-file v2.5.0/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c --- v2.5.0/linux/arch/i386/kernel/apm.c Fri Nov 9 13:58:02 2001 +++ linux/arch/i386/kernel/apm.c Fri Nov 30 08:38:44 2001 @@ -387,6 +387,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); static struct apm_user * user_list; +static spinlock_t user_list_lock = SPIN_LOCK_UNLOCKED; static char driver_version[] = "1.15"; /* no spaces */ @@ -526,7 +527,7 @@ __asm__ __volatile__(APM_DO_ZERO_SEGS "pushl %%edi\n\t" "pushl %%ebp\n\t" - "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" + "lcall *%%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" "setc %%al\n\t" "popl %%ebp\n\t" "popl %%edi\n\t" @@ -573,7 +574,7 @@ __asm__ __volatile__(APM_DO_ZERO_SEGS "pushl %%edi\n\t" "pushl %%ebp\n\t" - "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" + "lcall *%%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" "setc %%bl\n\t" "popl %%ebp\n\t" "popl %%edi\n\t" @@ -1053,8 +1054,9 @@ { struct apm_user * as; + spin_lock(&user_list_lock); if (user_list == NULL) - return; + goto out; for (as = user_list; as != NULL; as = as->next) { if ((as == sender) || (!as->reader)) continue; @@ -1084,6 +1086,8 @@ } } wake_up_interruptible(&apm_waitqueue); +out: + spin_unlock(&user_list_lock); } static void set_time(void) @@ -1179,10 +1183,12 @@ send_event(APM_NORMAL_RESUME); sti(); queue_event(APM_NORMAL_RESUME, NULL); + spin_lock(&user_list_lock); for (as = user_list; as != NULL; as = as->next) { as->suspend_wait = 0; as->suspend_result = ((err == APM_SUCCESS) ? 0 : -EIO); } + spin_unlock(&user_list_lock); ignore_normal_resume = 1; wake_up_interruptible(&apm_suspend_waitqueue); return err; @@ -1519,7 +1525,6 @@ if (check_apm_user(as, "release")) return 0; filp->private_data = NULL; - lock_kernel(); if (as->standbys_pending > 0) { standbys_pending -= as->standbys_pending; if (standbys_pending <= 0) @@ -1530,6 +1535,7 @@ if (suspends_pending <= 0) (void) suspend(); } + spin_lock(&user_list_lock); if (user_list == as) user_list = as->next; else { @@ -1544,7 +1550,7 @@ else as1->next = as->next; } - unlock_kernel(); + spin_unlock(&user_list_lock); kfree(as); return 0; } @@ -1573,8 +1579,10 @@ as->suser = capable(CAP_SYS_ADMIN); as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE; as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ; + spin_lock(&user_list_lock); as->next = user_list; user_list = as; + spin_unlock(&user_list_lock); filp->private_data = as; return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/i386/kernel/dmi_scan.c linux/arch/i386/kernel/dmi_scan.c --- v2.5.0/linux/arch/i386/kernel/dmi_scan.c Sun Nov 11 10:38:46 2001 +++ linux/arch/i386/kernel/dmi_scan.c Thu Dec 6 14:01:17 2001 @@ -191,6 +191,7 @@ * corruption problems */ +#if 0 static __init int disable_ide_dma(struct dmi_blacklist *d) { #ifdef CONFIG_BLK_DEV_IDE @@ -203,6 +204,7 @@ #endif return 0; } +#endif /* * Reboot options and system auto-detection code provided by @@ -521,6 +523,12 @@ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "R0121Z1"), MATCH(DMI_BIOS_DATE, "05/11/00"), NO_MATCH + } }, + + { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z600NE */ + MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), + MATCH(DMI_BIOS_VERSION, "WME01Z1"), + MATCH(DMI_BIOS_DATE, "08/11/00"), NO_MATCH } }, { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS */ diff -u --recursive --new-file v2.5.0/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.5.0/linux/arch/i386/kernel/irq.c Thu Oct 25 13:53:46 2001 +++ linux/arch/i386/kernel/irq.c Wed Nov 28 13:22:25 2001 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -131,57 +132,53 @@ * Generic, controller-independent functions: */ -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; - char *p = buf; - p += sprintf(p, " "); + seq_printf(p, " "); for (j=0; jtypename); - p += sprintf(p, " %s", action->name); + seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) - p += sprintf(p, ", %s", action->name); - *p++ = '\n'; + seq_printf(p, ", %s", action->name); + seq_putc(p, '\n'); } - p += sprintf(p, "NMI: "); + seq_printf(p, "NMI: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", - nmi_count(cpu_logical_map(j))); - p += sprintf(p, "\n"); + seq_printf(p, "%10u ", nmi_count(cpu_logical_map(j))); + seq_putc(p, '\n'); #if CONFIG_X86_LOCAL_APIC - p += sprintf(p, "LOC: "); + seq_printf(p, "LOC: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", - apic_timer_irqs[cpu_logical_map(j)]); - p += sprintf(p, "\n"); + seq_printf(p, "%10u ", apic_timer_irqs[cpu_logical_map(j)]); + seq_putc(p, '\n'); #endif - p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); + seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); #ifdef CONFIG_X86_IO_APIC #ifdef APIC_MISMATCH_DEBUG - p += sprintf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); + seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); #endif #endif - return p - buf; + return 0; } - /* * Global interrupt locks for SMP. Allow interrupts to come in on any diff -u --recursive --new-file v2.5.0/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c --- v2.5.0/linux/arch/i386/kernel/mtrr.c Fri Nov 9 13:58:02 2001 +++ linux/arch/i386/kernel/mtrr.c Fri Nov 30 08:26:04 2001 @@ -1788,7 +1788,6 @@ unsigned int *fcount = file->private_data; if (fcount == NULL) return 0; - lock_kernel(); max = get_num_var_ranges (); for (i = 0; i < max; ++i) { @@ -1798,7 +1797,6 @@ --fcount[i]; } } - unlock_kernel(); kfree (fcount); file->private_data = NULL; return 0; diff -u --recursive --new-file v2.5.0/linux/arch/i386/kernel/pci-pc.c linux/arch/i386/kernel/pci-pc.c --- v2.5.0/linux/arch/i386/kernel/pci-pc.c Fri Nov 9 13:58:02 2001 +++ linux/arch/i386/kernel/pci-pc.c Fri Dec 7 16:26:13 2001 @@ -458,7 +458,7 @@ unsigned long flags; __save_flags(flags); __cli(); - __asm__("lcall (%%edi); cld" + __asm__("lcall *(%%edi); cld" : "=a" (return_code), "=b" (address), "=c" (length), @@ -499,7 +499,7 @@ __save_flags(flags); __cli(); __asm__( - "lcall (%%edi); cld\n\t" + "lcall *(%%edi); cld\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -544,7 +544,7 @@ unsigned short bx; unsigned short ret; - __asm__("lcall (%%edi); cld\n\t" + __asm__("lcall *(%%edi); cld\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -573,7 +573,7 @@ switch (len) { case 1: - __asm__("lcall (%%esi); cld\n\t" + __asm__("lcall *(%%esi); cld\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -585,7 +585,7 @@ "S" (&pci_indirect)); break; case 2: - __asm__("lcall (%%esi); cld\n\t" + __asm__("lcall *(%%esi); cld\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -597,7 +597,7 @@ "S" (&pci_indirect)); break; case 4: - __asm__("lcall (%%esi); cld\n\t" + __asm__("lcall *(%%esi); cld\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -628,7 +628,7 @@ switch (len) { case 1: - __asm__("lcall (%%esi); cld\n\t" + __asm__("lcall *(%%esi); cld\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -640,7 +640,7 @@ "S" (&pci_indirect)); break; case 2: - __asm__("lcall (%%esi); cld\n\t" + __asm__("lcall *(%%esi); cld\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -652,7 +652,7 @@ "S" (&pci_indirect)); break; case 4: - __asm__("lcall (%%esi); cld\n\t" + __asm__("lcall *(%%esi); cld\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -875,7 +875,7 @@ __asm__("push %%es\n\t" "push %%ds\n\t" "pop %%es\n\t" - "lcall (%%esi); cld\n\t" + "lcall *(%%esi); cld\n\t" "pop %%es\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" @@ -908,7 +908,7 @@ { int ret; - __asm__("lcall (%%esi); cld\n\t" + __asm__("lcall *(%%esi); cld\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -1114,17 +1114,26 @@ * But it does seem to fix some unspecified problem * with 'movntq' copies on Athlons. * - * VIA 8363 chipset: - * - bit 7 at offset 0x55: Debug (RW) + * VIA 8363,8622,8361 Northbridges: + * - bits 5, 6, 7 at offset 0x55 need to be turned off + * VIA 8367 (KT266x) Northbridges: + * - bits 5, 6, 7 at offset 0x95 need to be turned off */ static void __init pci_fixup_via_athlon_bug(struct pci_dev *d) { u8 v; - pci_read_config_byte(d, 0x55, &v); - if (v & 0x80) { + int where = 0x55; + + if (d->device == PCI_DEVICE_ID_VIA_8367_0) { + where = 0x95; /* the memory write queue timer register is + different for the kt266x's: 0x95 not 0x55 */ + } + + pci_read_config_byte(d, where, &v); + if (v & 0xe0) { printk("Trying to stomp on Athlon bug...\n"); - v &= 0x7f; /* clear bit 55.7 */ - pci_write_config_byte(d, 0x55, v); + v &= 0x1f; /* clear bits 5, 6, 7 */ + pci_write_config_byte(d, where, v); } } @@ -1138,6 +1147,9 @@ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5598, pci_fixup_latency }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci_fixup_piix4_acpi }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_via_athlon_bug }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_athlon_bug }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_athlon_bug }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_athlon_bug }, { 0 } }; diff -u --recursive --new-file v2.5.0/linux/arch/i386/kernel/semaphore.c linux/arch/i386/kernel/semaphore.c --- v2.5.0/linux/arch/i386/kernel/semaphore.c Fri Nov 9 13:58:02 2001 +++ linux/arch/i386/kernel/semaphore.c Fri Nov 30 08:54:18 2001 @@ -238,31 +238,30 @@ */ #if defined(CONFIG_SMP) asm( -" -.align 4 -.globl __write_lock_failed -__write_lock_failed: - " LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax) -1: rep; nop - cmpl $" RW_LOCK_BIAS_STR ",(%eax) - jne 1b +".text\n" +".align 4\n" +".globl __write_lock_failed\n" +"__write_lock_failed:\n\t" + LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" +"1: rep; nop\n\t" + "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" + "jne 1b\n\t" + LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" + "jnz __write_lock_failed\n\t" + "ret" +); - " LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax) - jnz __write_lock_failed - ret - - -.align 4 -.globl __read_lock_failed -__read_lock_failed: - lock ; incl (%eax) -1: rep; nop - cmpl $1,(%eax) - js 1b - - lock ; decl (%eax) - js __read_lock_failed - ret -" +asm( +".text\n" +".align 4\n" +".globl __read_lock_failed\n" +"__read_lock_failed:\n\t" + LOCK "incl (%eax)\n" +"1: rep; nop\n\t" + "cmpl $1,(%eax)\n\t" + "js 1b\n\t" + LOCK "decl (%eax)\n\t" + "js __read_lock_failed\n\t" + "ret" ); #endif diff -u --recursive --new-file v2.5.0/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- v2.5.0/linux/arch/i386/kernel/setup.c Mon Nov 19 15:16:13 2001 +++ linux/arch/i386/kernel/setup.c Tue Nov 27 09:23:27 2001 @@ -157,6 +157,7 @@ extern void mcheck_init(struct cpuinfo_x86 *c); extern int root_mountflags; extern char _text, _etext, _edata, _end; +extern int blk_nohighio; static int disable_x86_serial_nr __initdata = 1; static int disable_x86_fxsr __initdata = 0; @@ -782,7 +783,7 @@ void __init setup_arch(char **cmdline_p) { unsigned long bootmap_size, low_mem_size; - unsigned long start_pfn, max_pfn, max_low_pfn; + unsigned long start_pfn, max_low_pfn; int i; #ifdef CONFIG_VISWS @@ -1067,6 +1068,14 @@ __setup("notsc", tsc_setup); #endif +static int __init highio_setup(char *str) +{ + printk("i386: disabling HIGHMEM block I/O\n"); + blk_nohighio = 1; + return 1; +} +__setup("nohighio", highio_setup); + static int __init get_model_name(struct cpuinfo_x86 *c) { unsigned int *v; diff -u --recursive --new-file v2.5.0/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c --- v2.5.0/linux/arch/i386/kernel/traps.c Sun Sep 30 12:26:08 2001 +++ linux/arch/i386/kernel/traps.c Sun Nov 25 09:48:47 2001 @@ -697,7 +697,7 @@ */ asmlinkage void math_state_restore(struct pt_regs regs) { - __asm__ __volatile__("clts"); /* Allow maths ops (or we recurse) */ + clts(); /* Allow maths ops (or we recurse) */ if (current->used_math) { restore_fpu(current); diff -u --recursive --new-file v2.5.0/linux/arch/i386/lib/iodebug.c linux/arch/i386/lib/iodebug.c --- v2.5.0/linux/arch/i386/lib/iodebug.c Tue Oct 19 12:26:53 1999 +++ linux/arch/i386/lib/iodebug.c Tue Dec 11 10:47:49 2001 @@ -9,11 +9,3 @@ return (void *)x; } -unsigned long __io_phys_debug(unsigned long x, const char *file, int line) -{ - if (x < PAGE_OFFSET) { - printk("io mapaddr 0x%05lx not valid at %s:%d!\n", x, file, line); - return x; - } - return __pa(x); -} diff -u --recursive --new-file v2.5.0/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c --- v2.5.0/linux/arch/i386/mm/init.c Sun Nov 11 10:09:32 2001 +++ linux/arch/i386/mm/init.c Sun Nov 25 09:48:47 2001 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -333,7 +334,7 @@ { pagetable_init(); - __asm__( "movl %%ecx,%%cr3\n" ::"c"(__pa(swapper_pg_dir))); + __asm__( "movl %0,%%cr3\n" ::"r"(__pa(swapper_pg_dir))); #if CONFIG_X86_PAE /* @@ -596,3 +597,17 @@ val->mem_unit = PAGE_SIZE; return; } + +#if defined(CONFIG_X86_PAE) +struct kmem_cache_s *pae_pgd_cachep; +void __init pgtable_cache_init(void) +{ + /* + * PAE pgds must be 16-byte aligned: + */ + pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0, + SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL); + if (!pae_pgd_cachep) + panic("init_pae(): Cannot alloc pae_pgd SLAB cache"); +} +#endif /* CONFIG_X86_PAE */ diff -u --recursive --new-file v2.5.0/linux/arch/ia64/kernel/efivars.c linux/arch/ia64/kernel/efivars.c --- v2.5.0/linux/arch/ia64/kernel/efivars.c Fri Nov 9 14:26:17 2001 +++ linux/arch/ia64/kernel/efivars.c Mon Dec 10 13:52:53 2001 @@ -100,7 +100,7 @@ struct list_head list; } efivar_entry_t; -spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED; static LIST_HEAD(efivar_list); static struct proc_dir_entry *efi_vars_dir = NULL; diff -u --recursive --new-file v2.5.0/linux/arch/ia64/kernel/irq.c linux/arch/ia64/kernel/irq.c --- v2.5.0/linux/arch/ia64/kernel/irq.c Fri Nov 9 14:26:17 2001 +++ linux/arch/ia64/kernel/irq.c Wed Nov 28 13:22:25 2001 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -131,55 +132,54 @@ * Generic, controller-independent functions: */ -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; irq_desc_t *idesc; - char *p = buf; - p += sprintf(p, " "); + seq_puts(p, " "); for (j=0; jaction; if (!action) continue; - p += sprintf(p, "%3d: ",i); + seq_printf(p, "%3d: ",i); #ifndef CONFIG_SMP - p += sprintf(p, "%10u ", kstat_irqs(i)); + seq_printf(p, "%10u ", kstat_irqs(i)); #else for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", kstat.irqs[cpu_logical_map(j)][i]); #endif - p += sprintf(p, " %14s", idesc->handler->typename); - p += sprintf(p, " %s", action->name); + seq_printf(p, " %14s", idesc->handler->typename); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) - p += sprintf(p, ", %s", action->name); - *p++ = '\n'; + seq_printf(p, ", %s", action->name); + seq_putc('\n'); } - p += sprintf(p, "NMI: "); + seq_puts(p, "NMI: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", nmi_count(cpu_logical_map(j))); - p += sprintf(p, "\n"); + seq_putc(p, '\n'); #if defined(CONFIG_SMP) && defined(CONFIG_X86) - p += sprintf(p, "LOC: "); + seq_puts(p, "LOC: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", apic_timer_irqs[cpu_logical_map(j)]); - p += sprintf(p, "\n"); + seq_putc(p, '\n'); #endif - p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); + seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); #if defined(CONFIG_X86) && defined(CONFIG_X86_IO_APIC) && defined(APIC_MISMATCH_DEBUG) - p += sprintf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); + seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); #endif - return p - buf; + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/ia64/kernel/pci.c linux/arch/ia64/kernel/pci.c --- v2.5.0/linux/arch/ia64/kernel/pci.c Fri Nov 9 14:26:17 2001 +++ linux/arch/ia64/kernel/pci.c Mon Dec 10 13:52:53 2001 @@ -46,7 +46,7 @@ * This interrupt-safe spinlock protects all accesses to PCI * configuration space. */ -spinlock_t pci_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t pci_lock = SPIN_LOCK_UNLOCKED; struct pci_fixup pcibios_fixups[] = { { 0 } diff -u --recursive --new-file v2.5.0/linux/arch/ia64/sn/io/hubspc.c linux/arch/ia64/sn/io/hubspc.c --- v2.5.0/linux/arch/ia64/sn/io/hubspc.c Thu Apr 5 12:51:47 2001 +++ linux/arch/ia64/sn/io/hubspc.c Mon Dec 10 13:52:53 2001 @@ -61,7 +61,7 @@ }cpuprom_info_t; static cpuprom_info_t *cpuprom_head; -spinlock_t cpuprom_spinlock; +static spinlock_t cpuprom_spinlock; #define PROM_LOCK() mutex_spinlock(&cpuprom_spinlock) #define PROM_UNLOCK(s) mutex_spinunlock(&cpuprom_spinlock, (s)) diff -u --recursive --new-file v2.5.0/linux/arch/m68k/amiga/amiints.c linux/arch/m68k/amiga/amiints.c --- v2.5.0/linux/arch/m68k/amiga/amiints.c Mon Nov 27 17:57:34 2000 +++ linux/arch/m68k/amiga/amiints.c Wed Nov 28 13:22:25 2001 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -53,7 +54,7 @@ unsigned long flags, const char *devname, void *dev_id); extern void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id); extern void cia_init_IRQ(struct ciabase *base); -extern int cia_get_irq_list(struct ciabase *base, char *buf); +extern int cia_get_irq_list(struct ciabase *base, struct seq_file *p); /* irq node variables for amiga interrupt sources */ static irq_node_t *ami_irq_list[AMI_STD_IRQS]; @@ -468,28 +469,28 @@ ami_int4, ami_int5, ami_badint, ami_int7 }; -int amiga_get_irq_list(char *buf) +int show_amiga_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; irq_node_t *node; for (i = 0; i < AMI_STD_IRQS; i++) { if (!(node = ami_irq_list[i])) continue; - len += sprintf(buf+len, "ami %2d: %10u ", i, + seq_printf(p, "ami %2d: %10u ", i, kstat.irqs[0][SYS_IRQS + i]); do { if (node->flags & SA_INTERRUPT) - len += sprintf(buf+len, "F "); + seq_puts(p, "F "); else - len += sprintf(buf+len, " "); - len += sprintf(buf+len, "%s\n", node->devname); + seq_puts(p, " "); + seq_printf(p, "%s\n", node->devname); if ((node = node->next)) - len += sprintf(buf+len, " "); + seq_puts(p, " "); } while (node); } - len += cia_get_irq_list(&ciaa_base, buf+len); - len += cia_get_irq_list(&ciab_base, buf+len); - return len; + cia_get_irq_list(&ciaa_base, p); + cia_get_irq_list(&ciab_base, p); + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/m68k/amiga/cia.c linux/arch/m68k/amiga/cia.c --- v2.5.0/linux/arch/m68k/amiga/cia.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/amiga/cia.c Wed Nov 28 13:22:25 2001 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -158,16 +159,16 @@ custom.intena = IF_SETCLR | base->int_mask; } -int cia_get_irq_list(struct ciabase *base, char *buf) +int cia_get_irq_list(struct ciabase *base, struct seq_file *p) { - int i, j, len = 0; + int i, j; j = base->cia_irq; for (i = 0; i < CIA_IRQS; i++) { - len += sprintf(buf+len, "cia %2d: %10d ", j + i, + seq_printf(p, "cia %2d: %10d ", j + i, kstat.irqs[0][SYS_IRQS + j + i]); - len += sprintf(buf+len, " "); - len += sprintf(buf+len, "%s\n", base->irq_list[i].devname); + seq_puts(p, " "); + seq_printf(p, "%s\n", base->irq_list[i].devname); } - return len; + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/m68k/amiga/config.c linux/arch/m68k/amiga/config.c --- v2.5.0/linux/arch/m68k/amiga/config.c Thu Sep 13 15:21:32 2001 +++ linux/arch/m68k/amiga/config.c Wed Nov 28 13:22:25 2001 @@ -86,7 +86,7 @@ extern void amiga_disable_irq (unsigned int); static void amiga_get_model(char *model); static int amiga_get_hardware_list(char *buffer); -extern int amiga_get_irq_list (char *); +extern int show_amiga_interrupts (struct seq_file *, void *); /* amiga specific timer functions */ static unsigned long amiga_gettimeoffset (void); static void a3000_gettod (int *, int *, int *, int *, int *, int *); @@ -403,7 +403,7 @@ disable_irq = amiga_disable_irq; mach_get_model = amiga_get_model; mach_get_hardware_list = amiga_get_hardware_list; - mach_get_irq_list = amiga_get_irq_list; + mach_get_irq_list = show_amiga_interrupts; mach_gettimeoffset = amiga_gettimeoffset; if (AMIGAHW_PRESENT(A3000_CLK)){ mach_gettod = a3000_gettod; diff -u --recursive --new-file v2.5.0/linux/arch/m68k/apollo/config.c linux/arch/m68k/apollo/config.c --- v2.5.0/linux/arch/m68k/apollo/config.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/apollo/config.c Wed Nov 28 13:22:25 2001 @@ -31,7 +31,7 @@ extern void dn_free_irq(unsigned int irq, void *dev_id); extern void dn_enable_irq(unsigned int); extern void dn_disable_irq(unsigned int); -extern int dn_get_irq_list(char *); +extern int show_dn_interrupts(struct seq_file *, void *); extern unsigned long dn_gettimeoffset(void); extern void dn_gettod(int *, int *, int *, int *, int *, int *); extern int dn_dummy_hwclk(int, struct hwclk_time *); @@ -173,7 +173,7 @@ mach_free_irq = dn_free_irq; enable_irq = dn_enable_irq; disable_irq = dn_disable_irq; - mach_get_irq_list = dn_get_irq_list; + mach_get_irq_list = show_dn_interrupts; mach_gettimeoffset = dn_gettimeoffset; mach_gettod = dn_gettod; /* */ mach_max_dma_address = 0xffffffff; diff -u --recursive --new-file v2.5.0/linux/arch/m68k/apollo/dn_ints.c linux/arch/m68k/apollo/dn_ints.c --- v2.5.0/linux/arch/m68k/apollo/dn_ints.c Tue Mar 6 19:44:35 2001 +++ linux/arch/m68k/apollo/dn_ints.c Wed Nov 28 13:22:25 2001 @@ -104,7 +104,7 @@ } -int dn_get_irq_list(char *buf) { +int show_dn_interrupts(struct seq_file *p, void *v) { printk("dn get irq list\n"); diff -u --recursive --new-file v2.5.0/linux/arch/m68k/atari/ataints.c linux/arch/m68k/atari/ataints.c --- v2.5.0/linux/arch/m68k/atari/ataints.c Fri Aug 4 16:15:37 2000 +++ linux/arch/m68k/atari/ataints.c Wed Nov 28 13:22:25 2001 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -609,37 +610,37 @@ } -int atari_get_irq_list(char *buf) +int show_atari_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; for (i = 0; i < NUM_INT_SOURCES; ++i) { if (vectors[IRQ_SOURCE_TO_VECTOR(i)] == bad_interrupt) continue; if (i < STMFP_SOURCE_BASE) - len += sprintf(buf+len, "auto %2d: %10u ", + seq_printf(p,, "auto %2d: %10u ", i, kstat.irqs[0][i]); else - len += sprintf(buf+len, "vec $%02x: %10u ", + seq_printf(p,, "vec $%02x: %10u ", IRQ_SOURCE_TO_VECTOR(i), kstat.irqs[0][i]); if (irq_handler[i].handler != atari_call_irq_list) { - len += sprintf(buf+len, "%s\n", irq_param[i].devname); + seq_printf(p,, "%s\n", irq_param[i].devname); } else { irq_node_t *p; for( p = (irq_node_t *)irq_handler[i].dev_id; p; p = p->next ) { - len += sprintf(buf+len, "%s\n", p->devname); + seq_printf(p,, "%s\n", p->devname); if (p->next) - len += sprintf( buf+len, " " ); + seq_puts(p,, " " ); } } } if (num_spurious) - len += sprintf(buf+len, "spurio.: %10u\n", num_spurious); + seq_printf(p, "spurio.: %10u\n", num_spurious); - return len; + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/m68k/atari/config.c linux/arch/m68k/atari/config.c --- v2.5.0/linux/arch/m68k/atari/config.c Mon Nov 27 17:57:34 2000 +++ linux/arch/m68k/atari/config.c Wed Nov 28 13:22:25 2001 @@ -70,7 +70,7 @@ extern void atari_free_irq (unsigned int irq, void *dev_id); extern void atari_enable_irq (unsigned int); extern void atari_disable_irq (unsigned int); -extern int atari_get_irq_list (char *buf); +extern int show_atari_interrupts (struct seq_file *, void *); extern void atari_mksound( unsigned int count, unsigned int ticks ); #ifdef CONFIG_HEARTBEAT static void atari_heartbeat( int on ); @@ -265,7 +265,7 @@ disable_irq = atari_disable_irq; mach_get_model = atari_get_model; mach_get_hardware_list = atari_get_hardware_list; - mach_get_irq_list = atari_get_irq_list; + mach_get_irq_list = show_atari_interrupts; mach_gettimeoffset = atari_gettimeoffset; mach_reset = atari_reset; #ifdef CONFIG_ATARI_FLOPPY diff -u --recursive --new-file v2.5.0/linux/arch/m68k/atari/joystick.c linux/arch/m68k/atari/joystick.c --- v2.5.0/linux/arch/m68k/atari/joystick.c Wed Jul 12 21:58:42 2000 +++ linux/arch/m68k/atari/joystick.c Fri Nov 30 08:26:04 2001 @@ -61,13 +61,11 @@ { int minor = DEVICE_NR(inode->i_rdev); - lock_kernel(); joystick[minor].active = 0; joystick[minor].ready = 0; if ((joystick[0].active == 0) && (joystick[1].active == 0)) ikbd_joystick_disable(); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/m68k/bvme6000/bvmeints.c linux/arch/m68k/bvme6000/bvmeints.c --- v2.5.0/linux/arch/m68k/bvme6000/bvmeints.c Thu Dec 17 09:06:29 1998 +++ linux/arch/m68k/bvme6000/bvmeints.c Wed Nov 28 13:22:25 2001 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -127,17 +128,17 @@ } } -int bvme6000_get_irq_list (char *buf) +int show_bvme6000_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; for (i = 0; i < 256; i++) { if (irq_tab[i].count) - len += sprintf (buf+len, "Vec 0x%02x: %8d %s\n", + seq_printf(p, "Vec 0x%02x: %8d %s\n", i, irq_tab[i].count, irq_tab[i].devname ? irq_tab[i].devname : "free"); } - return len; + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/m68k/bvme6000/config.c linux/arch/m68k/bvme6000/config.c --- v2.5.0/linux/arch/m68k/bvme6000/config.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/bvme6000/config.c Wed Nov 28 13:22:25 2001 @@ -36,7 +36,7 @@ extern void bvme6000_process_int (int level, struct pt_regs *regs); extern void bvme6000_init_IRQ (void); extern void bvme6000_free_irq (unsigned int, void *); -extern int bvme6000_get_irq_list (char *); +extern int show_bvme6000_interrupts(struct seq_file *, void *); extern void bvme6000_enable_irq (unsigned int); extern void bvme6000_disable_irq (unsigned int); static void bvme6000_get_model(char *model); @@ -145,7 +145,7 @@ mach_reset = bvme6000_reset; mach_free_irq = bvme6000_free_irq; mach_process_int = bvme6000_process_int; - mach_get_irq_list = bvme6000_get_irq_list; + mach_get_irq_list = show_bvme6000_interrupts; mach_request_irq = bvme6000_request_irq; enable_irq = bvme6000_enable_irq; disable_irq = bvme6000_disable_irq; diff -u --recursive --new-file v2.5.0/linux/arch/m68k/hp300/config.c linux/arch/m68k/hp300/config.c --- v2.5.0/linux/arch/m68k/hp300/config.c Thu Aug 26 12:42:31 1999 +++ linux/arch/m68k/hp300/config.c Wed Nov 28 13:22:25 2001 @@ -25,7 +25,7 @@ extern void hp300_reset(void); extern void (*hp300_default_handler[])(int, void *, struct pt_regs *); -extern int hp300_get_irq_list(char *buf); +extern int show_hp300_interrupts(struct seq_file *, void *); #ifdef CONFIG_VT extern int hp300_keyb_init(void); @@ -70,7 +70,7 @@ mach_request_irq = hp300_request_irq; mach_free_irq = hp300_free_irq; mach_get_model = hp300_get_model; - mach_get_irq_list = hp300_get_irq_list; + mach_get_irq_list = show_hp300_interrupts; mach_gettimeoffset = hp300_gettimeoffset; mach_default_handler = &hp300_default_handler; #if 0 diff -u --recursive --new-file v2.5.0/linux/arch/m68k/hp300/ints.c linux/arch/m68k/hp300/ints.c --- v2.5.0/linux/arch/m68k/hp300/ints.c Wed Sep 8 11:59:00 1999 +++ linux/arch/m68k/hp300/ints.c Wed Nov 28 13:22:25 2001 @@ -148,7 +148,7 @@ spin_unlock_irqrestore(&irqlist_lock, flags); } -int hp300_get_irq_list(char *buf) +int show_hp300_interrupts(struct seq_file *p, void *v) { return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/m68k/kernel/ints.c linux/arch/m68k/kernel/ints.c --- v2.5.0/linux/arch/m68k/kernel/ints.c Tue Mar 6 19:44:36 2001 +++ linux/arch/m68k/kernel/ints.c Wed Nov 28 13:22:25 2001 @@ -242,22 +242,22 @@ } } -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; /* autovector interrupts */ if (mach_default_handler) { for (i = 0; i < SYS_IRQS; i++) { - len += sprintf(buf+len, "auto %2d: %10u ", i, + seq_printf(p, "auto %2d: %10u ", i, i ? kstat.irqs[0][i] : num_spurious); - len += sprintf(buf+len, " "); - len += sprintf(buf+len, "%s\n", irq_list[i].devname); + seq_puts(p, " "); + seq_printf(p, "%s\n", irq_list[i].devname); } } - len += mach_get_irq_list(buf+len); - return len; + mach_get_irq_list(p, v); + return 0; } void init_irq_proc(void) diff -u --recursive --new-file v2.5.0/linux/arch/m68k/kernel/setup.c linux/arch/m68k/kernel/setup.c --- v2.5.0/linux/arch/m68k/kernel/setup.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/kernel/setup.c Sun Dec 16 12:23:05 2001 @@ -80,7 +80,7 @@ void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; void (*mach_get_model) (char *model) = NULL; int (*mach_get_hardware_list) (char *buffer) = NULL; -int (*mach_get_irq_list) (char *) = NULL; +int (*mach_get_irq_list) (struct seq_file *, void *) = NULL; void (*mach_process_int) (int, struct pt_regs *) = NULL; /* machine dependent timer functions */ unsigned long (*mach_gettimeoffset) (void); @@ -93,7 +93,6 @@ long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ #if defined(CONFIG_AMIGA_FLOPPY) || defined(CONFIG_ATARI_FLOPPY) void (*mach_floppy_setup) (char *, int *) __initdata = NULL; -void (*mach_floppy_eject) (void) = NULL; #endif #ifdef CONFIG_HEARTBEAT void (*mach_heartbeat) (int) = NULL; @@ -514,11 +513,6 @@ mach_floppy_setup (str, ints); } -void floppy_eject(void) -{ - if (mach_floppy_eject) - mach_floppy_eject(); -} #endif /* for "kbd-reset" cmdline param */ diff -u --recursive --new-file v2.5.0/linux/arch/m68k/mac/config.c linux/arch/m68k/mac/config.c --- v2.5.0/linux/arch/m68k/mac/config.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/mac/config.c Wed Nov 28 13:22:25 2001 @@ -66,7 +66,7 @@ extern unsigned long mac_gettimeoffset (void); extern int mac_hwclk (int, struct hwclk_time *); extern int mac_set_clock_mmss (unsigned long); -extern int mac_get_irq_list(char *); +extern int show_mac_interrupts(struct seq_file *, void *); extern void iop_preinit(void); extern void iop_init(void); extern void via_init(void); @@ -241,7 +241,7 @@ disable_irq = mac_disable_irq; mach_get_model = mac_get_model; mach_default_handler = &mac_handlers; - mach_get_irq_list = mac_get_irq_list; + mach_get_irq_list = show_mac_interrupts; mach_gettimeoffset = mac_gettimeoffset; mach_gettod = mac_gettod; mach_hwclk = mac_hwclk; diff -u --recursive --new-file v2.5.0/linux/arch/m68k/mac/macints.c linux/arch/m68k/mac/macints.c --- v2.5.0/linux/arch/m68k/mac/macints.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/mac/macints.c Wed Nov 28 13:22:25 2001 @@ -120,6 +120,7 @@ #include #include /* for intr_count */ #include +#include #include #include @@ -576,9 +577,9 @@ * displayed for us as autovector irq 0. */ -int mac_get_irq_list (char *buf) +int show_mac_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; irq_node_t *node; char *base; @@ -618,25 +619,24 @@ case 8: base = "bbn"; break; } - len += sprintf(buf+len, "%4s %2d: %10u ", - base, i, kstat.irqs[0][i]); + seq_printf(p, "%4s %2d: %10u ", base, i, kstat.irqs[0][i]); do { if (node->flags & IRQ_FLG_FAST) { - len += sprintf(buf+len, "F "); + seq_puts(p, "F "); } else if (node->flags & IRQ_FLG_SLOW) { - len += sprintf(buf+len, "S "); + seq_puts(p, "S "); } else { - len += sprintf(buf+len, " "); + seq_puts(p, " "); } - len += sprintf(buf+len, "%s\n", node->devname); + seq_printf(p, "%s\n", node->devname); if ((node = node->next)) { - len += sprintf(buf+len, " "); + seq_puts(p, " "); } } while(node); } - return len; + return 0; } void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs) diff -u --recursive --new-file v2.5.0/linux/arch/m68k/mvme147/147ints.c linux/arch/m68k/mvme147/147ints.c --- v2.5.0/linux/arch/m68k/mvme147/147ints.c Tue May 11 09:57:14 1999 +++ linux/arch/m68k/mvme147/147ints.c Wed Nov 28 13:22:25 2001 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -112,17 +113,17 @@ } } -int mvme147_get_irq_list (char *buf) +int show_mvme147_interrupts (struct seq_file *p, void *v) { - int i, len = 0; + int i; for (i = 0; i < 256; i++) { if (irq_tab[i].count) - len += sprintf (buf+len, "Vec 0x%02x: %8d %s\n", + seq_printf(p, "Vec 0x%02x: %8d %s\n", i, irq_tab[i].count, irq_tab[i].devname ? irq_tab[i].devname : "free"); } - return len; + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/m68k/mvme147/config.c linux/arch/m68k/mvme147/config.c --- v2.5.0/linux/arch/m68k/mvme147/config.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/mvme147/config.c Wed Nov 28 13:22:25 2001 @@ -36,7 +36,7 @@ extern void mvme147_process_int (int level, struct pt_regs *regs); extern void mvme147_init_IRQ (void); extern void mvme147_free_irq (unsigned int, void *); -extern int mvme147_get_irq_list (char *); +extern int show_mvme147_interrupts (struct seq_file *, void *); extern void mvme147_enable_irq (unsigned int); extern void mvme147_disable_irq (unsigned int); static void mvme147_get_model(char *model); @@ -113,7 +113,7 @@ mach_reset = mvme147_reset; mach_free_irq = mvme147_free_irq; mach_process_int = mvme147_process_int; - mach_get_irq_list = mvme147_get_irq_list; + mach_get_irq_list = show_mvme147_interrupts; mach_request_irq = mvme147_request_irq; enable_irq = mvme147_enable_irq; disable_irq = mvme147_disable_irq; diff -u --recursive --new-file v2.5.0/linux/arch/m68k/mvme16x/16xints.c linux/arch/m68k/mvme16x/16xints.c --- v2.5.0/linux/arch/m68k/mvme16x/16xints.c Thu Dec 17 09:06:30 1998 +++ linux/arch/m68k/mvme16x/16xints.c Wed Nov 28 13:22:25 2001 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -114,17 +115,17 @@ } } -int mvme16x_get_irq_list (char *buf) +int show_mvme16x_interrupts (struct seq_file *p, void *v) { - int i, len = 0; + int i; for (i = 0; i < 192; i++) { if (irq_tab[i].count) - len += sprintf (buf+len, "Vec 0x%02x: %8d %s\n", + seq_printf(p, "Vec 0x%02x: %8d %s\n", i+64, irq_tab[i].count, irq_tab[i].devname ? irq_tab[i].devname : "free"); } - return len; + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/m68k/mvme16x/config.c linux/arch/m68k/mvme16x/config.c --- v2.5.0/linux/arch/m68k/mvme16x/config.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/mvme16x/config.c Wed Nov 28 13:22:25 2001 @@ -40,7 +40,7 @@ extern void mvme16x_process_int (int level, struct pt_regs *regs); extern void mvme16x_init_IRQ (void); extern void mvme16x_free_irq (unsigned int, void *); -extern int mvme16x_get_irq_list (char *); +extern int show_mvme16x_interrupts (struct seq_file *, void *); extern void mvme16x_enable_irq (unsigned int); extern void mvme16x_disable_irq (unsigned int); static void mvme16x_get_model(char *model); @@ -156,7 +156,7 @@ mach_reset = mvme16x_reset; mach_free_irq = mvme16x_free_irq; mach_process_int = mvme16x_process_int; - mach_get_irq_list = mvme16x_get_irq_list; + mach_get_irq_list = show_mvme16x_interrupts; mach_request_irq = mvme16x_request_irq; enable_irq = mvme16x_enable_irq; disable_irq = mvme16x_disable_irq; diff -u --recursive --new-file v2.5.0/linux/arch/m68k/mvme16x/rtc.c linux/arch/m68k/mvme16x/rtc.c --- v2.5.0/linux/arch/m68k/mvme16x/rtc.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/mvme16x/rtc.c Fri Nov 30 08:26:04 2001 @@ -36,7 +36,7 @@ static unsigned char days_in_mo[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -static char rtc_status = 0; +static atomic_t rtc_ready = ATOMIC_INIT(1); static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -130,18 +130,18 @@ static int rtc_open(struct inode *inode, struct file *file) { - if(rtc_status) + if( !atomic_dec_and_test(&rtc_ready) ) + { + atomic_inc( &rtc_ready ); return -EBUSY; + } - rtc_status = 1; return 0; } static int rtc_release(struct inode *inode, struct file *file) { - lock_kernel(); - rtc_status = 0; - unlock_kernel(); + atomic_inc( &rtc_ready ); return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/m68k/q40/config.c linux/arch/m68k/q40/config.c --- v2.5.0/linux/arch/m68k/q40/config.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/q40/config.c Sun Dec 16 12:23:05 2001 @@ -36,7 +36,6 @@ #include #include -extern void floppy_eject(void); extern void floppy_setup(char *str, int *ints); extern int q40kbd_translate(unsigned char scancode, unsigned char *keycode, @@ -45,7 +44,7 @@ extern void (*q40_sys_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */ extern void q40_init_IRQ (void); extern void q40_free_irq (unsigned int, void *); -extern int q40_get_irq_list (char *); +extern int show_q40_interrupts (struct seq_file *, void *); extern void q40_enable_irq (unsigned int); extern void q40_disable_irq (unsigned int); static void q40_get_model(char *model); @@ -236,7 +235,7 @@ mach_reset = q40_reset; mach_free_irq = q40_free_irq; mach_process_int = q40_process_int; - mach_get_irq_list = q40_get_irq_list; + mach_get_irq_list = show_q40_interrupts; mach_request_irq = q40_request_irq; enable_irq = q40_enable_irq; disable_irq = q40_disable_irq; diff -u --recursive --new-file v2.5.0/linux/arch/m68k/q40/q40ints.c linux/arch/m68k/q40/q40ints.c --- v2.5.0/linux/arch/m68k/q40/q40ints.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/q40/q40ints.c Wed Nov 28 13:22:25 2001 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -431,21 +432,20 @@ } } -int q40_get_irq_list (char *buf) +int show_q40_interrupts (struct seq_file *p, void *v) { - int i, len = 0; + int i; - for (i = 0; i <= Q40_IRQ_MAX; i++) - { + for (i = 0; i <= Q40_IRQ_MAX; i++) { if (irq_tab[i].count) - len += sprintf (buf+len, "%sIRQ %02d: %8d %s%s\n", + seq_printf(p, "%sIRQ %02d: %8d %s%s\n", (i<=15) ? "ISA-" : " " , i, irq_tab[i].count, irq_tab[i].devname[0] ? irq_tab[i].devname : "?", irq_tab[i].handler == q40_defhand ? " (now unassigned)" : ""); } - return len; + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/m68k/sun3/config.c linux/arch/m68k/sun3/config.c --- v2.5.0/linux/arch/m68k/sun3/config.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/sun3/config.c Wed Nov 28 13:22:25 2001 @@ -36,7 +36,7 @@ char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; extern unsigned long sun3_gettimeoffset(void); -extern int sun3_get_irq_list (char *); +extern int show_sun3_interrupts (char *); extern void sun3_sched_init(void (*handler)(int, void *, struct pt_regs *)); extern void sun3_get_model (char* model); extern void idprom_init (void); @@ -145,7 +145,7 @@ enable_irq = sun3_enable_irq; disable_irq = sun3_disable_irq; mach_process_int = sun3_process_int; - mach_get_irq_list = sun3_get_irq_list; + mach_get_irq_list = show_sun3_interrupts; mach_gettod = sun3_gettod; mach_reset = sun3_reboot; mach_gettimeoffset = sun3_gettimeoffset; diff -u --recursive --new-file v2.5.0/linux/arch/m68k/sun3/sun3ints.c linux/arch/m68k/sun3/sun3ints.c --- v2.5.0/linux/arch/m68k/sun3/sun3ints.c Mon Jun 11 19:15:27 2001 +++ linux/arch/m68k/sun3/sun3ints.c Wed Nov 28 13:22:25 2001 @@ -15,6 +15,7 @@ #include #include #include +#include extern void sun3_leds (unsigned char); @@ -62,7 +63,7 @@ *sun3_intreg |= (1< #include #include +#include #include #include @@ -141,27 +142,27 @@ */ static struct irqaction *irq_action[BAGET_IRQ_NR] = { NULL, }; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; struct irqaction * action; for (i = 0 ; i < BAGET_IRQ_NR ; i++) { action = irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %8d %c %s", + seq_printf(p, "%2d: %8d %c %s", i, kstat.irqs[0][i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, "\n"); + seq_putc(p, '\n'); } - return len; + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/mips/dec/irq.c linux/arch/mips/dec/irq.c --- v2.5.0/linux/arch/mips/dec/irq.c Sun Sep 9 10:43:01 2001 +++ linux/arch/mips/dec/irq.c Wed Nov 28 13:22:25 2001 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -92,27 +93,27 @@ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; - struct irqaction *action; + int i; + struct irqaction *action; - for (i = 0; i < 32; i++) { - action = irq_action[i]; - if (!action) - continue; - len += sprintf(buf + len, "%2d: %8d %c %s", - i, kstat.irqs[0][i], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action = action->next; action; action = action->next) { - len += sprintf(buf + len, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); + for (i = 0; i < 32; i++) { + action = irq_action[i]; + if (!action) + continue; + seq_printf(p, "%2d: %8d %c %s", + i, kstat.irqs[0][i], + (action->flags & SA_INTERRUPT) ? '+' : ' ', + action->name); + for (action = action->next; action; action = action->next) { + seq_printf(p, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + seq_putc(p, '\n'); } - len += sprintf(buf + len, "\n"); - } - return len; + return 0; } /* diff -u --recursive --new-file v2.5.0/linux/arch/mips/ite-boards/generic/irq.c linux/arch/mips/ite-boards/generic/irq.c --- v2.5.0/linux/arch/mips/ite-boards/generic/irq.c Sun Sep 9 10:43:01 2001 +++ linux/arch/mips/ite-boards/generic/irq.c Wed Nov 28 13:22:25 2001 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -217,34 +218,34 @@ }; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0, j; + int i, j; struct irqaction * action; - len += sprintf(buf+len, " "); + seq_printf(p, " "); for (j=0; jhandler ) continue; - len += sprintf(buf+len, "%3d: ", i); - len += sprintf(buf+len, "%10u ", kstat_irqs(i)); + seq_printf(p, "%3d: ", i); + seq_printf(p, "%10u ", kstat_irqs(i)); if ( irq_desc[i].handler ) - len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename ); + seq_printf(p, " %s ", irq_desc[i].handler->typename ); else - len += sprintf(buf+len, " None "); - len += sprintf(buf+len, " %s",action->name); + seq_puts(p, " None "); + seq_printf(p, " %s",action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ", %s", action->name); + seq_printf(p, ", %s", action->name); } - len += sprintf(buf+len, "\n"); + seq_putc(p, '\n'); } - len += sprintf(buf+len, "BAD: %10lu\n", spurious_count); - return len; + seq_printf(p, "BAD: %10lu\n", spurious_count); + return 0; } asmlinkage void do_IRQ(int irq, struct pt_regs *regs) diff -u --recursive --new-file v2.5.0/linux/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c --- v2.5.0/linux/arch/mips/kernel/irq.c Sun Sep 9 10:43:01 2001 +++ linux/arch/mips/kernel/irq.c Wed Nov 28 13:22:25 2001 @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -69,32 +70,31 @@ * Generic, controller-independent functions: */ -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { struct irqaction * action; - char *p = buf; int i; - p += sprintf(p, " "); + seq_puts(p, " "); for (i=0; i < 1 /*smp_num_cpus*/; i++) - p += sprintf(p, "CPU%d ", i); - *p++ = '\n'; + seq_printf(p, "CPU%d ", i); + seq_putc(p, '\n'); for (i = 0 ; i < NR_IRQS ; i++) { action = irq_desc[i].action; if (!action) continue; - p += sprintf(p, "%3d: ",i); - p += sprintf(p, "%10u ", kstat_irqs(i)); - p += sprintf(p, " %14s", irq_desc[i].handler->typename); - p += sprintf(p, " %s", action->name); + seq_printf(p, "%3d: ",i); + seq_printf(p, "%10u ", kstat_irqs(i)); + seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) - p += sprintf(p, ", %s", action->name); - *p++ = '\n'; + seq_printf(p, ", %s", action->name); + seq_putc(p, '\n'); } - p += sprintf(p, "ERR: %10lu\n", irq_err_count); - return p - buf; + seq_printf(p, "ERR: %10lu\n", irq_err_count); + return 0; } /* diff -u --recursive --new-file v2.5.0/linux/arch/mips/kernel/old-irq.c linux/arch/mips/kernel/old-irq.c --- v2.5.0/linux/arch/mips/kernel/old-irq.c Sun Sep 9 10:43:01 2001 +++ linux/arch/mips/kernel/old-irq.c Wed Nov 28 13:22:25 2001 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -123,27 +124,27 @@ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; struct irqaction * action; for (i = 0 ; i < 32 ; i++) { action = irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %8d %c %s", + seq_printf(p, "%2d: %8d %c %s", i, kstat.irqs[0][i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, "\n"); + seq_putc(p, '\n'); } - return len; + return 0; } static inline void i8259_mask_and_ack_irq(int irq) diff -u --recursive --new-file v2.5.0/linux/arch/mips/mips-boards/atlas/atlas_int.c linux/arch/mips/mips-boards/atlas/atlas_int.c --- v2.5.0/linux/arch/mips/mips-boards/atlas/atlas_int.c Sun Sep 9 10:43:02 2001 +++ linux/arch/mips/mips-boards/atlas/atlas_int.c Wed Nov 28 13:22:25 2001 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -93,9 +94,9 @@ NULL }; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; int num = 0; struct irqaction *action; @@ -103,18 +104,18 @@ action = irq_desc[i].action; if (!action) continue; - len += sprintf(buf+len, "%2d: %8d %c %s", + seq_printf(p, "%2d: %8d %c %s", num, kstat.irqs[0][num], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, " [hw0]\n"); + seq_printf(p, " [hw0]\n"); } - return len; + return 0; } int request_irq(unsigned int irq, diff -u --recursive --new-file v2.5.0/linux/arch/mips/philips/nino/irq.c linux/arch/mips/philips/nino/irq.c --- v2.5.0/linux/arch/mips/philips/nino/irq.c Sun Sep 9 10:43:02 2001 +++ linux/arch/mips/philips/nino/irq.c Wed Nov 28 13:22:25 2001 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -114,27 +115,27 @@ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; struct irqaction *action; for (i = 0; i < NR_IRQS; i++) { action = irq_action[i]; if (!action) continue; - len += sprintf(buf + len, "%2d: %8d %c %s", + seq_printf(p, "%2d: %8d %c %s", i, kstat.irqs[0][i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action = action->next; action; action = action->next) { - len += sprintf(buf + len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf + len, "\n"); + seq_putc(p, '\n'); } - return len; + return 0; } atomic_t __mips_bh_counter; diff -u --recursive --new-file v2.5.0/linux/arch/mips64/mips-boards/atlas/atlas_int.c linux/arch/mips64/mips-boards/atlas/atlas_int.c --- v2.5.0/linux/arch/mips64/mips-boards/atlas/atlas_int.c Sun Sep 9 10:43:02 2001 +++ linux/arch/mips64/mips-boards/atlas/atlas_int.c Wed Nov 28 13:22:25 2001 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -89,9 +90,9 @@ NULL }; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; int num = 0; struct irqaction *action; @@ -99,18 +100,18 @@ action = irq_desc[i].action; if (!action) continue; - len += sprintf(buf+len, "%2d: %8d %c %s", + seq_printf(p, "%2d: %8d %c %s", num, kstat.irqs[0][num], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, " [hw0]\n"); + seq_puts(p, " [hw0]\n"); } - return len; + return 0; } int request_irq(unsigned int irq, diff -u --recursive --new-file v2.5.0/linux/arch/mips64/mips-boards/malta/malta_int.c linux/arch/mips64/mips-boards/malta/malta_int.c --- v2.5.0/linux/arch/mips64/mips-boards/malta/malta_int.c Sun Sep 9 10:43:02 2001 +++ linux/arch/mips64/mips-boards/malta/malta_int.c Wed Nov 28 13:22:25 2001 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -119,9 +120,9 @@ } -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; int num = 0; struct irqaction *action; @@ -129,33 +130,33 @@ action = irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %8d %c %s", + seq_printf(p, "%2d: %8d %c %s", num, kstat.irqs[0][num], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, " [on-chip]\n"); + seq_puts(p, " [on-chip]\n"); } for (i = 0; i < MALTAINT_END; i++, num++) { action = hw0_irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %8d %c %s", + seq_printf(p, "%2d: %8d %c %s", num, kstat.irqs[0][num], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, " [hw0]\n"); + seq_puts(p, " [hw0]\n"); } - return len; + return 0; } int request_irq(unsigned int irq, diff -u --recursive --new-file v2.5.0/linux/arch/mips64/sgi-ip22/ip22-int.c linux/arch/mips64/sgi-ip22/ip22-int.c --- v2.5.0/linux/arch/mips64/sgi-ip22/ip22-int.c Sun Sep 9 10:43:02 2001 +++ linux/arch/mips64/sgi-ip22/ip22-int.c Wed Nov 28 13:22:26 2001 @@ -8,6 +8,7 @@ */ #include #include +#include #include #include @@ -231,9 +232,9 @@ NULL, NULL, NULL, NULL }; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; int num = 0; struct irqaction * action; @@ -241,33 +242,33 @@ action = irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %8d %c %s", + seq_printf(p, "%2d: %8d %c %s", num, kstat.irqs[0][num], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, " [on-chip]\n"); + seq_puts(p, " [on-chip]\n"); } for (i = 0 ; i < 24 ; i++, num++) { action = local_irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %8d %c %s", + seq_printf(p, "%2d: %8d %c %s", num, kstat.irqs[0][num], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, " [local]\n"); + seq_puts(p, " [local]\n"); } - return len; + return 0; } /* diff -u --recursive --new-file v2.5.0/linux/arch/mips64/sgi-ip27/ip27-irq.c linux/arch/mips64/sgi-ip27/ip27-irq.c --- v2.5.0/linux/arch/mips64/sgi-ip27/ip27-irq.c Sun Sep 9 10:43:02 2001 +++ linux/arch/mips64/sgi-ip27/ip27-irq.c Wed Nov 28 13:22:26 2001 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -136,27 +137,27 @@ /* This is stupid for an Origin which can have thousands of IRQs ... */ static struct irqaction *irq_action[NR_IRQS]; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; struct irqaction * action; for (i = 0 ; i < NR_IRQS ; i++) { action = irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.irqs[0][i], + seq_printf(p, "%2d: %8d %c %s", i, kstat.irqs[0][i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, "\n"); + seq_putc(p, '\n'); } - return len; + return 0; } /* diff -u --recursive --new-file v2.5.0/linux/arch/mips64/sgi-ip27/ip27-rtc.c linux/arch/mips64/sgi-ip27/ip27-rtc.c --- v2.5.0/linux/arch/mips64/sgi-ip27/ip27-rtc.c Tue Nov 28 21:42:04 2000 +++ linux/arch/mips64/sgi-ip27/ip27-rtc.c Fri Nov 30 08:26:04 2001 @@ -53,14 +53,7 @@ static void get_rtc_time(struct rtc_time *rtc_tm); -/* - * Bits in rtc_status. (6 bits of room for future expansion) - */ - -#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ -#define RTC_TIMER_ON 0x02 /* missed irq timer active */ - -static unsigned char rtc_status; /* bitmapped status byte. */ +static atomic_t rtc_ready = ATOMIC_INIT(1); static unsigned long rtc_freq; /* Current periodic IRQ rate */ static struct m48t35_rtc *rtc; @@ -166,23 +159,17 @@ static int rtc_open(struct inode *inode, struct file *file) { - if(rtc_status & RTC_IS_OPEN) + if( atomic_dec_and_test( &rtc_ready ) ) + { + atomic_inc( &rtc_ready ); return -EBUSY; - - rtc_status |= RTC_IS_OPEN; + } return 0; } static int rtc_release(struct inode *inode, struct file *file) { - /* - * Turn off all interrupts once the device is no longer - * in use, and clear the data. - */ - - lock_kernel(); - rtc_status &= ~RTC_IS_OPEN; - unlock_kernel(); + atomic_inc( &rtc_ready ); return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/parisc/kernel/irq.c linux/arch/parisc/kernel/irq.c --- v2.5.0/linux/arch/parisc/kernel/irq.c Fri Feb 9 11:29:44 2001 +++ linux/arch/parisc/kernel/irq.c Wed Nov 28 13:22:26 2001 @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -160,19 +161,18 @@ BUG(); } -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { #ifdef CONFIG_PROC_FS - char *p = buf; int i, j; int regnr, irq_no; struct irq_region *region; struct irqaction *action, *mainaction; - p += sprintf(p, " "); + seq_puts(p, " "); for (j=0; jdata.name ? region->data.name : "N/A"); - p += sprintf(p, " %s", action->name); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) - p += sprintf(p, ", %s", action->name); - *p++ = '\n'; + seq_printf(p, ", %s", action->name); + seq_putc(p, '\n'); } } - p += sprintf(p, "\n"); + seq_putc(p, '\n'); #if CONFIG_SMP - p += sprintf(p, "LOC: "); + seq_puts(p, "LOC: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", apic_timer_irqs[cpu_logical_map(j)]); - p += sprintf(p, "\n"); + seq_putc(p, '\n'); #endif - - return p - buf; - -#else /* CONFIG_PROC_FS */ - - return 0; - #endif /* CONFIG_PROC_FS */ + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/ppc/amiga/amiints.c linux/arch/ppc/amiga/amiints.c --- v2.5.0/linux/arch/ppc/amiga/amiints.c Mon May 21 17:04:46 2001 +++ linux/arch/ppc/amiga/amiints.c Wed Nov 28 13:22:26 2001 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -61,7 +62,7 @@ unsigned long flags, const char *devname, void *dev_id); extern void cia_free_irq(unsigned int irq, void *dev_id); extern void cia_init_IRQ(struct ciabase *base); -extern int cia_get_irq_list(struct ciabase *base, char *buf); +extern int cia_get_irq_list(struct ciabase *base, struct seq_file *p); /* irq node variables for amiga interrupt sources */ static irq_node_t *ami_irq_list[AMI_STD_IRQS]; @@ -480,28 +481,28 @@ }; #endif -int amiga_get_irq_list(char *buf) +int show_amiga_intreeupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; irq_node_t *node; for (i = 0; i < AMI_STD_IRQS; i++) { if (!(node = ami_irq_list[i])) continue; - len += sprintf(buf+len, "ami %2d: %10u ", i, + seq_printf(p, "ami %2d: %10u ", i, kstat.irqs[0][SYS_IRQS + i]); do { if (node->flags & SA_INTERRUPT) - len += sprintf(buf+len, "F "); + seq_puts(p, "F "); else - len += sprintf(buf+len, " "); - len += sprintf(buf+len, "%s\n", node->devname); + seq_puts(p, " "); + seq_printf(p, "%s\n", node->devname); if ((node = node->next)) - len += sprintf(buf+len, " "); + seq_puts(p, " "); } while (node); } - len += cia_get_irq_list(&ciaa_base, buf+len); - len += cia_get_irq_list(&ciab_base, buf+len); + cia_get_irq_list(&ciaa_base, p); + cia_get_irq_list(&ciab_base, p); return len; } diff -u --recursive --new-file v2.5.0/linux/arch/ppc/amiga/cia.c linux/arch/ppc/amiga/cia.c --- v2.5.0/linux/arch/ppc/amiga/cia.c Mon May 21 17:04:46 2001 +++ linux/arch/ppc/amiga/cia.c Wed Nov 28 13:22:26 2001 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -222,16 +223,16 @@ custom.intena = IF_SETCLR | base->int_mask; } -int cia_get_irq_list(struct ciabase *base, char *buf) +int cia_get_irq_list(struct ciabase *base, struct seq_file *p) { - int i, j, len = 0; + int i, j; j = base->cia_irq; for (i = 0; i < CIA_IRQS; i++) { - len += sprintf(buf+len, "cia %2d: %10d ", j + i, + seq_printf(p, "cia %2d: %10d ", j + i, kstat.irqs[0][SYS_IRQS + j + i]); - len += sprintf(buf+len, " "); - len += sprintf(buf+len, "%s\n", base->irq_list[i].devname); + seq_puts(p, " "); + seq_printf(p, "%s\n", base->irq_list[i].devname); } - return len; + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/ppc/amiga/config.c linux/arch/ppc/amiga/config.c --- v2.5.0/linux/arch/ppc/amiga/config.c Thu Oct 11 09:04:57 2001 +++ linux/arch/ppc/amiga/config.c Wed Nov 28 13:22:26 2001 @@ -28,6 +28,7 @@ #ifdef CONFIG_ZORRO #include #endif +#include #include #include @@ -91,7 +92,7 @@ extern void amiga_disable_irq (unsigned int); static void amiga_get_model(char *model); static int amiga_get_hardware_list(char *buffer); -extern int amiga_get_irq_list (char *); +extern int show_amiga_interrupts (struct seq_file *, void *); /* amiga specific timer functions */ static unsigned long amiga_gettimeoffset (void); static void a3000_gettod (int *, int *, int *, int *, int *, int *); @@ -422,7 +423,7 @@ #endif mach_get_model = amiga_get_model; mach_get_hardware_list = amiga_get_hardware_list; - mach_get_irq_list = amiga_get_irq_list; + mach_get_irq_list = show_amiga_interrupts; mach_gettimeoffset = amiga_gettimeoffset; if (AMIGAHW_PRESENT(A3000_CLK)){ mach_gettod = a3000_gettod; diff -u --recursive --new-file v2.5.0/linux/arch/ppc/amiga/ints.c linux/arch/ppc/amiga/ints.c --- v2.5.0/linux/arch/ppc/amiga/ints.c Mon May 21 17:04:46 2001 +++ linux/arch/ppc/amiga/ints.c Wed Nov 28 13:22:26 2001 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -143,20 +144,20 @@ } } -int m68k_get_irq_list(char *buf) +int m68k_get_irq_list(struct seq_file *p, void *v) { - int i, len = 0; + int i; /* autovector interrupts */ if (mach_default_handler) { for (i = 0; i < SYS_IRQS; i++) { - len += sprintf(buf+len, "auto %2d: %10u ", i, + seq_printf(p, "auto %2d: %10u ", i, i ? kstat.irqs[0][i] : num_spurious); - len += sprintf(buf+len, " "); - len += sprintf(buf+len, "%s\n", irq_list[i].devname); + seq_puts(p, " "); + seq_printf(p, "%s\n", irq_list[i].devname); } } - len += mach_get_irq_list(buf+len); - return len; + mach_get_irq_list(p, v); + return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/ppc/kernel/apus_setup.c linux/arch/ppc/kernel/apus_setup.c --- v2.5.0/linux/arch/ppc/kernel/apus_setup.c Fri Nov 16 10:10:08 2001 +++ linux/arch/ppc/kernel/apus_setup.c Sun Dec 16 12:23:05 2001 @@ -95,7 +95,7 @@ void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; void (*mach_get_model) (char *model) = NULL; int (*mach_get_hardware_list) (char *buffer) = NULL; -int (*mach_get_irq_list) (char *) = NULL; +int (*mach_get_irq_list) (struct seq_file *, void *) = NULL; void (*mach_process_int) (int, struct pt_regs *) = NULL; /* machine dependent timer functions */ unsigned long (*mach_gettimeoffset) (void); @@ -106,7 +106,6 @@ long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ #if defined(CONFIG_AMIGA_FLOPPY) void (*mach_floppy_setup) (char *, int *) __initdata = NULL; -void (*mach_floppy_eject) (void) = NULL; #endif #ifdef CONFIG_HEARTBEAT void (*mach_heartbeat) (int) = NULL; @@ -404,12 +403,6 @@ if (mach_floppy_setup) mach_floppy_setup (str, ints); } - -void floppy_eject(void) -{ - if (mach_floppy_eject) - mach_floppy_eject(); -} #endif /*********************************************************** MEMORY */ @@ -671,12 +664,12 @@ return irq; } -int apus_get_irq_list(char *buf) +int show_apus_interrupts(struct seq_file *p, void *v) { #ifdef CONFIG_APUS - extern int amiga_get_irq_list(char *buf); + extern int show_amiga_interrupts(struct seq_file *p, void *v) - return amiga_get_irq_list (buf); + return show_amiga_interrupts(p, v); #else return 0; #endif diff -u --recursive --new-file v2.5.0/linux/arch/ppc/kernel/i8259.c linux/arch/ppc/kernel/i8259.c --- v2.5.0/linux/arch/ppc/kernel/i8259.c Mon May 21 17:04:47 2001 +++ linux/arch/ppc/kernel/i8259.c Mon Dec 10 13:52:53 2001 @@ -13,7 +13,7 @@ #define cached_A1 (cached_8259[0]) #define cached_21 (cached_8259[1]) -spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED; int i8259_pic_irq_offset; diff -u --recursive --new-file v2.5.0/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c --- v2.5.0/linux/arch/ppc/kernel/irq.c Tue Aug 28 06:58:33 2001 +++ linux/arch/ppc/kernel/irq.c Wed Nov 28 13:22:26 2001 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -371,58 +372,58 @@ spin_unlock_irqrestore(&desc->lock, flags); } -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { #ifdef CONFIG_APUS - return apus_get_irq_list (buf); + return show_apus_interrupts(p, v); #else - int i, len = 0, j; + int i, j; struct irqaction * action; - len += sprintf(buf+len, " "); + seq_puts(p, " "); for (j=0; jhandler ) continue; - len += sprintf(buf+len, "%3d: ", i); + seq_printf(p, "%3d: ", i); #ifdef CONFIG_SMP for (j = 0; j < smp_num_cpus; j++) - len += sprintf(buf+len, "%10u ", + seq_printf(p, "%10u ", kstat.irqs[cpu_logical_map(j)][i]); #else - len += sprintf(buf+len, "%10u ", kstat_irqs(i)); + seq_printf(p, "%10u ", kstat_irqs(i)); #endif /* CONFIG_SMP */ if ( irq_desc[i].handler ) - len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename ); + seq_printf(p, " %s ", irq_desc[i].handler->typename ); else - len += sprintf(buf+len, " None "); - len += sprintf(buf+len, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); - len += sprintf(buf+len, " %s",action->name); + seq_puts(p, " None "); + seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); + seq_printf(p, " %s",action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ", %s", action->name); + seq_printf(p, ", %s", action->name); } - len += sprintf(buf+len, "\n"); + seq_putc(p, '\n'); } #ifdef CONFIG_TAU_INT if (tau_initialized){ - len += sprintf(buf+len, "TAU: "); + seq_puts(p, "TAU: "); for (j = 0; j < smp_num_cpus; j++) - len += sprintf(buf+len, "%10u ", + seq_printf(p, "%10u ", tau_interrupts(j)); - len += sprintf(buf+len, " PowerPC Thermal Assist (cpu temp)\n"); + seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n"); } #endif #ifdef CONFIG_SMP /* should this be per processor send/receive? */ - len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n", + seq_printf(p, "IPI (recv/sent): %10u/%u\n", atomic_read(&ipi_recv), atomic_read(&ipi_sent)); #endif - len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts); - return len; + seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); + return 0; #endif /* CONFIG_APUS */ } diff -u --recursive --new-file v2.5.0/linux/arch/ppc/kernel/pmac_pic.c linux/arch/ppc/kernel/pmac_pic.c --- v2.5.0/linux/arch/ppc/kernel/pmac_pic.c Sat Sep 8 12:38:42 2001 +++ linux/arch/ppc/kernel/pmac_pic.c Mon Dec 10 13:52:53 2001 @@ -36,7 +36,7 @@ static int max_irqs; static int max_real_irqs; -spinlock_t pmac_pic_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t pmac_pic_lock = SPIN_LOCK_UNLOCKED; #define GATWICK_IRQ_POOL_SIZE 10 diff -u --recursive --new-file v2.5.0/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c --- v2.5.0/linux/arch/ppc/kernel/prom.c Sat Sep 8 12:38:42 2001 +++ linux/arch/ppc/kernel/prom.c Mon Dec 10 13:52:53 2001 @@ -1928,7 +1928,7 @@ } #endif -spinlock_t rtas_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t rtas_lock = SPIN_LOCK_UNLOCKED; /* this can be called after setup -- Cort */ int __openfirmware diff -u --recursive --new-file v2.5.0/linux/arch/s390/kernel/irq.c linux/arch/s390/kernel/irq.c --- v2.5.0/linux/arch/s390/kernel/irq.c Wed Jul 25 14:12:01 2001 +++ linux/arch/s390/kernel/irq.c Wed Nov 28 13:22:26 2001 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -59,22 +60,19 @@ BUILD_SMP_INTERRUPT(spurious_interrupt) #endif -#if 0 -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; - char *p = buf; - p += sprintf(p, " "); + seq_puts(p, " "); for (j=0; jirq_desc.handler->typename); - p += sprintf(p, " %s", action->name); + seq_printf(p, " %14s", ioinfo[i]->irq_desc.handler->typename); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) { - p += sprintf(p, ", %s", action->name); + seq_printf(p, ", %s", action->name); } /* endfor */ - *p++ = '\n'; + seq_putc(p, '\n'); } /* endfor */ - p += sprintf(p, "NMI: %10u\n", nmi_counter); + seq_printf(p, "NMI: %10u\n", nmi_counter); #ifdef CONFIG_SMP - p += sprintf(p, "IPI: %10u\n", atomic_read(&ipi_count)); + seq_printf(p, "IPI: %10u\n", atomic_read(&ipi_count)); #endif - - return p - buf; + return 0; } -#endif /* * Global interrupt locks for SMP. Allow interrupts to come in on any diff -u --recursive --new-file v2.5.0/linux/arch/s390x/kernel/irq.c linux/arch/s390x/kernel/irq.c --- v2.5.0/linux/arch/s390x/kernel/irq.c Wed Jul 25 14:12:01 2001 +++ linux/arch/s390x/kernel/irq.c Wed Nov 28 13:22:26 2001 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -59,19 +60,17 @@ BUILD_SMP_INTERRUPT(spurious_interrupt) #endif -#if 0 -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; - char *p = buf; - p += sprintf(p, " "); + seq_puts(p, " "); for (j=0; jirq_desc.handler->typename); - p += sprintf(p, " %s", action->name); + seq_printf(p, " %14s", ioinfo[i]->irq_desc.handler->typename); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) { - p += sprintf(p, ", %s", action->name); + seq_printf(p, ", %s", action->name); } /* endfor */ - *p++ = '\n'; + seq_putc(p, '\n'); } /* endfor */ - p += sprintf(p, "NMI: %10u\n", nmi_counter); + seq_printf(p, "NMI: %10u\n", nmi_counter); #ifdef CONFIG_SMP - p += sprintf(p, "IPI: %10u\n", atomic_read(&ipi_count)); + seq_printf(p, "IPI: %10u\n", atomic_read(&ipi_count)); #endif - return p - buf; + return 0; } -#endif /* * Global interrupt locks for SMP. Allow interrupts to come in on any diff -u --recursive --new-file v2.5.0/linux/arch/sh/config.in linux/arch/sh/config.in --- v2.5.0/linux/arch/sh/config.in Mon Oct 15 13:36:48 2001 +++ linux/arch/sh/config.in Tue Dec 11 10:10:18 2001 @@ -189,7 +189,7 @@ if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then define_bool CONFIG_PCI_DIRECT y fi - define_bool CONFIG_SH_PCIDMA_NONCOHERENT n + bool 'Cache and PCI noncoherent' CONFIG_SH_PCIDMA_NONCOHERENT n fi source drivers/pci/Config.in diff -u --recursive --new-file v2.5.0/linux/arch/sh/kernel/io_7751se.c linux/arch/sh/kernel/io_7751se.c --- v2.5.0/linux/arch/sh/kernel/io_7751se.c Sat Sep 8 12:29:09 2001 +++ linux/arch/sh/kernel/io_7751se.c Tue Dec 11 10:10:18 2001 @@ -17,7 +17,7 @@ #include #include -#include +#include #include #if 0 @@ -70,7 +70,7 @@ else return (volatile __u16 *) (PA_SUPERIO + (port << 1)); #endif - maybebadio(name,port); + maybebadio(name,(unsigned long)port); return (volatile __u16*)port; } @@ -276,6 +276,7 @@ /* ISA page descriptor. */ static __u32 sh_isa_memmap[256]; +#if 0 static int sh_isa_mmap(__u32 start, __u32 length, __u32 offset) { @@ -286,12 +287,11 @@ idx = start >> 12; sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); -#if 0 printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", start, length, offset, idx, sh_isa_memmap[idx]); -#endif return 0; } +#endif unsigned long sh7751se_isa_port2addr(unsigned long offset) diff -u --recursive --new-file v2.5.0/linux/arch/sh/kernel/irq.c linux/arch/sh/kernel/irq.c --- v2.5.0/linux/arch/sh/kernel/irq.c Sat Sep 8 12:29:09 2001 +++ linux/arch/sh/kernel/irq.c Wed Nov 28 13:22:26 2001 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -84,31 +85,30 @@ */ #if defined(CONFIG_PROC_FS) -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; - char *p = buf; - p += sprintf(p, " "); + seq_puts(p, " "); for (j=0; jtypename); - p += sprintf(p, " %s", action->name); + seq_printf(p, "%3d: ",i); + seq_printf(p, "%10u ", kstat_irqs(i)); + seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) - p += sprintf(p, ", %s", action->name); - *p++ = '\n'; + seq_printf(p, ", %s", action->name); + seq_putc(p, '\n'); } - return p - buf; + return 0; } #endif diff -u --recursive --new-file v2.5.0/linux/arch/sh/kernel/pci-7751se.c linux/arch/sh/kernel/pci-7751se.c --- v2.5.0/linux/arch/sh/kernel/pci-7751se.c Sat Sep 8 12:29:09 2001 +++ linux/arch/sh/kernel/pci-7751se.c Tue Dec 11 10:10:18 2001 @@ -37,7 +37,6 @@ */ int __init pcibios_init_platform(void) { - unsigned long data; unsigned long bcr1, wcr1, wcr2, wcr3, mcr; unsigned short bcr2; diff -u --recursive --new-file v2.5.0/linux/arch/sh/kernel/traps.c linux/arch/sh/kernel/traps.c --- v2.5.0/linux/arch/sh/kernel/traps.c Sat Sep 8 12:29:09 2001 +++ linux/arch/sh/kernel/traps.c Tue Dec 11 10:10:18 2001 @@ -560,3 +560,8 @@ } } } + +void show_trace_task(struct task_struct *tsk) +{ + printk("Backtrace not yet implemented for SH.\n"); +} diff -u --recursive --new-file v2.5.0/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c --- v2.5.0/linux/arch/sparc/kernel/irq.c Thu Jul 19 18:11:13 2001 +++ linux/arch/sparc/kernel/irq.c Wed Nov 28 13:22:26 2001 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -97,42 +98,42 @@ NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL }; -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; struct irqaction * action; #ifdef CONFIG_SMP int j; #endif if (sparc_cpu_model == sun4d) { - extern int sun4d_get_irq_list(char *); + extern int show_sun4d_interrupts(struct seq_file *, void *); - return sun4d_get_irq_list(buf); + return show_sun4d_interrupts(p, v); } for (i = 0 ; i < (NR_IRQS+1) ; i++) { action = *(i + irq_action); if (!action) continue; - len += sprintf(buf+len, "%3d: ", i); + seq_printf(p, "%3d: ", i); #ifndef CONFIG_SMP - len += sprintf(buf+len, "%10u ", kstat_irqs(i)); + seq_printf(p, "%10u ", kstat_irqs(i)); #else for (j = 0; j < smp_num_cpus; j++) - len += sprintf(buf+len, "%10u ", + seq_printf(p, "%10u ", kstat.irqs[cpu_logical_map(j)][i]); #endif - len += sprintf(buf+len, " %c %s", + seq_printf(p, " %c %s", (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - len += sprintf(buf+len, "\n"); + seq_putc(p, '\n'); } - return len; + return 0; } void free_irq(unsigned int irq, void *dev_id) diff -u --recursive --new-file v2.5.0/linux/arch/sparc/kernel/sun4d_irq.c linux/arch/sparc/kernel/sun4d_irq.c --- v2.5.0/linux/arch/sparc/kernel/sun4d_irq.c Thu Jul 19 18:11:13 2001 +++ linux/arch/sparc/kernel/sun4d_irq.c Wed Nov 28 13:22:26 2001 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -72,9 +73,9 @@ spinlock_t sun4d_imsk_lock = SPIN_LOCK_UNLOCKED; #endif -int sun4d_get_irq_list(char *buf) +int show_sun4d_interrupts(struct seq_file *p, void *v) { - int i, j = 0, k = 0, len = 0, sbusl; + int i, j = 0, k = 0, sbusl; struct irqaction * action; #ifdef CONFIG_SMP int x; @@ -94,21 +95,21 @@ } continue; } -found_it: len += sprintf(buf+len, "%3d: ", i); +found_it: seq_printf(p, "%3d: ", i); #ifndef CONFIG_SMP - len += sprintf(buf+len, "%10u ", kstat_irqs(i)); + seq_printf(p, "%10u ", kstat_irqs(i)); #else for (x = 0; x < smp_num_cpus; x++) - len += sprintf(buf+len, "%10u ", + seq_printf(p, "%10u ", kstat.irqs[cpu_logical_map(x)][i]); #endif - len += sprintf(buf+len, "%c %s", + seq_printf(p, "%c %s", (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); action = action->next; for (;;) { for (; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", + seq_printf(p, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } @@ -123,9 +124,9 @@ action = sbus_actions [(j << 5) + (sbusl << 2)].action; } } - len += sprintf(buf+len, "\n"); + seq_putc(p, '\n'); } - return len; + return 0; } void sun4d_free_irq(unsigned int irq, void *dev_id) diff -u --recursive --new-file v2.5.0/linux/arch/sparc64/kernel/iommu_common.c linux/arch/sparc64/kernel/iommu_common.c --- v2.5.0/linux/arch/sparc64/kernel/iommu_common.c Fri Oct 12 15:35:53 2001 +++ linux/arch/sparc64/kernel/iommu_common.c Sun Dec 16 12:20:20 2001 @@ -1,4 +1,4 @@ -/* $Id: iommu_common.c,v 1.6 2001/10/09 02:24:33 davem Exp $ +/* $Id: iommu_common.c,v 1.8 2001/12/11 11:13:06 davem Exp $ * iommu_common.c: UltraSparc SBUS/PCI common iommu code. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -66,7 +66,9 @@ daddr = dma_sg->dma_address; sglen = sg->length; - sgaddr = (unsigned long) sg->address; + sgaddr = (unsigned long) (sg->address ? + sg->address : + page_address(sg->page) + sg->offset); while (dlen > 0) { unsigned long paddr; @@ -116,7 +118,9 @@ sg++; if (--nents <= 0) break; - sgaddr = (unsigned long) sg->address; + sgaddr = (unsigned long) (sg->address ? + sg->address : + page_address(sg->page) + sg->offset); sglen = sg->length; } if (dlen < 0) { @@ -197,14 +201,21 @@ unsigned long prev; u32 dent_addr, dent_len; - prev = (unsigned long) sg->address; + prev = (unsigned long) (sg->address ? + sg->address : + page_address(sg->page) + sg->offset); prev += (unsigned long) (dent_len = sg->length); - dent_addr = (u32) ((unsigned long)sg->address & (IO_PAGE_SIZE - 1UL)); + dent_addr = (u32) ((unsigned long)(sg->address ? + sg->address : + page_address(sg->page) + sg->offset) + & (IO_PAGE_SIZE - 1UL)); while (--nents) { unsigned long addr; sg++; - addr = (unsigned long) sg->address; + addr = (unsigned long) (sg->address ? + sg->address : + page_address(sg->page) + sg->offset); if (! VCONTIG(prev, addr)) { dma_sg->dma_address = dent_addr; dma_sg->dma_length = dent_len; diff -u --recursive --new-file v2.5.0/linux/arch/sparc64/kernel/iommu_common.h linux/arch/sparc64/kernel/iommu_common.h --- v2.5.0/linux/arch/sparc64/kernel/iommu_common.h Fri Oct 12 15:35:53 2001 +++ linux/arch/sparc64/kernel/iommu_common.h Sun Dec 16 12:20:20 2001 @@ -1,4 +1,4 @@ -/* $Id: iommu_common.h,v 1.4 2001/10/09 02:24:33 davem Exp $ +/* $Id: iommu_common.h,v 1.5 2001/12/11 09:41:01 davem Exp $ * iommu_common.h: UltraSparc SBUS/PCI common iommu declarations. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -6,8 +6,9 @@ #include #include +#include +#include -#include #include #include diff -u --recursive --new-file v2.5.0/linux/arch/sparc64/kernel/irq.c linux/arch/sparc64/kernel/irq.c --- v2.5.0/linux/arch/sparc64/kernel/irq.c Tue Nov 13 09:16:05 2001 +++ linux/arch/sparc64/kernel/irq.c Wed Nov 28 13:22:26 2001 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -104,9 +105,9 @@ #define put_smpaff_in_irqaction(action, smpaff) (action)->mask = (smpaff) #define get_smpaff_in_irqaction(action) ((action)->mask) -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { - int i, len = 0; + int i; struct irqaction *action; #ifdef CONFIG_SMP int j; @@ -115,23 +116,23 @@ for(i = 0; i < (NR_IRQS + 1); i++) { if(!(action = *(i + irq_action))) continue; - len += sprintf(buf + len, "%3d: ", i); + seq_print(p, "%3d: ", i); #ifndef CONFIG_SMP - len += sprintf(buf + len, "%10u ", kstat_irqs(i)); + seq_print(p, "%10u ", kstat_irqs(i)); #else for (j = 0; j < smp_num_cpus; j++) - len += sprintf(buf + len, "%10u ", + seq_print(p, "%10u ", kstat.irqs[cpu_logical_map(j)][i]); #endif - len += sprintf(buf + len, " %s:%lx", action->name, \ + seq_print(p, " %s:%lx", action->name, get_ino_in_irqaction(action)); for(action = action->next; action; action = action->next) { - len += sprintf(buf+len, ", %s:%lx", action->name, \ + seq_print(p, ", %s:%lx", action->name, get_ino_in_irqaction(action)); } - len += sprintf(buf + len, "\n"); + seq_putc(p, '\n'); } - return len; + return 0; } /* Now these are always passed a true fully specified sun4u INO. */ diff -u --recursive --new-file v2.5.0/linux/arch/sparc64/solaris/socksys.c linux/arch/sparc64/solaris/socksys.c --- v2.5.0/linux/arch/sparc64/solaris/socksys.c Sun Feb 18 19:49:54 2001 +++ linux/arch/sparc64/solaris/socksys.c Fri Nov 30 08:26:04 2001 @@ -118,7 +118,6 @@ struct T_primsg *it; /* XXX: check this */ - lock_kernel(); sock = (struct sol_socket_struct *)filp->private_data; SOLDD(("sock release %016lx(%016lx)\n", sock, filp)); it = sock->pfirst; @@ -132,7 +131,6 @@ filp->private_data = NULL; SOLDD(("socksys_release %016lx\n", sock)); mykfree((char*)sock); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/arch/sparc64/solaris/timod.c linux/arch/sparc64/solaris/timod.c --- v2.5.0/linux/arch/sparc64/solaris/timod.c Thu Sep 20 14:11:57 2001 +++ linux/arch/sparc64/solaris/timod.c Mon Dec 10 13:52:53 2001 @@ -33,7 +33,7 @@ u32 arg); asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg); -spinlock_t timod_pagelock = SPIN_LOCK_UNLOCKED; +static spinlock_t timod_pagelock = SPIN_LOCK_UNLOCKED; static char * page = NULL ; #ifndef DEBUG_SOLARIS_KMALLOC diff -u --recursive --new-file v2.5.0/linux/drivers/acorn/block/fd1772.c linux/drivers/acorn/block/fd1772.c --- v2.5.0/linux/drivers/acorn/block/fd1772.c Sun Aug 12 10:38:48 2001 +++ linux/drivers/acorn/block/fd1772.c Sun Dec 16 12:23:05 2001 @@ -1620,7 +1620,3 @@ return 0; } - -void floppy_eject(void) -{ -} diff -u --recursive --new-file v2.5.0/linux/drivers/acorn/scsi/arxescsi.h linux/drivers/acorn/scsi/arxescsi.h --- v2.5.0/linux/drivers/acorn/scsi/arxescsi.h Fri May 12 11:21:20 2000 +++ linux/drivers/acorn/scsi/arxescsi.h Wed Nov 28 10:22:26 2001 @@ -61,7 +61,6 @@ eh_bus_reset_handler: fas216_eh_bus_reset, \ eh_device_reset_handler: fas216_eh_device_reset, \ eh_abort_handler: fas216_eh_abort, \ -use_new_eh_code: 1 \ } #ifndef HOSTS_C diff -u --recursive --new-file v2.5.0/linux/drivers/acorn/scsi/cumana_2.c linux/drivers/acorn/scsi/cumana_2.c --- v2.5.0/linux/drivers/acorn/scsi/cumana_2.c Sun Nov 4 09:31:57 2001 +++ linux/drivers/acorn/scsi/cumana_2.c Wed Nov 28 10:22:26 2001 @@ -575,7 +575,6 @@ eh_bus_reset_handler: fas216_eh_bus_reset, eh_device_reset_handler: fas216_eh_device_reset, eh_abort_handler: fas216_eh_abort, - use_new_eh_code: 1 }; static int __init cumanascsi2_init(void) diff -u --recursive --new-file v2.5.0/linux/drivers/acorn/scsi/eesox.c linux/drivers/acorn/scsi/eesox.c --- v2.5.0/linux/drivers/acorn/scsi/eesox.c Sun Nov 4 09:31:57 2001 +++ linux/drivers/acorn/scsi/eesox.c Wed Nov 28 10:22:27 2001 @@ -577,7 +577,6 @@ eh_bus_reset_handler: fas216_eh_bus_reset, eh_device_reset_handler: fas216_eh_device_reset, eh_abort_handler: fas216_eh_abort, - use_new_eh_code: 1 }; static int __init eesox_init(void) diff -u --recursive --new-file v2.5.0/linux/drivers/acorn/scsi/powertec.c linux/drivers/acorn/scsi/powertec.c --- v2.5.0/linux/drivers/acorn/scsi/powertec.c Sun Nov 4 09:31:57 2001 +++ linux/drivers/acorn/scsi/powertec.c Wed Nov 28 10:22:27 2001 @@ -477,7 +477,6 @@ eh_bus_reset_handler: fas216_eh_bus_reset, eh_device_reset_handler: fas216_eh_device_reset, eh_abort_handler: fas216_eh_abort, - use_new_eh_code: 1 }; static int __init powertecscsi_init(void) diff -u --recursive --new-file v2.5.0/linux/drivers/block/DAC960.c linux/drivers/block/DAC960.c --- v2.5.0/linux/drivers/block/DAC960.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/block/DAC960.c Sun Dec 16 12:20:20 2001 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -306,9 +307,9 @@ static void DAC960_WaitForCommand(DAC960_Controller_T *Controller) { - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&Controller->RequestQueue->queue_lock); __wait_event(Controller->CommandWaitQueue, Controller->FreeCommands); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&Controller->RequestQueue->queue_lock); } @@ -1922,76 +1923,6 @@ /* - DAC960_BackMergeFunction is the Back Merge Function for the DAC960 driver. -*/ - -static int DAC960_BackMergeFunction(RequestQueue_T *RequestQueue, - IO_Request_T *Request, - BufferHeader_T *BufferHeader, - int MaxSegments) -{ - DAC960_Controller_T *Controller = - (DAC960_Controller_T *) RequestQueue->queuedata; - if (Request->bhtail->b_data + Request->bhtail->b_size == BufferHeader->b_data) - return true; - if (Request->nr_segments < MaxSegments && - Request->nr_segments < Controller->DriverScatterGatherLimit) - { - Request->nr_segments++; - return true; - } - return false; -} - - -/* - DAC960_FrontMergeFunction is the Front Merge Function for the DAC960 driver. -*/ - -static int DAC960_FrontMergeFunction(RequestQueue_T *RequestQueue, - IO_Request_T *Request, - BufferHeader_T *BufferHeader, - int MaxSegments) -{ - DAC960_Controller_T *Controller = - (DAC960_Controller_T *) RequestQueue->queuedata; - if (BufferHeader->b_data + BufferHeader->b_size == Request->bh->b_data) - return true; - if (Request->nr_segments < MaxSegments && - Request->nr_segments < Controller->DriverScatterGatherLimit) - { - Request->nr_segments++; - return true; - } - return false; -} - - -/* - DAC960_MergeRequestsFunction is the Merge Requests Function for the - DAC960 driver. -*/ - -static int DAC960_MergeRequestsFunction(RequestQueue_T *RequestQueue, - IO_Request_T *Request, - IO_Request_T *NextRequest, - int MaxSegments) -{ - DAC960_Controller_T *Controller = - (DAC960_Controller_T *) RequestQueue->queuedata; - int TotalSegments = Request->nr_segments + NextRequest->nr_segments; - if (Request->bhtail->b_data + Request->bhtail->b_size - == NextRequest->bh->b_data) - TotalSegments--; - if (TotalSegments > MaxSegments || - TotalSegments > Controller->DriverScatterGatherLimit) - return false; - Request->nr_segments = TotalSegments; - return true; -} - - -/* DAC960_RegisterBlockDevice registers the Block Device structures associated with Controller. */ @@ -2016,14 +1947,16 @@ */ RequestQueue = BLK_DEFAULT_QUEUE(MajorNumber); blk_init_queue(RequestQueue, DAC960_RequestFunction); - blk_queue_headactive(RequestQueue, 0); - RequestQueue->back_merge_fn = DAC960_BackMergeFunction; - RequestQueue->front_merge_fn = DAC960_FrontMergeFunction; - RequestQueue->merge_requests_fn = DAC960_MergeRequestsFunction; RequestQueue->queuedata = Controller; + blk_queue_max_hw_segments(RequestQueue, + Controller->DriverScatterGatherLimit); + blk_queue_max_phys_segments(RequestQueue, ~0); + blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand); + Controller->RequestQueue = RequestQueue; /* - Initialize the Max Sectors per Request array. + Initialize the Disk Partitions array, Partition Sizes array, Block Sizes + array, and Max Sectors per Request array. */ for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++) Controller->MaxSectorsPerRequest[MinorNumber] = @@ -2031,7 +1964,6 @@ Controller->GenericDiskInfo.part = Controller->DiskPartitions; Controller->GenericDiskInfo.sizes = Controller->PartitionSizes; blksize_size[MajorNumber] = Controller->BlockSizes; - max_sectors[MajorNumber] = Controller->MaxSectorsPerRequest; /* Initialize Read Ahead to 128 sectors. */ @@ -2080,9 +2012,7 @@ */ Controller->GenericDiskInfo.part = NULL; Controller->GenericDiskInfo.sizes = NULL; - blk_size[MajorNumber] = NULL; - blksize_size[MajorNumber] = NULL; - max_sectors[MajorNumber] = NULL; + blk_clear(MajorNumber); /* Remove the Generic Disk Information structure from the list. */ @@ -2813,23 +2743,24 @@ CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount; while (BufferHeader != NULL) { - if (BufferHeader->b_data == LastDataEndPointer) + if (bio_data(BufferHeader) == LastDataEndPointer) { ScatterGatherList[SegmentNumber-1].SegmentByteCount += - BufferHeader->b_size; - LastDataEndPointer += BufferHeader->b_size; + bio_size(BufferHeader); + LastDataEndPointer += bio_size(BufferHeader); } else { ScatterGatherList[SegmentNumber].SegmentDataPointer = - Virtual_to_Bus32(BufferHeader->b_data); + Virtual_to_Bus32(bio_data(BufferHeader)); ScatterGatherList[SegmentNumber].SegmentByteCount = - BufferHeader->b_size; - LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size; + bio_size(BufferHeader); + LastDataEndPointer = bio_data(BufferHeader) + + bio_size(BufferHeader); if (SegmentNumber++ > Controller->DriverScatterGatherLimit) panic("DAC960: Scatter/Gather Segment Overflow\n"); } - BufferHeader = BufferHeader->b_reqnext; + BufferHeader = BufferHeader->bi_next; } if (SegmentNumber != Command->SegmentCount) panic("DAC960: SegmentNumber != SegmentCount\n"); @@ -2903,23 +2834,24 @@ .ScatterGatherSegments; while (BufferHeader != NULL) { - if (BufferHeader->b_data == LastDataEndPointer) + if (bio_data(BufferHeader) == LastDataEndPointer) { ScatterGatherList[SegmentNumber-1].SegmentByteCount += - BufferHeader->b_size; - LastDataEndPointer += BufferHeader->b_size; + bio_size(BufferHeader); + LastDataEndPointer += bio_size(BufferHeader); } else { ScatterGatherList[SegmentNumber].SegmentDataPointer = - Virtual_to_Bus64(BufferHeader->b_data); + Virtual_to_Bus64(bio_data(BufferHeader)); ScatterGatherList[SegmentNumber].SegmentByteCount = - BufferHeader->b_size; - LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size; + bio_size(BufferHeader); + LastDataEndPointer = bio_data(BufferHeader) + + bio_size(BufferHeader); if (SegmentNumber++ > Controller->DriverScatterGatherLimit) panic("DAC960: Scatter/Gather Segment Overflow\n"); } - BufferHeader = BufferHeader->b_reqnext; + BufferHeader = BufferHeader->bi_next; } if (SegmentNumber != Command->SegmentCount) panic("DAC960: SegmentNumber != SegmentCount\n"); @@ -2947,7 +2879,7 @@ while (true) { if (list_empty(RequestQueueHead)) return false; - Request = blkdev_entry_next_request(RequestQueueHead); + Request = elv_next_request(RequestQueue); Command = DAC960_AllocateCommand(Controller); if (Command != NULL) break; if (!WaitForCommand) return false; @@ -2958,12 +2890,10 @@ else Command->CommandType = DAC960_WriteCommand; Command->Completion = Request->waiting; Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev); - Command->BlockNumber = - Request->sector - + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect; + Command->BlockNumber = Request->sector; Command->BlockCount = Request->nr_sectors; - Command->SegmentCount = Request->nr_segments; - Command->BufferHeader = Request->bh; + Command->SegmentCount = Request->nr_phys_segments; + Command->BufferHeader = Request->bio; Command->RequestBuffer = Request->buffer; blkdev_dequeue_request(Request); blkdev_release_request(Request); @@ -3016,8 +2946,10 @@ static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader, boolean SuccessfulIO) { - blk_finished_io(BufferHeader->b_size >> 9); - BufferHeader->b_end_io(BufferHeader, SuccessfulIO); + if (SuccessfulIO) + set_bit(BIO_UPTODATE, &BufferHeader->bi_flags); + blk_finished_io(bio_sectors(BufferHeader)); + BufferHeader->bi_end_io(BufferHeader); } @@ -3071,13 +3003,13 @@ Controller, Controller->ControllerNumber, Command->LogicalDriveNumber, Command->BlockNumber, Command->BlockNumber + Command->BlockCount - 1); - if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0) + if (DAC960_PartitionNumber(Command->BufferHeader->bi_dev) > 0) DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %u..%u\n", Controller, Controller->ControllerNumber, Command->LogicalDriveNumber, - DAC960_PartitionNumber(Command->BufferHeader->b_rdev), - Command->BufferHeader->b_rsector, - Command->BufferHeader->b_rsector + Command->BlockCount - 1); + DAC960_PartitionNumber(Command->BufferHeader->bi_dev), + Command->BufferHeader->bi_sector, + Command->BufferHeader->bi_sector + Command->BlockCount - 1); } @@ -3104,8 +3036,8 @@ */ while (BufferHeader != NULL) { - BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext; - BufferHeader->b_reqnext = NULL; + BufferHeader_T *NextBufferHeader = BufferHeader->bi_next; + BufferHeader->bi_next = NULL; DAC960_ProcessCompletedBuffer(BufferHeader, true); BufferHeader = NextBufferHeader; } @@ -3119,7 +3051,7 @@ else if ((CommandStatus == DAC960_V1_IrrecoverableDataError || CommandStatus == DAC960_V1_BadDataEncountered) && BufferHeader != NULL && - BufferHeader->b_reqnext != NULL) + BufferHeader->bi_next != NULL) { DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; @@ -3133,10 +3065,10 @@ Command->CommandType = DAC960_WriteRetryCommand; CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write; } - Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits; + Command->BlockCount = bio_size(BufferHeader) >> DAC960_BlockSizeBits; CommandMailbox->Type5.LD.TransferLength = Command->BlockCount; CommandMailbox->Type5.BusAddress = - Virtual_to_Bus32(BufferHeader->b_data); + Virtual_to_Bus32(bio_data(BufferHeader)); DAC960_QueueCommand(Command); return; } @@ -3149,8 +3081,8 @@ */ while (BufferHeader != NULL) { - BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext; - BufferHeader->b_reqnext = NULL; + BufferHeader_T *NextBufferHeader = BufferHeader->bi_next; + BufferHeader->bi_next = NULL; DAC960_ProcessCompletedBuffer(BufferHeader, false); BufferHeader = NextBufferHeader; } @@ -3164,8 +3096,8 @@ else if (CommandType == DAC960_ReadRetryCommand || CommandType == DAC960_WriteRetryCommand) { - BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext; - BufferHeader->b_reqnext = NULL; + BufferHeader_T *NextBufferHeader = BufferHeader->bi_next; + BufferHeader->bi_next = NULL; /* Perform completion processing for this single buffer. */ @@ -3182,14 +3114,14 @@ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; Command->BlockNumber += - BufferHeader->b_size >> DAC960_BlockSizeBits; + bio_size(BufferHeader) >> DAC960_BlockSizeBits; Command->BlockCount = - NextBufferHeader->b_size >> DAC960_BlockSizeBits; + bio_size(NextBufferHeader) >> DAC960_BlockSizeBits; Command->BufferHeader = NextBufferHeader; CommandMailbox->Type5.LD.TransferLength = Command->BlockCount; CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber; CommandMailbox->Type5.BusAddress = - Virtual_to_Bus32(NextBufferHeader->b_data); + Virtual_to_Bus32(bio_data(NextBufferHeader)); DAC960_QueueCommand(Command); return; } @@ -3935,13 +3867,13 @@ Controller, Controller->ControllerNumber, Command->LogicalDriveNumber, Command->BlockNumber, Command->BlockNumber + Command->BlockCount - 1); - if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0) + if (DAC960_PartitionNumber(Command->BufferHeader->bi_dev) > 0) DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %u..%u\n", Controller, Controller->ControllerNumber, Command->LogicalDriveNumber, - DAC960_PartitionNumber(Command->BufferHeader->b_rdev), - Command->BufferHeader->b_rsector, - Command->BufferHeader->b_rsector + Command->BlockCount - 1); + DAC960_PartitionNumber(Command->BufferHeader->bi_dev), + Command->BufferHeader->bi_sector, + Command->BufferHeader->bi_sector + Command->BlockCount - 1); } @@ -4210,8 +4142,8 @@ */ while (BufferHeader != NULL) { - BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext; - BufferHeader->b_reqnext = NULL; + BufferHeader_T *NextBufferHeader = BufferHeader->bi_next; + BufferHeader->bi_next = NULL; DAC960_ProcessCompletedBuffer(BufferHeader, true); BufferHeader = NextBufferHeader; } @@ -4225,19 +4157,19 @@ else if (Command->V2.RequestSense.SenseKey == DAC960_SenseKey_MediumError && BufferHeader != NULL && - BufferHeader->b_reqnext != NULL) + BufferHeader->bi_next != NULL) { if (CommandType == DAC960_ReadCommand) Command->CommandType = DAC960_ReadRetryCommand; else Command->CommandType = DAC960_WriteRetryCommand; - Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits; + Command->BlockCount = bio_size(BufferHeader) >> DAC960_BlockSizeBits; CommandMailbox->SCSI_10.CommandControlBits .AdditionalScatterGatherListMemory = false; CommandMailbox->SCSI_10.DataTransferSize = Command->BlockCount << DAC960_BlockSizeBits; CommandMailbox->SCSI_10.DataTransferMemoryAddress .ScatterGatherSegments[0].SegmentDataPointer = - Virtual_to_Bus64(BufferHeader->b_data); + Virtual_to_Bus64(bio_data(BufferHeader)); CommandMailbox->SCSI_10.DataTransferMemoryAddress .ScatterGatherSegments[0].SegmentByteCount = CommandMailbox->SCSI_10.DataTransferSize; @@ -4255,8 +4187,8 @@ */ while (BufferHeader != NULL) { - BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext; - BufferHeader->b_reqnext = NULL; + BufferHeader_T *NextBufferHeader = BufferHeader->bi_next; + BufferHeader->bi_next = NULL; DAC960_ProcessCompletedBuffer(BufferHeader, false); BufferHeader = NextBufferHeader; } @@ -4270,8 +4202,8 @@ else if (CommandType == DAC960_ReadRetryCommand || CommandType == DAC960_WriteRetryCommand) { - BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext; - BufferHeader->b_reqnext = NULL; + BufferHeader_T *NextBufferHeader = BufferHeader->bi_next; + BufferHeader->bi_next = NULL; /* Perform completion processing for this single buffer. */ @@ -4286,16 +4218,16 @@ if (NextBufferHeader != NULL) { Command->BlockNumber += - BufferHeader->b_size >> DAC960_BlockSizeBits; + bio_size(BufferHeader) >> DAC960_BlockSizeBits; Command->BlockCount = - NextBufferHeader->b_size >> DAC960_BlockSizeBits; + bio_size(NextBufferHeader) >> DAC960_BlockSizeBits; Command->BufferHeader = NextBufferHeader; CommandMailbox->SCSI_10.DataTransferSize = Command->BlockCount << DAC960_BlockSizeBits; CommandMailbox->SCSI_10.DataTransferMemoryAddress .ScatterGatherSegments[0] .SegmentDataPointer = - Virtual_to_Bus64(NextBufferHeader->b_data); + Virtual_to_Bus64(bio_data(NextBufferHeader)); CommandMailbox->SCSI_10.DataTransferMemoryAddress .ScatterGatherSegments[0] .SegmentByteCount = @@ -5416,7 +5348,8 @@ int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev); DiskGeometry_T Geometry, *UserGeometry; DAC960_Controller_T *Controller; - int PartitionNumber; + int res; + if (File != NULL && (File->f_flags & O_NONBLOCK)) return DAC960_UserIOCTL(Inode, File, Request, Argument); if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1) @@ -5465,61 +5398,27 @@ LogicalDeviceInfo->ConfigurableDeviceSize / (Geometry.heads * Geometry.sectors); } - Geometry.start = - Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].start_sect; + Geometry.start = get_start_sect(Inode->i_rdev); return (copy_to_user(UserGeometry, &Geometry, sizeof(DiskGeometry_T)) ? -EFAULT : 0); case BLKGETSIZE: - /* Get Device Size. */ - if ((unsigned long *) Argument == NULL) return -EINVAL; - return put_user(Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)] - .nr_sects, - (unsigned long *) Argument); case BLKGETSIZE64: - if ((u64 *) Argument == NULL) return -EINVAL; - return put_user((u64) Controller->GenericDiskInfo - .part[MINOR(Inode->i_rdev)] - .nr_sects << 9, - (u64 *) Argument); case BLKRAGET: case BLKRASET: case BLKFLSBUF: case BLKBSZGET: case BLKBSZSET: return blk_ioctl(Inode->i_rdev, Request, Argument); + case BLKRRPART: /* Re-Read Partition Table. */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (Controller->LogicalDriveUsageCount[LogicalDriveNumber] > 1) return -EBUSY; - for (PartitionNumber = 0; - PartitionNumber < DAC960_MaxPartitions; - PartitionNumber++) - { - KernelDevice_T Device = DAC960_KernelDevice(ControllerNumber, - LogicalDriveNumber, - PartitionNumber); - int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber, - PartitionNumber); - if (Controller->GenericDiskInfo.part[MinorNumber].nr_sects == 0) - continue; - /* - Flush all changes and invalidate buffered state. - */ - invalidate_device(Device, 1); - /* - Clear existing partition sizes. - */ - if (PartitionNumber > 0) - { - Controller->GenericDiskInfo.part[MinorNumber].start_sect = 0; - Controller->GenericDiskInfo.part[MinorNumber].nr_sects = 0; - } - /* - Reset the Block Size so that the partition table can be read. - */ - set_blocksize(Device, BLOCK_SIZE); - } + res = wipe_partitions(Inode->i_rdev); + if (res) /* nothing */ + return res; + DAC960_RegisterDisk(Controller, LogicalDriveNumber); return 0; } @@ -5641,11 +5540,11 @@ while (Controller->V1.DirectCommandActive[DCDB.Channel] [DCDB.TargetID]) { - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&Controller->RequestQueue->queue_lock); __wait_event(Controller->CommandWaitQueue, !Controller->V1.DirectCommandActive [DCDB.Channel][DCDB.TargetID]); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&Controller->RequestQueue->queue_lock); } Controller->V1.DirectCommandActive[DCDB.Channel] [DCDB.TargetID] = true; diff -u --recursive --new-file v2.5.0/linux/drivers/block/DAC960.h linux/drivers/block/DAC960.h --- v2.5.0/linux/drivers/block/DAC960.h Wed Oct 17 14:46:29 2001 +++ linux/drivers/block/DAC960.h Tue Nov 27 09:23:27 2001 @@ -2191,7 +2191,7 @@ of the Linux Kernel and I/O Subsystem. */ -typedef struct buffer_head BufferHeader_T; +typedef struct bio BufferHeader_T; typedef struct file File_T; typedef struct block_device_operations BlockDeviceOperations_T; typedef struct completion Completion_T; @@ -2475,7 +2475,6 @@ DiskPartition_T DiskPartitions[DAC960_MinorCount]; int PartitionSizes[DAC960_MinorCount]; int BlockSizes[DAC960_MinorCount]; - int MaxSectorsPerRequest[DAC960_MinorCount]; unsigned char ProgressBuffer[DAC960_ProgressBufferSize]; unsigned char UserStatusBuffer[DAC960_UserMessageSize]; } @@ -2509,7 +2508,7 @@ void DAC960_AcquireControllerLock(DAC960_Controller_T *Controller, ProcessorFlags_T *ProcessorFlags) { - spin_lock_irqsave(&io_request_lock, *ProcessorFlags); + spin_lock_irqsave(&Controller->RequestQueue->queue_lock, *ProcessorFlags); } @@ -2521,13 +2520,13 @@ void DAC960_ReleaseControllerLock(DAC960_Controller_T *Controller, ProcessorFlags_T *ProcessorFlags) { - spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags); + spin_unlock_irqrestore(&Controller->RequestQueue->queue_lock, *ProcessorFlags); } /* DAC960_AcquireControllerLockRF acquires exclusive access to Controller, - but is only called from the request function with the io_request_lock held. + but is only called from the request function with the queue lock held. */ static inline @@ -2539,7 +2538,7 @@ /* DAC960_ReleaseControllerLockRF releases exclusive access to Controller, - but is only called from the request function with the io_request_lock held. + but is only called from the request function with the queue lock held. */ static inline @@ -2558,7 +2557,7 @@ void DAC960_AcquireControllerLockIH(DAC960_Controller_T *Controller, ProcessorFlags_T *ProcessorFlags) { - spin_lock_irqsave(&io_request_lock, *ProcessorFlags); + spin_lock_irqsave(&Controller->RequestQueue->queue_lock, *ProcessorFlags); } @@ -2571,7 +2570,7 @@ void DAC960_ReleaseControllerLockIH(DAC960_Controller_T *Controller, ProcessorFlags_T *ProcessorFlags) { - spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags); + spin_unlock_irqrestore(&Controller->RequestQueue->queue_lock, *ProcessorFlags); } diff -u --recursive --new-file v2.5.0/linux/drivers/block/Makefile linux/drivers/block/Makefile --- v2.5.0/linux/drivers/block/Makefile Sun Sep 9 12:00:55 2001 +++ linux/drivers/block/Makefile Thu Dec 6 14:02:56 2001 @@ -10,9 +10,9 @@ O_TARGET := block.o -export-objs := ll_rw_blk.o blkpg.o loop.o DAC960.o genhd.o +export-objs := elevator.o ll_rw_blk.o blkpg.o loop.o DAC960.o genhd.o block_ioctl.o -obj-y := ll_rw_blk.o blkpg.o genhd.o elevator.o +obj-y := elevator.o ll_rw_blk.o blkpg.o genhd.o block_ioctl.o obj-$(CONFIG_MAC_FLOPPY) += swim3.o obj-$(CONFIG_BLK_DEV_FD) += floppy.o diff -u --recursive --new-file v2.5.0/linux/drivers/block/acsi.c linux/drivers/block/acsi.c --- v2.5.0/linux/drivers/block/acsi.c Fri Nov 9 13:58:03 2001 +++ linux/drivers/block/acsi.c Sun Dec 16 12:20:20 2001 @@ -253,6 +253,8 @@ static int CurrentNSect; static char *CurrentBuffer; +static spinlock_t acsi_lock = SPIN_LOCK_UNLOCKED; + #define SET_TIMER() mod_timer(&acsi_timer, jiffies + ACSI_TIMEOUT) #define CLEAR_TIMER() del_timer(&acsi_timer) @@ -1011,7 +1013,6 @@ goto repeat; } - block += acsi_part[dev].start_sect; target = acsi_info[DEVICE_NR(dev)].target; lun = acsi_info[DEVICE_NR(dev)].lun; @@ -1123,7 +1124,7 @@ put_user( 64, &geo->heads ); put_user( 32, &geo->sectors ); put_user( acsi_info[dev].size >> 11, &geo->cylinders ); - put_user( acsi_part[MINOR(inode->i_rdev)].start_sect, &geo->start ); + put_user(get_start_sect(inode->i_rdev), &geo->start); return 0; } @@ -1785,7 +1786,7 @@ phys_acsi_buffer = virt_to_phys( acsi_buffer ); STramMask = ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000 : 0xff000000; - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST, &acsi_lock); read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */ add_gendisk(&acsi_gendisk); @@ -1852,7 +1853,7 @@ { int device; struct gendisk * gdev; - int max_p, start, i; + int res; struct acsi_info_struct *aip; device = DEVICE_NR(MINOR(dev)); @@ -1867,16 +1868,7 @@ DEVICE_BUSY = 1; sti(); - max_p = gdev->max_p; - start = device << gdev->minor_shift; - - for( i = max_p - 1; i >= 0 ; i-- ) { - if (gdev->part[start + i].nr_sects != 0) { - invalidate_device(MKDEV(MAJOR_NR, start + i), 1); - gdev->part[start + i].nr_sects = 0; - } - gdev->part[start+i].start_sect = 0; - }; + res = wipe_partitions(dev); stdma_lock( NULL, NULL ); @@ -1891,12 +1883,13 @@ ENABLE_IRQ(); stdma_release(); - - grok_partitions(gdev, device, (aip->type==HARDDISK)?1<<4:1, aip->size); + + if (!res) + grok_partitions(dev, aip->size); DEVICE_BUSY = 0; wake_up(&busy_wait); - return 0; + return res; } diff -u --recursive --new-file v2.5.0/linux/drivers/block/acsi_slm.c linux/drivers/block/acsi_slm.c --- v2.5.0/linux/drivers/block/acsi_slm.c Tue May 22 10:23:16 2001 +++ linux/drivers/block/acsi_slm.c Fri Nov 30 08:26:04 2001 @@ -121,8 +121,8 @@ static struct slm { unsigned target; /* target number */ unsigned lun; /* LUN in target controller */ - unsigned wbusy : 1; /* output part busy */ - unsigned rbusy : 1; /* status part busy */ + atomic_t wr_ok; /* set to 0 if output part busy */ + atomic_t rd_ok; /* set to 0 if status part busy */ } slm_info[MAX_SLM]; int N_SLM_Printers = 0; @@ -778,15 +778,17 @@ if (file->f_mode & 2) { /* open for writing is exclusive */ - if (sip->wbusy) + if ( !atomic_dec_and_test(&sip->wr_ok) ) { + atomic_inc(&sip->wr_ok); return( -EBUSY ); - sip->wbusy = 1; + } } if (file->f_mode & 1) { - /* open for writing is exclusive */ - if (sip->rbusy) - return( -EBUSY ); - sip->rbusy = 1; + /* open for reading is exclusive */ + if ( !atomic_dec_and_test(&sip->rd_ok) ) { + atomic_inc(&sip->rd_ok); + return( -EBUSY ); + } } return( 0 ); @@ -801,12 +803,10 @@ device = MINOR(inode->i_rdev); sip = &slm_info[device]; - lock_kernel(); if (file->f_mode & 2) - sip->wbusy = 0; + atomic_inc( &sip->wr_ok ); if (file->f_mode & 1) - sip->rbusy = 0; - unlock_kernel(); + atomic_inc( &sip->rd_ok ); return( 0 ); } @@ -983,8 +983,8 @@ slm_info[N_SLM_Printers].target = target; slm_info[N_SLM_Printers].lun = lun; - slm_info[N_SLM_Printers].wbusy = 0; - slm_info[N_SLM_Printers].rbusy = 0; + atomic_set(&slm_info[N_SLM_Printers].wr_ok, 1 ); + atomic_set(&slm_info[N_SLM_Printers].rd_ok, 1 ); printk( KERN_INFO " Printer: %s\n", SLMBuffer ); printk( KERN_INFO "Detected slm%d at id %d lun %d\n", diff -u --recursive --new-file v2.5.0/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c --- v2.5.0/linux/drivers/block/amiflop.c Thu Oct 25 13:58:34 2001 +++ linux/drivers/block/amiflop.c Sun Dec 16 12:20:20 2001 @@ -174,6 +174,8 @@ static int writefromint; static char *raw_buf; +static spinlock_t amiflop_lock = SPIN_LOCK_UNLOCKED; + #define RAW_BUF_SIZE 30000 /* size of raw disk data */ /* @@ -1855,7 +1857,7 @@ post_write_timer.data = 0; post_write_timer.function = post_write; - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST, &amiflop_lock); blksize_size[MAJOR_NR] = floppy_blocksizes; blk_size[MAJOR_NR] = floppy_sizes; @@ -1895,10 +1897,9 @@ free_irq(IRQ_AMIGA_DSKBLK, NULL); custom.dmacon = DMAF_DISK; /* disable DMA */ amiga_chip_free(raw_buf); - blk_size[MAJOR_NR] = NULL; - blksize_size[MAJOR_NR] = NULL; blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); release_mem_region(CUSTOM_PHYSADDR+0x20, 8); unregister_blkdev(MAJOR_NR, "fd"); + blk_clear(MAJOR_NR); } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c --- v2.5.0/linux/drivers/block/ataflop.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/block/ataflop.c Sun Dec 16 12:20:20 2001 @@ -156,6 +156,8 @@ static int DriveType = TYPE_HD; +static spinlock_t ataflop_lock = SPIN_LOCK_UNLOCKED; + /* Array for translating minors into disk formats */ static struct { int index; @@ -2013,7 +2015,7 @@ blk_size[MAJOR_NR] = floppy_sizes; blksize_size[MAJOR_NR] = floppy_blocksizes; - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST, &ataflop_lock); printk(KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n", DriveType == 0 ? 'D' : DriveType == 1 ? 'H' : 'E', diff -u --recursive --new-file v2.5.0/linux/drivers/block/blkpg.c linux/drivers/block/blkpg.c --- v2.5.0/linux/drivers/block/blkpg.c Sun Nov 11 10:20:21 2001 +++ linux/drivers/block/blkpg.c Thu Dec 6 14:02:56 2001 @@ -63,7 +63,8 @@ * or has the same number as an existing one * 0: all OK. */ -int add_partition(kdev_t dev, struct blkpg_partition *p) { +int add_partition(kdev_t dev, struct blkpg_partition *p) +{ struct gendisk *g; long long ppstart, pplength; long pstart, plength; @@ -123,7 +124,8 @@ * * Note that the dev argument refers to the entire disk, not the partition. */ -int del_partition(kdev_t dev, struct blkpg_partition *p) { +int del_partition(kdev_t dev, struct blkpg_partition *p) +{ struct gendisk *g; kdev_t devp; int drive, first_minor, minor; @@ -192,16 +194,21 @@ /* * Common ioctl's for block devices */ - +extern int block_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg); int blk_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg) { + request_queue_t *q; struct gendisk *g; u64 ullval = 0; - int intval; + int intval, *iptr; if (!dev) return -EINVAL; + intval = block_ioctl(dev, cmd, arg); + if (intval != -ENOTTY) + return intval; + switch (cmd) { case BLKROSET: if (!capable(CAP_SYS_ADMIN)) @@ -226,8 +233,26 @@ return -EINVAL; return put_user(read_ahead[MAJOR(dev)], (long *) arg); + case BLKFRASET: + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (!(iptr = max_readahead[MAJOR(dev)])) + return -EINVAL; + iptr[MINOR(dev)] = arg; + return 0; + + case BLKFRAGET: + if (!(iptr = max_readahead[MAJOR(dev)])) + return -EINVAL; + return put_user(iptr[MINOR(dev)], (long *) arg); + + case BLKSECTGET: + if ((q = blk_get_queue(dev))) + return put_user(q->max_sectors, (unsigned short *)arg); + return -EINVAL; + case BLKFLSBUF: - if(!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN)) return -EACCES; fsync_dev(dev); invalidate_buffers(dev); @@ -246,8 +271,7 @@ if (cmd == BLKGETSIZE) return put_user((unsigned long)ullval, (unsigned long *)arg); - else - return put_user(ullval, (u64 *)arg); + return put_user(ullval, (u64 *)arg); #if 0 case BLKRRPART: /* Re-read partition tables */ if (!capable(CAP_SYS_ADMIN)) @@ -258,34 +282,34 @@ case BLKPG: return blkpg_ioctl(dev, (struct blkpg_ioctl_arg *) arg); + /* + * deprecated, use the /proc/iosched interface instead + */ case BLKELVGET: - return blkelvget_ioctl(&blk_get_queue(dev)->elevator, - (blkelv_ioctl_arg_t *) arg); case BLKELVSET: - return blkelvset_ioctl(&blk_get_queue(dev)->elevator, - (blkelv_ioctl_arg_t *) arg); + return -ENOTTY; case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ intval = BLOCK_SIZE; if (blksize_size[MAJOR(dev)]) intval = blksize_size[MAJOR(dev)][MINOR(dev)]; - return put_user (intval, (int *) arg); + return put_user(intval, (int *) arg); case BLKBSZSET: /* set the logical block size */ - if (!capable (CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (!dev || !arg) + if (!arg) return -EINVAL; - if (get_user (intval, (int *) arg)) + if (get_user(intval, (int *) arg)) return -EFAULT; if (intval > PAGE_SIZE || intval < 512 || (intval & (intval - 1))) return -EINVAL; - if (is_mounted (dev) || is_swap_partition (dev)) + if (is_mounted(dev) || is_swap_partition(dev)) return -EBUSY; - set_blocksize (dev, intval); + set_blocksize(dev, intval); return 0; default: diff -u --recursive --new-file v2.5.0/linux/drivers/block/block_ioctl.c linux/drivers/block/block_ioctl.c --- v2.5.0/linux/drivers/block/block_ioctl.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/block_ioctl.c Sun Dec 16 12:20:20 2001 @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2001 Jens Axboe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public Licens + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int blk_do_rq(request_queue_t *q, struct request *rq) +{ + DECLARE_COMPLETION(wait); + int err = 0; + + rq->flags |= REQ_BARRIER; + rq->waiting = &wait; + elv_add_request(q, rq, 1); + generic_unplug_device(q); + wait_for_completion(&wait); + + /* + * for now, never retry anything + */ + if (rq->errors) + err = -EIO; + + return err; +} + +int block_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg) +{ + request_queue_t *q; + struct request *rq; + int close = 0, err; + + q = blk_get_queue(dev); + if (!q) + return -ENXIO; + + switch (cmd) { + case CDROMCLOSETRAY: + close = 1; + case CDROMEJECT: + rq = blk_get_request(q, WRITE, __GFP_WAIT); + rq->flags = REQ_BLOCK_PC; + memset(rq->cmd, 0, sizeof(rq->cmd)); + rq->cmd[0] = GPCMD_START_STOP_UNIT; + rq->cmd[4] = 0x02 + (close != 0); + err = blk_do_rq(q, rq); + blk_put_request(rq); + break; + default: + err = -ENOTTY; + } + +#if 0 + blk_put_queue(q); +#endif + return err; +} diff -u --recursive --new-file v2.5.0/linux/drivers/block/cciss.c linux/drivers/block/cciss.c --- v2.5.0/linux/drivers/block/cciss.c Fri Nov 9 14:28:46 2001 +++ linux/drivers/block/cciss.c Sun Dec 16 12:20:20 2001 @@ -84,7 +84,7 @@ #define MAX_CONFIG_WAIT 1000 #define READ_AHEAD 128 -#define NR_CMDS 128 /* #commands that can be outstanding */ +#define NR_CMDS 384 /* #commands that can be outstanding */ #define MAX_CTLR 8 #define CCISS_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */ @@ -147,7 +147,6 @@ " IRQ: %d\n" " Logical drives: %d\n" " Current Q depth: %d\n" - " Current # commands on controller %d\n" " Max Q depth since init: %d\n" " Max # commands on controller since init: %d\n" " Max SG entries since init: %d\n\n", @@ -158,8 +157,7 @@ (unsigned long)h->vaddr, (unsigned int)h->intr, h->num_luns, - h->Qdepth, h->commands_outstanding, - h->maxQsinceinit, h->max_outstanding, h->maxSG); + h->Qdepth, h->maxQsinceinit, h->max_outstanding, h->maxSG); pos += size; len += size; for(i=0; inum_luns; i++) { @@ -237,7 +235,7 @@ i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS); if (i == NR_CMDS) return NULL; - } while(test_and_set_bit(i%32, h->cmd_pool_bits+(i/32)) != 0); + } while(test_and_set_bit(i & 31, h->cmd_pool_bits+(i/32)) != 0); #ifdef CCISS_DEBUG printk(KERN_DEBUG "cciss: using command buffer %d\n", i); #endif @@ -308,13 +306,10 @@ /* for each partition */ for(j=0; jblocksizes[(i<hardsizes[ (i<block_size; - } hba[ctlr]->gendisk.nr_real++; + (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->block_size; } } /* @@ -377,8 +372,6 @@ { int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR; int dsk = MINOR(inode->i_rdev) >> NWD_SHIFT; - int diskinfo[4]; - struct hd_geometry *geo = (struct hd_geometry *)arg; #ifdef CCISS_DEBUG printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg); @@ -386,6 +379,10 @@ switch(cmd) { case HDIO_GETGEO: + { + struct hd_geometry *geo = (struct hd_geometry *)arg; + int diskinfo[4]; + if (hba[ctlr]->drv[dsk].cylinders) { diskinfo[0] = hba[ctlr]->drv[dsk].heads; diskinfo[1] = hba[ctlr]->drv[dsk].sectors; @@ -393,20 +390,18 @@ } else { diskinfo[0] = 0xff; diskinfo[1] = 0x3f; - diskinfo[2] = hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f); } + diskinfo[2] = hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f); + } put_user(diskinfo[0], &geo->heads); put_user(diskinfo[1], &geo->sectors); put_user(diskinfo[2], &geo->cylinders); - put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect, &geo->start); - return 0; - case BLKGETSIZE: - put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg); - return 0; - case BLKGETSIZE64: - put_user((u64)hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects << 9, (u64*)arg); + put_user(get_start_sect(inode->i_rdev), &geo->start); return 0; + } case BLKRRPART: return revalidate_logvol(inode->i_rdev, 1); + case BLKGETSIZE: + case BLKGETSIZE64: case BLKFLSBUF: case BLKBSZSET: case BLKBSZGET: @@ -415,9 +410,7 @@ case BLKRASET: case BLKRAGET: case BLKPG: - case BLKELVGET: - case BLKELVSET: - return( blk_ioctl(inode->i_rdev, cmd, arg)); + return blk_ioctl(inode->i_rdev, cmd, arg); case CCISS_GETPCIINFO: { cciss_pci_info_struct pciinfo; @@ -459,16 +452,7 @@ // printk("cciss_ioctl: delay and count cannot be 0\n"); return( -EINVAL); } - spin_lock_irqsave(&io_request_lock, flags); - /* Can only safely update if no commands outstanding */ - if (c->commands_outstanding > 0 ) - { -// printk("cciss_ioctl: cannot change coalasing " -// "%d commands outstanding on controller\n", -// c->commands_outstanding); - spin_unlock_irqrestore(&io_request_lock, flags); - return(-EINVAL); - } + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); /* Update the field, and then ring the doorbell */ writel( intinfo.delay, &(c->cfgtable->HostWrite.CoalIntDelay)); @@ -484,7 +468,7 @@ /* delay and try again */ udelay(1000); } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); if (i >= MAX_CONFIG_WAIT) return( -EFAULT); return(0); @@ -515,7 +499,7 @@ if (copy_from_user(NodeName, (void *) arg, sizeof( NodeName_type))) return -EFAULT; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); /* Update the field, and then ring the doorbell */ for(i=0;i<16;i++) @@ -531,7 +515,7 @@ /* delay and try again */ udelay(1000); } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); if (i >= MAX_CONFIG_WAIT) return( -EFAULT); return(0); @@ -658,11 +642,11 @@ c->SG[0].Ext = 0; // we are not chaining } /* Put the request on the tail of the request queue */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); addQ(&h->reqQ, c); h->Qdepth++; start_io(h); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); /* Wait for completion */ while(c->cmd_type != CMD_IOCTL_DONE) @@ -710,42 +694,32 @@ int ctlr, target; struct gendisk *gdev; unsigned long flags; - int max_p; - int start; - int i; + int res; target = MINOR(dev) >> NWD_SHIFT; ctlr = MAJOR(dev) - MAJOR_NR; gdev = &(hba[ctlr]->gendisk); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); if (hba[ctlr]->drv[target].usage_count > maxusage) { - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); printk(KERN_WARNING "cciss: Device busy for " "revalidation (usage=%d)\n", hba[ctlr]->drv[target].usage_count); return -EBUSY; } hba[ctlr]->drv[target].usage_count++; - spin_unlock_irqrestore(&io_request_lock, flags); - - max_p = gdev->max_p; - start = target << gdev->minor_shift; + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - for(i=max_p-1; i>=0; i--) { - int minor = start+i; - invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1); - gdev->part[minor].start_sect = 0; - gdev->part[minor].nr_sects = 0; + res = wipe_partitions(dev); + if (res) + goto leave; - /* reset the blocksize so we can read the partition table */ - blksize_size[MAJOR_NR+ctlr][minor] = 1024; - } /* setup partitions per disk */ - grok_partitions(gdev, target, MAX_PART, - hba[ctlr]->drv[target].nr_blocks); + grok_partitions(dev, hba[ctlr]->drv[target].nr_blocks); +leave: hba[ctlr]->drv[target].usage_count--; - return 0; + return res; } static int frevalidate_logvol(kdev_t dev) @@ -776,15 +750,15 @@ if (MINOR(dev) != 0) return -ENXIO; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); if (hba[ctlr]->usage_count > 1) { - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); printk(KERN_WARNING "cciss: Device busy for volume" " revalidation (usage=%d)\n", hba[ctlr]->usage_count); return -EBUSY; } - spin_unlock_irqrestore(&io_request_lock, flags); hba[ctlr]->usage_count++; + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); /* * Set the partition and block size structures for all volumes @@ -793,7 +767,6 @@ memset(hba[ctlr]->hd, 0, sizeof(struct hd_struct) * 256); memset(hba[ctlr]->sizes, 0, sizeof(int) * 256); memset(hba[ctlr]->blocksizes, 0, sizeof(int) * 256); - memset(hba[ctlr]->hardsizes, 0, sizeof(int) * 256); memset(hba[ctlr]->drv, 0, sizeof(drive_info_struct) * CISS_MAX_LUN); hba[ctlr]->gendisk.nr_real = 0; @@ -1089,11 +1062,11 @@ while(( c = h->reqQ) != NULL ) { /* can't do anything if fifo is full */ - if ((h->access.fifo_full(h))) - { - printk(KERN_WARNING "cciss: fifo full \n"); - return; + if ((h->access.fifo_full(h))) { + printk(KERN_WARNING "cciss: fifo full\n"); + break; } + /* Get the frist entry from the Request Q */ removeQ(&(h->reqQ), c); h->Qdepth--; @@ -1106,18 +1079,18 @@ } } -static inline void complete_buffers( struct buffer_head *bh, int status) +static inline void complete_buffers(struct bio *bio, int status) { - struct buffer_head *xbh; - - while(bh) - { - xbh = bh->b_reqnext; - bh->b_reqnext = NULL; - blk_finished_io(bh->b_size >> 9); - bh->b_end_io(bh, status); - bh = xbh; + while (bio) { + int nsecs = bio_sectors(bio); + + struct bio *xbh = bio->bi_next; + bio->bi_next = NULL; + blk_finished_io(nsecs); + bio_endio(bio, status, nsecs); + bio = xbh; } + } /* checks the status of the job and calls complete buffers to mark all * buffers for the completed job. @@ -1135,7 +1108,7 @@ { temp64.val32.lower = cmd->SG[i].Addr.lower; temp64.val32.upper = cmd->SG[i].Addr.upper; - pci_unmap_single(hba[cmd->ctlr]->pdev, + pci_unmap_page(hba[cmd->ctlr]->pdev, temp64.val, cmd->SG[i].Len, (cmd->Request.Type.Direction == XFER_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); @@ -1214,84 +1187,39 @@ status=0; } } - complete_buffers(cmd->rq->bh, status); + + complete_buffers(cmd->rq->bio, status); #ifdef CCISS_DEBUG printk("Done with %p\n", cmd->rq); #endif /* CCISS_DEBUG */ - end_that_request_last(cmd->rq); -} - - -static inline int cpq_new_segment(request_queue_t *q, struct request *rq, - int max_segments) -{ - if (rq->nr_segments < MAXSGENTRIES) { - rq->nr_segments++; - return 1; - } - return 0; -} - -static int cpq_back_merge_fn(request_queue_t *q, struct request *rq, - struct buffer_head *bh, int max_segments) -{ - if (rq->bhtail->b_data + rq->bhtail->b_size == bh->b_data) - return 1; - return cpq_new_segment(q, rq, max_segments); -} - -static int cpq_front_merge_fn(request_queue_t *q, struct request *rq, - struct buffer_head *bh, int max_segments) -{ - if (bh->b_data + bh->b_size == rq->bh->b_data) - return 1; - return cpq_new_segment(q, rq, max_segments); -} - -static int cpq_merge_requests_fn(request_queue_t *q, struct request *rq, - struct request *nxt, int max_segments) -{ - int total_segments = rq->nr_segments + nxt->nr_segments; - - if (rq->bhtail->b_data + rq->bhtail->b_size == nxt->bh->b_data) - total_segments--; - - if (total_segments > MAXSGENTRIES) - return 0; - rq->nr_segments = total_segments; - return 1; + end_that_request_last(cmd->rq); } /* * Get a request and submit it to the controller. - * Currently we do one request at a time. Ideally we would like to send - * everything to the controller on the first call, but there is a danger - * of holding the io_request_lock for to long. */ static void do_cciss_request(request_queue_t *q) { ctlr_info_t *h= q->queuedata; CommandList_struct *c; int log_unit, start_blk, seg; - char *lastdataend; - struct buffer_head *bh; struct list_head *queue_head = &q->queue_head; struct request *creq; u64bit temp64; - struct my_sg tmp_sg[MAXSGENTRIES]; - int i; + struct scatterlist tmp_sg[MAXSGENTRIES]; + int i, dir; - if (q->plugged) + if (blk_queue_plugged(q)) goto startio; -queue_next: +queue: if (list_empty(queue_head)) goto startio; - creq = blkdev_entry_next_request(queue_head); - if (creq->nr_segments > MAXSGENTRIES) + creq = elv_next_request(q); + if (creq->nr_phys_segments > MAXSGENTRIES) BUG(); if (h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR ) @@ -1299,7 +1227,7 @@ printk(KERN_WARNING "doreq cmd for %d, %x at %p\n", h->ctlr, creq->rq_dev, creq); blkdev_dequeue_request(creq); - complete_buffers(creq->bh, 0); + complete_buffers(creq->bio, 0); end_that_request_last(creq); goto startio; } @@ -1309,10 +1237,9 @@ blkdev_dequeue_request(creq); - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(q->queue_lock); - c->cmd_type = CMD_RWREQ; - bh = creq->bh; + c->cmd_type = CMD_RWREQ; c->rq = creq; /* fill in the request */ @@ -1325,44 +1252,29 @@ c->Request.Type.Type = TYPE_CMD; // It is a command. c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = - (creq->cmd == READ) ? XFER_READ: XFER_WRITE; + (rq_data_dir(creq) == READ) ? XFER_READ: XFER_WRITE; c->Request.Timeout = 0; // Don't time out - c->Request.CDB[0] = (creq->cmd == READ) ? CCISS_READ : CCISS_WRITE; - start_blk = hba[h->ctlr]->hd[MINOR(creq->rq_dev)].start_sect + creq->sector; + c->Request.CDB[0] = (rq_data_dir(creq) == READ) ? CCISS_READ : CCISS_WRITE; + start_blk = creq->sector; #ifdef CCISS_DEBUG - if (bh == NULL) - panic("cciss: bh== NULL?"); printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n",(int) creq->sector, (int) creq->nr_sectors); #endif /* CCISS_DEBUG */ - seg = 0; - lastdataend = NULL; - while(bh) - { - if (bh->b_data == lastdataend) - { // tack it on to the last segment - tmp_sg[seg-1].len +=bh->b_size; - lastdataend += bh->b_size; - } else - { - if (seg == MAXSGENTRIES) - BUG(); - tmp_sg[seg].len = bh->b_size; - tmp_sg[seg].start_addr = bh->b_data; - lastdataend = bh->b_data + bh->b_size; - seg++; - } - bh = bh->b_reqnext; - } + + seg = blk_rq_map_sg(q, creq, tmp_sg); + /* get the DMA records for the setup */ + if (c->Request.Type.Direction == XFER_READ) + dir = PCI_DMA_FROMDEVICE; + else + dir = PCI_DMA_TODEVICE; + for (i=0; iSG[i].Len = tmp_sg[i].len; - temp64.val = (__u64) pci_map_single( h->pdev, - tmp_sg[i].start_addr, - tmp_sg[i].len, - (c->Request.Type.Direction == XFER_READ) ? - PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); + c->SG[i].Len = tmp_sg[i].length; + temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page, + tmp_sg[i].offset, tmp_sg[i].length, + dir); c->SG[i].Addr.lower = temp64.val32.lower; c->SG[i].Addr.upper = temp64.val32.upper; c->SG[i].Ext = 0; // we are not chaining @@ -1386,14 +1298,14 @@ c->Request.CDB[8]= creq->nr_sectors & 0xff; c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; - spin_lock_irq(&io_request_lock); + spin_lock_irq(q->queue_lock); addQ(&(h->reqQ),c); h->Qdepth++; if(h->Qdepth > h->maxQsinceinit) h->maxQsinceinit = h->Qdepth; - goto queue_next; + goto queue; startio: start_io(h); } @@ -1414,7 +1326,7 @@ * If there are completed commands in the completion queue, * we had better do something about it. */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); while( h->access.intr_pending(h)) { while((a = h->access.command_completed(h)) != FIFO_EMPTY) @@ -1447,11 +1359,12 @@ } } } + /* * See if we can queue up some more IO */ do_cciss_request(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr)); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); } /* * We cannot read the structure directly, for portablity we must use @@ -1873,7 +1786,18 @@ sprintf(hba[i]->devname, "cciss%d", i); hba[i]->ctlr = i; hba[i]->pdev = pdev; - + + /* configure PCI DMA stuff */ + if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) + printk("cciss: using DAC cycles\n"); + else if (!pci_set_dma_mask(pdev, 0xffffffff)) + printk("cciss: not using DAC cycles\n"); + else { + printk("cciss: no suitable DMA available\n"); + free_hba(i); + return -ENODEV; + } + if( register_blkdev(MAJOR_NR+i, hba[i]->devname, &cciss_fops)) { printk(KERN_ERR "cciss: Unable to get major number " @@ -1942,20 +1866,22 @@ q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); q->queuedata = hba[i]; - blk_init_queue(q, do_cciss_request); - blk_queue_headactive(q, 0); + spin_lock_init(&hba[i]->lock); + blk_init_queue(q, do_cciss_request, &hba[i]->lock); + blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); + + /* This is a hardware imposed limit. */ + blk_queue_max_hw_segments(q, MAXSGENTRIES); + + /* This is a limit in the driver and could be eliminated. */ + blk_queue_max_phys_segments(q, MAXSGENTRIES); + + blk_queue_max_sectors(q, 512); /* fill in the other Kernel structs */ blksize_size[MAJOR_NR+i] = hba[i]->blocksizes; - hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes; read_ahead[MAJOR_NR+i] = READ_AHEAD; - /* Set the pointers to queue functions */ - q->back_merge_fn = cpq_back_merge_fn; - q->front_merge_fn = cpq_front_merge_fn; - q->merge_requests_fn = cpq_merge_requests_fn; - - /* Fill in the gendisk data */ hba[i]->gendisk.major = MAJOR_NR + i; hba[i]->gendisk.major_name = "cciss"; @@ -2004,12 +1930,11 @@ unregister_blkdev(MAJOR_NR+i, hba[i]->devname); remove_proc_entry(hba[i]->devname, proc_cciss); - /* remove it from the disk list */ del_gendisk(&(hba[i]->gendisk)); - pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), - hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); + pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), + hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct), hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); kfree(hba[i]->cmd_pool_bits); @@ -2017,32 +1942,31 @@ } static struct pci_driver cciss_pci_driver = { - name: "cciss", - probe: cciss_init_one, - remove: cciss_remove_one, - id_table: cciss_pci_device_id, /* id_table */ + name: "cciss", + probe: cciss_init_one, + remove: cciss_remove_one, + id_table: cciss_pci_device_id, /* id_table */ }; /* -* This is it. Register the PCI driver information for the cards we control -* the OS will call our registered routines when it finds one of our cards. -*/ + * This is it. Register the PCI driver information for the cards we control + * the OS will call our registered routines when it finds one of our cards. + */ int __init cciss_init(void) { - printk(KERN_INFO DRIVER_NAME "\n"); + /* Register for out PCI devices */ if (pci_register_driver(&cciss_pci_driver) > 0 ) return 0; else return -ENODEV; - } +} EXPORT_NO_SYMBOLS; static int __init init_cciss_module(void) { - return ( cciss_init()); } diff -u --recursive --new-file v2.5.0/linux/drivers/block/cciss.h linux/drivers/block/cciss.h --- v2.5.0/linux/drivers/block/cciss.h Tue May 22 10:23:16 2001 +++ linux/drivers/block/cciss.h Wed Dec 12 13:41:03 2001 @@ -15,11 +15,6 @@ #define MAJOR_NR COMPAQ_CISS_MAJOR -struct my_sg { - int len; - char *start_addr; -}; - struct ctlr_info; typedef struct ctlr_info ctlr_info_t; @@ -71,6 +66,7 @@ unsigned int Qdepth; unsigned int maxQsinceinit; unsigned int maxSG; + spinlock_t lock; //* pointers to command and error info pool */ CommandList_struct *cmd_pool; @@ -85,9 +81,8 @@ struct gendisk gendisk; // indexed by minor numbers struct hd_struct hd[256]; - int sizes[256]; + int sizes[256]; int blocksizes[256]; - int hardsizes[256]; }; /* Defining the diffent access_menthods */ @@ -247,5 +242,8 @@ char *product_name; struct access_method *access; }; + +#define CCISS_LOCK(i) ((BLK_DEFAULT_QUEUE(MAJOR_NR + i))->queue_lock) + #endif /* CCISS_H */ diff -u --recursive --new-file v2.5.0/linux/drivers/block/cciss_cmd.h linux/drivers/block/cciss_cmd.h --- v2.5.0/linux/drivers/block/cciss_cmd.h Fri Nov 2 17:45:42 2001 +++ linux/drivers/block/cciss_cmd.h Tue Nov 27 09:23:27 2001 @@ -7,7 +7,7 @@ //general boundary defintions #define SENSEINFOBYTES 32//note that this value may vary between host implementations -#define MAXSGENTRIES 31 +#define MAXSGENTRIES 32 #define MAXREPLYQS 256 //Command Status value diff -u --recursive --new-file v2.5.0/linux/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c --- v2.5.0/linux/drivers/block/cpqarray.c Fri Nov 9 14:28:46 2001 +++ linux/drivers/block/cpqarray.c Sun Dec 16 12:20:20 2001 @@ -100,7 +100,6 @@ static struct hd_struct * ida; static int * ida_sizes; static int * ida_blocksizes; -static int * ida_hardsizes; static struct gendisk ida_gendisk[MAX_CTLR]; static struct proc_dir_entry *proc_array; @@ -145,7 +144,7 @@ static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c); static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c); -static inline void complete_buffers(struct buffer_head *bh, int ok); +static inline void complete_buffers(struct bio *bio, int ok); static inline void complete_command(cmdlist_t *cmd, int timeout); static void do_ida_intr(int irq, void *dev_id, struct pt_regs * regs); @@ -176,12 +175,11 @@ ida_sizes[(ctlr<nr_blks; - for(j=0; j<16; j++) { + for(j=0; j<16; j++) ida_blocksizes[(ctlr<blk_size; - } + + (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->blk_size; ida_gendisk[ctlr].nr_real++; } @@ -341,52 +339,10 @@ remove_proc_entry("cpqarray", proc_root_driver); kfree(ida); kfree(ida_sizes); - kfree(ida_hardsizes); kfree(ida_blocksizes); } #endif /* MODULE */ -static inline int cpq_new_segment(request_queue_t *q, struct request *rq, - int max_segments) -{ - if (rq->nr_segments < SG_MAX) { - rq->nr_segments++; - return 1; - } - return 0; -} - -static int cpq_back_merge_fn(request_queue_t *q, struct request *rq, - struct buffer_head *bh, int max_segments) -{ - if (rq->bhtail->b_data + rq->bhtail->b_size == bh->b_data) - return 1; - return cpq_new_segment(q, rq, max_segments); -} - -static int cpq_front_merge_fn(request_queue_t *q, struct request *rq, - struct buffer_head *bh, int max_segments) -{ - if (bh->b_data + bh->b_size == rq->bh->b_data) - return 1; - return cpq_new_segment(q, rq, max_segments); -} - -static int cpq_merge_requests_fn(request_queue_t *q, struct request *rq, - struct request *nxt, int max_segments) -{ - int total_segments = rq->nr_segments + nxt->nr_segments; - - if (rq->bhtail->b_data + rq->bhtail->b_size == nxt->bh->b_data) - total_segments--; - - if (total_segments > SG_MAX) - return 0; - - rq->nr_segments = total_segments; - return 1; -} - /* * This is it. Find all the controllers and register them. I really hate * stealing all these major device numbers. @@ -433,20 +389,9 @@ return(num_cntlrs_reg); } - ida_hardsizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL); - if(ida_hardsizes==NULL) - { - kfree(ida); - kfree(ida_sizes); - kfree(ida_blocksizes); - printk( KERN_ERR "cpqarray: out of memory"); - return(num_cntlrs_reg); - } - memset(ida, 0, sizeof(struct hd_struct)*nr_ctlr*NWD*16); memset(ida_sizes, 0, sizeof(int)*nr_ctlr*NWD*16); memset(ida_blocksizes, 0, sizeof(int)*nr_ctlr*NWD*16); - memset(ida_hardsizes, 0, sizeof(int)*nr_ctlr*NWD*16); memset(ida_gendisk, 0, sizeof(struct gendisk)*MAX_CTLR); /* @@ -504,7 +449,6 @@ { kfree(ida); kfree(ida_sizes); - kfree(ida_hardsizes); kfree(ida_blocksizes); } return(num_cntlrs_reg); @@ -523,16 +467,19 @@ q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); q->queuedata = hba[i]; - blk_init_queue(q, do_ida_request); - blk_queue_headactive(q, 0); + spin_lock_init(&hba[i]->lock); + blk_init_queue(q, do_ida_request, &hba[i]->lock); + blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask); + + /* This is a hardware imposed limit. */ + blk_queue_max_hw_segments(q, SG_MAX); + + /* This is a driver limit and could be eliminated. */ + blk_queue_max_phys_segments(q, SG_MAX); + blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256); - hardsect_size[MAJOR_NR+i] = ida_hardsizes + (i*256); read_ahead[MAJOR_NR+i] = READ_AHEAD; - q->back_merge_fn = cpq_back_merge_fn; - q->front_merge_fn = cpq_front_merge_fn; - q->merge_requests_fn = cpq_merge_requests_fn; - ida_gendisk[i].major = MAJOR_NR + i; ida_gendisk[i].major_name = "ida"; ida_gendisk[i].minor_shift = NWD_SHIFT; @@ -911,22 +858,20 @@ { ctlr_info_t *h = q->queuedata; cmdlist_t *c; - char *lastdataend; struct list_head * queue_head = &q->queue_head; - struct buffer_head *bh; struct request *creq; - struct my_sg tmp_sg[SG_MAX]; - int i, seg; + struct scatterlist tmp_sg[SG_MAX]; + int i, dir, seg; - if (q->plugged) + if (blk_queue_plugged(q)) goto startio; queue_next: if (list_empty(queue_head)) goto startio; - creq = blkdev_entry_next_request(queue_head); - if (creq->nr_segments > SG_MAX) + creq = elv_next_request(q); + if (creq->nr_phys_segments > SG_MAX) BUG(); if (h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR || h->ctlr > nr_ctlr) @@ -934,7 +879,7 @@ printk(KERN_WARNING "doreq cmd for %d, %x at %p\n", h->ctlr, creq->rq_dev, creq); blkdev_dequeue_request(creq); - complete_buffers(creq->bh, 0); + complete_buffers(creq->bio, 0); end_that_request_last(creq); goto startio; } @@ -944,55 +889,40 @@ blkdev_dequeue_request(creq); - spin_unlock_irq(&io_request_lock); - - bh = creq->bh; + spin_unlock_irq(q->queue_lock); c->ctlr = h->ctlr; c->hdr.unit = MINOR(creq->rq_dev) >> NWD_SHIFT; c->hdr.size = sizeof(rblk_t) >> 2; c->size += sizeof(rblk_t); - c->req.hdr.blk = ida[(h->ctlr<rq_dev)].start_sect + creq->sector; + c->req.hdr.blk = creq->sector; c->rq = creq; DBGPX( - if (bh == NULL) - panic("bh == NULL?"); - printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors); ); - seg = 0; lastdataend = NULL; - while(bh) { - if (bh->b_data == lastdataend) { - tmp_sg[seg-1].size += bh->b_size; - lastdataend += bh->b_size; - } else { - if (seg == SG_MAX) - BUG(); - tmp_sg[seg].size = bh->b_size; - tmp_sg[seg].start_addr = bh->b_data; - lastdataend = bh->b_data + bh->b_size; - seg++; - } - bh = bh->b_reqnext; - } + seg = blk_rq_map_sg(q, creq, tmp_sg); + /* Now do all the DMA Mappings */ + if (rq_data_dir(creq) == READ) + dir = PCI_DMA_FROMDEVICE; + else + dir = PCI_DMA_TODEVICE; for( i=0; i < seg; i++) { - c->req.sg[i].size = tmp_sg[i].size; - c->req.sg[i].addr = (__u32) pci_map_single( - h->pci_dev, tmp_sg[i].start_addr, - tmp_sg[i].size, - (creq->cmd == READ) ? - PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); + c->req.sg[i].size = tmp_sg[i].length; + c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev, + tmp_sg[i].page, + tmp_sg[i].offset, + tmp_sg[i].length, dir); } -DBGPX( printk("Submitting %d sectors in %d segments\n", sect, seg); ); +DBGPX( printk("Submitting %d sectors in %d segments\n", creq->nr_sectors, seg); ); c->req.hdr.sg_cnt = seg; c->req.hdr.blk_cnt = creq->nr_sectors; - c->req.hdr.cmd = (creq->cmd == READ) ? IDA_READ : IDA_WRITE; + c->req.hdr.cmd = (rq_data_dir(creq) == READ) ? IDA_READ : IDA_WRITE; c->type = CMD_RWREQ; - spin_lock_irq(&io_request_lock); + spin_lock_irq(q->queue_lock); /* Put the request on the tail of the request queue */ addQ(&h->reqQ, c); @@ -1033,17 +963,19 @@ } } -static inline void complete_buffers(struct buffer_head *bh, int ok) +static inline void complete_buffers(struct bio *bio, int ok) { - struct buffer_head *xbh; - while(bh) { - xbh = bh->b_reqnext; - bh->b_reqnext = NULL; + struct bio *xbh; + while(bio) { + int nsecs = bio_sectors(bio); + + xbh = bio->bi_next; + bio->bi_next = NULL; - blk_finished_io(bh->b_size >> 9); - bh->b_end_io(bh, ok); + blk_finished_io(nsecs); + bio_endio(bio, ok, nsecs); - bh = xbh; + bio = xbh; } } /* @@ -1052,7 +984,7 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) { int ok=1; - int i; + int i, ddir; if (cmd->req.hdr.rcode & RCODE_NONFATAL && (hba[cmd->ctlr]->misc_tflags & MISC_NONFATAL_WARN) == 0) { @@ -1074,19 +1006,18 @@ } if (timeout) ok = 0; /* unmap the DMA mapping for all the scatter gather elements */ + if (cmd->req.hdr.cmd == IDA_READ) + ddir = PCI_DMA_FROMDEVICE; + else + ddir = PCI_DMA_TODEVICE; for(i=0; ireq.hdr.sg_cnt; i++) - { - pci_unmap_single(hba[cmd->ctlr]->pci_dev, - cmd->req.sg[i].addr, cmd->req.sg[i].size, - (cmd->req.hdr.cmd == IDA_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); - } + pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, + cmd->req.sg[i].size, ddir); - complete_buffers(cmd->rq->bh, ok); + complete_buffers(cmd->rq->bio, ok); - DBGPX(printk("Done with %p\n", cmd->rq);); + DBGPX(printk("Done with %p\n", cmd->rq);); end_that_request_last(cmd->rq); - - } /* @@ -1111,7 +1042,7 @@ * If there are completed commands in the completion queue, * we had better do something about it. */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); if (istat & FIFO_NOT_EMPTY) { while((a = h->access.command_completed(h))) { a1 = a; a &= ~3; @@ -1155,7 +1086,7 @@ * See if we can queue up some more IO */ do_ida_request(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr)); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); } /* @@ -1201,14 +1132,10 @@ put_user(diskinfo[0], &geo->heads); put_user(diskinfo[1], &geo->sectors); put_user(diskinfo[2], &geo->cylinders); - put_user(ida[(ctlr<i_rdev)].start_sect, &geo->start); + put_user(get_start_sect(inode->i_rdev), &geo->start); return 0; case IDAGETDRVINFO: return copy_to_user(&io->c.drv,&hba[ctlr]->drv[dsk],sizeof(drv_info_t)); - case BLKGETSIZE: - return put_user(ida[(ctlr<i_rdev)].nr_sects, (unsigned long *)arg); - case BLKGETSIZE64: - return put_user((u64)(ida[(ctlr<i_rdev)].nr_sects) << 9, (u64*)arg); case BLKRRPART: return revalidate_logvol(inode->i_rdev, 1); case IDAPASSTHRU: @@ -1244,6 +1171,8 @@ return(0); } + case BLKGETSIZE: + case BLKGETSIZE64: case BLKFLSBUF: case BLKBSZSET: case BLKBSZGET: @@ -1251,8 +1180,6 @@ case BLKROGET: case BLKRASET: case BLKRAGET: - case BLKELVGET: - case BLKELVSET: case BLKPG: return blk_ioctl(inode->i_rdev, cmd, arg); @@ -1352,11 +1279,11 @@ } /* Put the request on the tail of the request queue */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(IDA_LOCK(ctlr), flags); addQ(&h->reqQ, c); h->Qdepth++; start_io(h); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(IDA_LOCK(ctlr), flags); /* Wait for completion */ while(c->type != CMD_IOCTL_DONE) @@ -1570,15 +1497,15 @@ if (MINOR(dev) != 0) return -ENXIO; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(IDA_LOCK(ctlr), flags); if (hba[ctlr]->usage_count > 1) { - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(IDA_LOCK(ctlr), flags); printk(KERN_WARNING "cpqarray: Device busy for volume" " revalidation (usage=%d)\n", hba[ctlr]->usage_count); return -EBUSY; } - spin_unlock_irqrestore(&io_request_lock, flags); hba[ctlr]->usage_count++; + spin_unlock_irqrestore(IDA_LOCK(ctlr), flags); /* * Set the partition and block size structures for all volumes @@ -1587,7 +1514,6 @@ memset(ida+(ctlr*256), 0, sizeof(struct hd_struct)*NWD*16); memset(ida_sizes+(ctlr*256), 0, sizeof(int)*NWD*16); memset(ida_blocksizes+(ctlr*256), 0, sizeof(int)*NWD*16); - memset(ida_hardsizes+(ctlr*256), 0, sizeof(int)*NWD*16); memset(hba[ctlr]->drv, 0, sizeof(drv_info_t)*NWD); ida_gendisk[ctlr].nr_real = 0; @@ -1615,17 +1541,15 @@ int ctlr, target; struct gendisk *gdev; unsigned long flags; - int max_p; - int start; - int i; + int res; target = DEVICE_NR(dev); ctlr = MAJOR(dev) - MAJOR_NR; gdev = &ida_gendisk[ctlr]; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(IDA_LOCK(ctlr), flags); if (hba[ctlr]->drv[target].usage_count > maxusage) { - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(IDA_LOCK(ctlr), flags); printk(KERN_WARNING "cpqarray: Device busy for " "revalidation (usage=%d)\n", hba[ctlr]->drv[target].usage_count); @@ -1633,25 +1557,14 @@ } hba[ctlr]->drv[target].usage_count++; - spin_unlock_irqrestore(&io_request_lock, flags); - - max_p = gdev->max_p; - start = target << gdev->minor_shift; + spin_unlock_irqrestore(IDA_LOCK(ctlr), flags); - for(i=max_p-1; i>=0; i--) { - int minor = start+i; - invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1); - gdev->part[minor].start_sect = 0; - gdev->part[minor].nr_sects = 0; + res = wipe_partitions(dev); + if (!res) + grok_partitions(dev, hba[ctlr]->drv[target].nr_blks); - /* reset the blocksize so we can read the partition table */ - blksize_size[MAJOR_NR+ctlr][minor] = 1024; - } - - /* 16 minors per disk... */ - grok_partitions(gdev, target, 16, hba[ctlr]->drv[target].nr_blks); hba[ctlr]->drv[target].usage_count--; - return 0; + return res; } diff -u --recursive --new-file v2.5.0/linux/drivers/block/cpqarray.h linux/drivers/block/cpqarray.h --- v2.5.0/linux/drivers/block/cpqarray.h Tue May 22 10:23:16 2001 +++ linux/drivers/block/cpqarray.h Wed Dec 12 13:41:03 2001 @@ -56,11 +56,6 @@ #ifdef __KERNEL__ -struct my_sg { - int size; - char *start_addr; -}; - struct ctlr_info; typedef struct ctlr_info ctlr_info_t; @@ -111,6 +106,7 @@ cmdlist_t *cmd_pool; dma_addr_t cmd_pool_dhandle; __u32 *cmd_pool_bits; + spinlock_t lock; unsigned int Qdepth; unsigned int maxQsinceinit; @@ -121,6 +117,9 @@ struct timer_list timer; unsigned int misc_tflags; }; + +#define IDA_LOCK(i) ((BLK_DEFAULT_QUEUE(MAJOR_NR + i))->queue_lock) + #endif #endif /* CPQARRAY_H */ diff -u --recursive --new-file v2.5.0/linux/drivers/block/elevator.c linux/drivers/block/elevator.c --- v2.5.0/linux/drivers/block/elevator.c Thu Jul 19 20:59:41 2001 +++ linux/drivers/block/elevator.c Fri Dec 7 16:32:26 2001 @@ -18,48 +18,70 @@ * Removed tests for max-bomb-segments, which was breaking elvtune * when run without -bN * + * Jens: + * - Rework again to work with bio instead of buffer_heads + * - loose bi_dev comparisons, partition handling is right now + * - completely modularize elevator setup and teardown + * */ - +#include #include #include #include #include +#include #include +#include +#include +#include + #include /* - * This is a bit tricky. It's given that bh and rq are for the same + * This is a bit tricky. It's given that bio and rq are for the same * device, but the next request might of course not be. Run through * the tests below to check if we want to insert here if we can't merge - * bh into an existing request + * bio into an existing request */ -inline int bh_rq_in_between(struct buffer_head *bh, struct request *rq, - struct list_head *head) +inline int bio_rq_in_between(struct bio *bio, struct request *rq, + struct list_head *head) { struct list_head *next; struct request *next_rq; - next = rq->queue.next; + /* + * if .next is a valid request + */ + next = rq->queuelist.next; if (next == head) return 0; + next_rq = list_entry(next, struct request, queuelist); + + BUG_ON(next_rq->flags & REQ_STARTED); + + /* + * not a sector based request + */ + if (!(next_rq->flags & REQ_CMD)) + return 0; + /* - * if the device is different (usually on a different partition), - * just check if bh is after rq + * if the device is different (not a normal case) just check if + * bio is after rq */ - next_rq = blkdev_entry_to_request(next); if (next_rq->rq_dev != rq->rq_dev) - return bh->b_rsector > rq->sector; + return bio->bi_sector > rq->sector; /* - * ok, rq, next_rq and bh are on the same device. if bh is in between + * ok, rq, next_rq and bio are on the same device. if bio is in between * the two, this is the sweet spot */ - if (bh->b_rsector < next_rq->sector && bh->b_rsector > rq->sector) + if (bio->bi_sector < next_rq->sector && bio->bi_sector > rq->sector) return 1; /* - * next_rq is ordered wrt rq, but bh is not in between the two + * next_rq is ordered wrt rq, but bio is not in between the two */ if (next_rq->sector > rq->sector) return 0; @@ -68,47 +90,77 @@ * next_rq and rq not ordered, if we happen to be either before * next_rq or after rq insert here anyway */ - if (bh->b_rsector > rq->sector || bh->b_rsector < next_rq->sector) + if (bio->bi_sector > rq->sector || bio->bi_sector < next_rq->sector) return 1; return 0; } +/* + * can we safely merge with this request? + */ +inline int elv_rq_merge_ok(struct request *rq, struct bio *bio) +{ + if (!(rq->flags & REQ_CMD)) + return 0; + + /* + * different data direction or already started, don't merge + */ + if (bio_data_dir(bio) != rq_data_dir(rq)) + return 0; + if (rq->flags & REQ_NOMERGE) + return 0; + + /* + * same device and no special stuff set, merge is ok + */ + if (rq->rq_dev == bio->bi_dev && !rq->waiting && !rq->special) + return 1; + + return 0; +} int elevator_linus_merge(request_queue_t *q, struct request **req, - struct list_head * head, - struct buffer_head *bh, int rw, - int max_sectors) + struct list_head *head, struct bio *bio) { + unsigned int count = bio_sectors(bio); struct list_head *entry = &q->queue_head; - unsigned int count = bh->b_size >> 9, ret = ELEVATOR_NO_MERGE; + int ret = ELEVATOR_NO_MERGE; + struct request *__rq; + entry = &q->queue_head; while ((entry = entry->prev) != head) { - struct request *__rq = blkdev_entry_to_request(entry); + __rq = list_entry_rq(entry); + + prefetch(list_entry_rq(entry->prev)); /* * simply "aging" of requests in queue */ if (__rq->elevator_sequence-- <= 0) break; - - if (__rq->waiting) - continue; - if (__rq->rq_dev != bh->b_rdev) + if (__rq->flags & (REQ_BARRIER | REQ_STARTED)) + break; + if (!(__rq->flags & REQ_CMD)) continue; - if (!*req && bh_rq_in_between(bh, __rq, &q->queue_head)) + + if (!*req && bio_rq_in_between(bio, __rq, &q->queue_head)) *req = __rq; - if (__rq->cmd != rw) - continue; - if (__rq->nr_sectors + count > max_sectors) + if (!elv_rq_merge_ok(__rq, bio)) continue; + if (__rq->elevator_sequence < count) break; - if (__rq->sector + __rq->nr_sectors == bh->b_rsector) { + + /* + * we can merge and sequence is ok, check if it's possible + */ + if (__rq->sector + __rq->nr_sectors == bio->bi_sector) { ret = ELEVATOR_BACK_MERGE; *req = __rq; break; - } else if (__rq->sector - count == bh->b_rsector) { + } else if (__rq->sector - count == bio->bi_sector) { ret = ELEVATOR_FRONT_MERGE; __rq->elevator_sequence -= count; *req = __rq; @@ -121,13 +173,18 @@ void elevator_linus_merge_cleanup(request_queue_t *q, struct request *req, int count) { - struct list_head *entry = &req->queue, *head = &q->queue_head; + struct list_head *entry; + + BUG_ON(req->q != q); /* * second pass scan of requests that got passed over, if any */ - while ((entry = entry->next) != head) { - struct request *tmp = blkdev_entry_to_request(entry); + entry = &req->queuelist; + while ((entry = entry->next) != &q->queue_head) { + struct request *tmp; + prefetch(list_entry_rq(entry->next)); + tmp = list_entry_rq(entry); tmp->elevator_sequence -= count; } } @@ -138,42 +195,66 @@ req->elevator_sequence = next->elevator_sequence; } +void elv_add_request_fn(request_queue_t *q, struct request *rq, + struct list_head *insert_here) +{ + list_add(&rq->queuelist, insert_here); +} + +struct request *elv_next_request_fn(request_queue_t *q) +{ + if (!blk_queue_empty(q)) + return list_entry(q->queue_head.next, struct request, queuelist); + + return NULL; +} + +int elv_linus_init(request_queue_t *q, elevator_t *e) +{ + return 0; +} + +void elv_linus_exit(request_queue_t *q, elevator_t *e) +{ +} + /* * See if we can find a request that this buffer can be coalesced with. */ int elevator_noop_merge(request_queue_t *q, struct request **req, - struct list_head * head, - struct buffer_head *bh, int rw, - int max_sectors) + struct list_head *head, struct bio *bio) { - struct list_head *entry; - unsigned int count = bh->b_size >> 9; - - if (list_empty(&q->queue_head)) - return ELEVATOR_NO_MERGE; + unsigned int count = bio_sectors(bio); + struct list_head *entry = &q->queue_head; + struct request *__rq; entry = &q->queue_head; while ((entry = entry->prev) != head) { - struct request *__rq = blkdev_entry_to_request(entry); + __rq = list_entry_rq(entry); - if (__rq->cmd != rw) - continue; - if (__rq->rq_dev != bh->b_rdev) - continue; - if (__rq->nr_sectors + count > max_sectors) + prefetch(list_entry_rq(entry->prev)); + + if (__rq->flags & (REQ_BARRIER | REQ_STARTED)) + break; + + if (!(__rq->flags & REQ_CMD)) continue; - if (__rq->waiting) + + if (!elv_rq_merge_ok(__rq, bio)) continue; - if (__rq->sector + __rq->nr_sectors == bh->b_rsector) { + + /* + * we can merge and sequence is ok, check if it's possible + */ + if (__rq->sector + __rq->nr_sectors == bio->bi_sector) { *req = __rq; return ELEVATOR_BACK_MERGE; - } else if (__rq->sector - count == bh->b_rsector) { + } else if (__rq->sector - count == bio->bi_sector) { *req = __rq; return ELEVATOR_FRONT_MERGE; } } - *req = blkdev_entry_to_request(q->queue_head.prev); return ELEVATOR_NO_MERGE; } @@ -181,42 +262,27 @@ void elevator_noop_merge_req(struct request *req, struct request *next) {} -int blkelvget_ioctl(elevator_t * elevator, blkelv_ioctl_arg_t * arg) +int elevator_init(request_queue_t *q, elevator_t *e, elevator_t type) { - blkelv_ioctl_arg_t output; + *e = type; - output.queue_ID = elevator->queue_ID; - output.read_latency = elevator->read_latency; - output.write_latency = elevator->write_latency; - output.max_bomb_segments = 0; + INIT_LIST_HEAD(&q->queue_head); - if (copy_to_user(arg, &output, sizeof(blkelv_ioctl_arg_t))) - return -EFAULT; + if (e->elevator_init_fn) + return e->elevator_init_fn(q, e); return 0; } -int blkelvset_ioctl(elevator_t * elevator, const blkelv_ioctl_arg_t * arg) +void elevator_exit(request_queue_t *q, elevator_t *e) { - blkelv_ioctl_arg_t input; - - if (copy_from_user(&input, arg, sizeof(blkelv_ioctl_arg_t))) - return -EFAULT; - - if (input.read_latency < 0) - return -EINVAL; - if (input.write_latency < 0) - return -EINVAL; - - elevator->read_latency = input.read_latency; - elevator->write_latency = input.write_latency; - return 0; + if (e->elevator_exit_fn) + e->elevator_exit_fn(q, e); } -void elevator_init(elevator_t * elevator, elevator_t type) +int elevator_global_init(void) { - static unsigned int queue_ID; - - *elevator = type; - elevator->queue_ID = queue_ID++; + return 0; } + +module_init(elevator_global_init); diff -u --recursive --new-file v2.5.0/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v2.5.0/linux/drivers/block/floppy.c Thu Oct 25 13:58:34 2001 +++ linux/drivers/block/floppy.c Sun Dec 16 12:23:05 2001 @@ -204,6 +204,8 @@ * record each buffers capabilities */ +static spinlock_t floppy_lock = SPIN_LOCK_UNLOCKED; + static unsigned short virtual_dma_port=0x3f0; void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs); static int set_dor(int fdc, char mask, char data); @@ -576,7 +578,7 @@ static struct floppy_struct *_floppy = floppy_type; static unsigned char current_drive; static long current_count_sectors; -static unsigned char sector_t; /* sector in track */ +static unsigned char fsector_t; /* sector in track */ static unsigned char in_sector_offset; /* offset within physical sector, * expressed in units of 512 bytes */ @@ -2276,8 +2278,8 @@ * logical buffer */ static void request_done(int uptodate) { - int block; unsigned long flags; + int block; probing = 0; reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate); @@ -2296,7 +2298,7 @@ DRS->maxtrack = 1; /* unlock chained buffers */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(QUEUE->queue_lock, flags); while (current_count_sectors && !QUEUE_EMPTY && current_count_sectors >= CURRENT->current_nr_sectors){ current_count_sectors -= CURRENT->current_nr_sectors; @@ -2304,7 +2306,7 @@ CURRENT->sector += CURRENT->current_nr_sectors; end_request(1); } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(QUEUE->queue_lock, flags); if (current_count_sectors && !QUEUE_EMPTY){ /* "unlock" last subsector */ @@ -2319,7 +2321,7 @@ DPRINT("request list destroyed in floppy request done\n"); } else { - if (CURRENT->cmd == WRITE) { + if (rq_data_dir(CURRENT) == WRITE) { /* record write error information */ DRWE->write_errors++; if (DRWE->write_errors == 1) { @@ -2329,9 +2331,9 @@ DRWE->last_error_sector = CURRENT->sector; DRWE->last_error_generation = DRS->generation; } - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(QUEUE->queue_lock, flags); end_request(0); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(QUEUE->queue_lock, flags); } } @@ -2377,7 +2379,7 @@ printk("rt=%d t=%d\n", R_TRACK, TRACK); printk("heads=%d eoc=%d\n", heads, eoc); printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK, - sector_t, ssize); + fsector_t, ssize); printk("in_sector_offset=%d\n", in_sector_offset); } #endif @@ -2424,7 +2426,7 @@ } else if (CT(COMMAND) == FD_READ){ buffer_track = raw_cmd->track; buffer_drive = current_drive; - INFBOUND(buffer_max, nr_sectors + sector_t); + INFBOUND(buffer_max, nr_sectors + fsector_t); } cont->redo(); } @@ -2432,34 +2434,36 @@ /* Compute maximal contiguous buffer size. */ static int buffer_chain_size(void) { - struct buffer_head *bh; - int size; + struct bio *bio; + struct bio_vec *bv; + int size, i; char *base; - base = CURRENT->buffer; - size = CURRENT->current_nr_sectors << 9; - bh = CURRENT->bh; + base = bio_data(CURRENT->bio); + size = 0; + + rq_for_each_bio(bio, CURRENT) { + bio_for_each_segment(bv, bio, i) { + if (page_address(bv->bv_page) + bv->bv_offset != base + size) + break; - if (bh){ - bh = bh->b_reqnext; - while (bh && bh->b_data == base + size){ - size += bh->b_size; - bh = bh->b_reqnext; + size += bv->bv_len; } } + return size >> 9; } /* Compute the maximal transfer size */ static int transfer_size(int ssize, int max_sector, int max_size) { - SUPBOUND(max_sector, sector_t + max_size); + SUPBOUND(max_sector, fsector_t + max_size); /* alignment */ max_sector -= (max_sector % _floppy->sect) % ssize; /* transfer size, beginning not aligned */ - current_count_sectors = max_sector - sector_t ; + current_count_sectors = max_sector - fsector_t ; return max_sector; } @@ -2470,17 +2474,18 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) { int remaining; /* number of transferred 512-byte sectors */ - struct buffer_head *bh; + struct bio_vec *bv; + struct bio *bio; char *buffer, *dma_buffer; - int size; + int size, i; max_sector = transfer_size(ssize, minimum(max_sector, max_sector_2), CURRENT->nr_sectors); if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE && - buffer_max > sector_t + CURRENT->nr_sectors) - current_count_sectors = minimum(buffer_max - sector_t, + buffer_max > fsector_t + CURRENT->nr_sectors) + current_count_sectors = minimum(buffer_max - fsector_t, CURRENT->nr_sectors); remaining = current_count_sectors << 9; @@ -2491,7 +2496,7 @@ printk("current_count_sectors=%ld\n", current_count_sectors); printk("remaining=%d\n", remaining >> 9); printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors); - printk("CURRENT->current_nr_sectors=%ld\n", + printk("CURRENT->current_nr_sectors=%u\n", CURRENT->current_nr_sectors); printk("max_sector=%d\n", max_sector); printk("ssize=%d\n", ssize); @@ -2500,22 +2505,27 @@ buffer_max = maximum(max_sector, buffer_max); - dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9); + dma_buffer = floppy_track_buffer + ((fsector_t - buffer_min) << 9); - bh = CURRENT->bh; size = CURRENT->current_nr_sectors << 9; - buffer = CURRENT->buffer; - while (remaining > 0){ - SUPBOUND(size, remaining); + rq_for_each_bio(bio, CURRENT) { + bio_for_each_segment(bv, bio, i) { + if (!remaining) + break; + + size = bv->bv_len; + SUPBOUND(size, remaining); + + buffer = page_address(bv->bv_page) + bv->bv_offset; #ifdef FLOPPY_SANITY_CHECK if (dma_buffer + size > floppy_track_buffer + (max_buffer_sectors << 10) || dma_buffer < floppy_track_buffer){ DPRINT("buffer overrun in copy buffer %d\n", (int) ((floppy_track_buffer - dma_buffer) >>9)); - printk("sector_t=%d buffer_min=%d\n", - sector_t, buffer_min); + printk("fsector_t=%d buffer_min=%d\n", + fsector_t, buffer_min); printk("current_count_sectors=%ld\n", current_count_sectors); if (CT(COMMAND) == FD_READ) @@ -2527,24 +2537,14 @@ if (((unsigned long)buffer) % 512) DPRINT("%p buffer not aligned\n", buffer); #endif - if (CT(COMMAND) == FD_READ) - memcpy(buffer, dma_buffer, size); - else - memcpy(dma_buffer, buffer, size); - remaining -= size; - if (!remaining) - break; + if (CT(COMMAND) == FD_READ) + memcpy(buffer, dma_buffer, size); + else + memcpy(dma_buffer, buffer, size); - dma_buffer += size; - bh = bh->b_reqnext; -#ifdef FLOPPY_SANITY_CHECK - if (!bh){ - DPRINT("bh=null in copy buffer after copy\n"); - break; + remaining -= size; + dma_buffer += size; } -#endif - size = bh->b_size; - buffer = bh->b_data; } #ifdef FLOPPY_SANITY_CHECK if (remaining){ @@ -2622,10 +2622,10 @@ raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK; raw_cmd->cmd_count = NR_RW; - if (CURRENT->cmd == READ){ + if (rq_data_dir(CURRENT) == READ) { raw_cmd->flags |= FD_RAW_READ; COMMAND = FM_MODE(_floppy,FD_READ); - } else if (CURRENT->cmd == WRITE){ + } else if (rq_data_dir(CURRENT) == WRITE){ raw_cmd->flags |= FD_RAW_WRITE; COMMAND = FM_MODE(_floppy,FD_WRITE); } else { @@ -2636,7 +2636,7 @@ max_sector = _floppy->sect * _floppy->head; TRACK = CURRENT->sector / max_sector; - sector_t = CURRENT->sector % max_sector; + fsector_t = CURRENT->sector % max_sector; if (_floppy->track && TRACK >= _floppy->track) { if (CURRENT->current_nr_sectors & 1) { current_count_sectors = 1; @@ -2644,17 +2644,17 @@ } else return 0; } - HEAD = sector_t / _floppy->sect; + HEAD = fsector_t / _floppy->sect; if (((_floppy->stretch & FD_SWAPSIDES) || TESTF(FD_NEED_TWADDLE)) && - sector_t < _floppy->sect) + fsector_t < _floppy->sect) max_sector = _floppy->sect; /* 2M disks have phantom sectors on the first track */ if ((_floppy->rate & FD_2M) && (!TRACK) && (!HEAD)){ max_sector = 2 * _floppy->sect / 3; - if (sector_t >= max_sector){ - current_count_sectors = minimum(_floppy->sect - sector_t, + if (fsector_t >= max_sector){ + current_count_sectors = minimum(_floppy->sect - fsector_t, CURRENT->nr_sectors); return 1; } @@ -2676,7 +2676,7 @@ GAP = _floppy->gap; CODE2SIZE; SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE; - SECTOR = ((sector_t % _floppy->sect) << 2 >> SIZECODE) + 1; + SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + 1; /* tracksize describes the size which can be filled up with sectors * of size ssize. @@ -2684,11 +2684,11 @@ tracksize = _floppy->sect - _floppy->sect % ssize; if (tracksize < _floppy->sect){ SECT_PER_TRACK ++; - if (tracksize <= sector_t % _floppy->sect) + if (tracksize <= fsector_t % _floppy->sect) SECTOR--; /* if we are beyond tracksize, fill up using smaller sectors */ - while (tracksize <= sector_t % _floppy->sect){ + while (tracksize <= fsector_t % _floppy->sect){ while(tracksize + ssize > _floppy->sect){ SIZECODE--; ssize >>= 1; @@ -2704,12 +2704,12 @@ max_sector = _floppy->sect; } - in_sector_offset = (sector_t % _floppy->sect) % ssize; - aligned_sector_t = sector_t - in_sector_offset; + in_sector_offset = (fsector_t % _floppy->sect) % ssize; + aligned_sector_t = fsector_t - in_sector_offset; max_size = CURRENT->nr_sectors; if ((raw_cmd->track == buffer_track) && (current_drive == buffer_drive) && - (sector_t >= buffer_min) && (sector_t < buffer_max)) { + (fsector_t >= buffer_min) && (fsector_t < buffer_max)) { /* data already in track buffer */ if (CT(COMMAND) == FD_READ) { copy_buffer(1, max_sector, buffer_max); @@ -2717,8 +2717,8 @@ } } else if (in_sector_offset || CURRENT->nr_sectors < ssize){ if (CT(COMMAND) == FD_WRITE){ - if (sector_t + CURRENT->nr_sectors > ssize && - sector_t + CURRENT->nr_sectors < ssize + ssize) + if (fsector_t + CURRENT->nr_sectors > ssize && + fsector_t + CURRENT->nr_sectors < ssize + ssize) max_size = ssize + ssize; else max_size = ssize; @@ -2731,7 +2731,7 @@ int direct, indirect; indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) - - sector_t; + fsector_t; /* * Do NOT use minimum() here---MAX_DMA_ADDRESS is 64 bits wide @@ -2746,7 +2746,7 @@ if (CROSS_64KB(CURRENT->buffer, max_size << 9)) max_size = (K_64 - ((unsigned long)CURRENT->buffer) % K_64)>>9; - direct = transfer_size(ssize,max_sector,max_size) - sector_t; + direct = transfer_size(ssize,max_sector,max_size) - fsector_t; /* * We try to read tracks, but if we get too many errors, we * go back to reading just one sector at a time. @@ -2765,8 +2765,8 @@ raw_cmd->length = current_count_sectors << 9; if (raw_cmd->length == 0){ DPRINT("zero dma transfer attempted from make_raw_request\n"); - DPRINT("indirect=%d direct=%d sector_t=%d", - indirect, direct, sector_t); + DPRINT("indirect=%d direct=%d fsector_t=%d", + indirect, direct, fsector_t); return 0; } /* check_dma_crossing(raw_cmd->kernel_data, @@ -2784,12 +2784,12 @@ /* claim buffer track if needed */ if (buffer_track != raw_cmd->track || /* bad track */ buffer_drive !=current_drive || /* bad drive */ - sector_t > buffer_max || - sector_t < buffer_min || + fsector_t > buffer_max || + fsector_t < buffer_min || ((CT(COMMAND) == FD_READ || (!in_sector_offset && CURRENT->nr_sectors >= ssize))&& max_sector > 2 * max_buffer_sectors + buffer_min && - max_size + sector_t > 2 * max_buffer_sectors + buffer_min) + max_size + fsector_t > 2 * max_buffer_sectors + buffer_min) /* not enough space */){ buffer_track = -1; buffer_drive = current_drive; @@ -2836,7 +2836,7 @@ floppy_track_buffer) >> 9), current_count_sectors); printk("st=%d ast=%d mse=%d msi=%d\n", - sector_t, aligned_sector_t, max_sector, max_size); + fsector_t, aligned_sector_t, max_sector, max_size); printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE); printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n", COMMAND, SECTOR, HEAD, TRACK); @@ -2854,8 +2854,8 @@ raw_cmd->kernel_data + raw_cmd->length > floppy_track_buffer + (max_buffer_sectors << 10)){ DPRINT("buffer overrun in schedule dma\n"); - printk("sector_t=%d buffer_min=%d current_count=%ld\n", - sector_t, buffer_min, + printk("fsector_t=%d buffer_min=%d current_count=%ld\n", + fsector_t, buffer_min, raw_cmd->length >> 9); printk("current_count_sectors=%ld\n", current_count_sectors); @@ -2908,8 +2908,6 @@ } if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) panic(DEVICE_NAME ": request list destroyed"); - if (CURRENT->bh && !buffer_locked(CURRENT->bh)) - panic(DEVICE_NAME ": block not locked"); device = CURRENT->rq_dev; set_fdc(DRIVE(device)); @@ -2977,7 +2975,7 @@ if (usage_count == 0) { printk("warning: usage count=0, CURRENT=%p exiting\n", CURRENT); - printk("sect=%ld cmd=%d\n", CURRENT->sector, CURRENT->cmd); + printk("sect=%ld flags=%lx\n", CURRENT->sector, CURRENT->flags); return; } if (fdc_busy){ @@ -3917,7 +3915,7 @@ {NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in}; base_minor = (drive < 4) ? drive : (124 + drive); - if (UDP->cmos <= NUMBER(default_drive_params)) { + if (UDP->cmos < NUMBER(default_drive_params)) { i = 0; do { char name[16]; @@ -4172,7 +4170,7 @@ blk_size[MAJOR_NR] = floppy_sizes; blksize_size[MAJOR_NR] = floppy_blocksizes; - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST, &floppy_lock); reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT); config_types(); @@ -4480,21 +4478,5 @@ #else __setup ("floppy=", floppy_setup); - -/* eject the boot floppy (if we need the drive for a different root floppy) */ -/* This should only be called at boot time when we're sure that there's no - * resource contention. */ -void floppy_eject(void) -{ - int dummy; - if (have_no_fdc) - return; - if(floppy_grab_irq_and_dma()==0) - { - lock_fdc(MAXTIMEOUT,0); - dummy=fd_eject(0); - process_fd_request(); - floppy_release_irq_and_dma(); - } -} +module_init(floppy_init) #endif diff -u --recursive --new-file v2.5.0/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.5.0/linux/drivers/block/genhd.c Wed Oct 17 14:46:29 2001 +++ linux/drivers/block/genhd.c Sat Dec 8 09:49:52 2001 @@ -28,14 +28,8 @@ /* * Global kernel list of partitioning information. - * - * XXX: you should _never_ access this directly. - * the only reason this is exported is source compatiblity. */ -/*static*/ struct gendisk *gendisk_head; - -EXPORT_SYMBOL(gendisk_head); - +static struct gendisk *gendisk_head; /** * add_gendisk - add partitioning information to kernel list @@ -123,6 +117,30 @@ EXPORT_SYMBOL(get_gendisk); +unsigned long +get_start_sect(kdev_t dev) +{ + struct gendisk *gp; + + gp = get_gendisk(dev); + if (gp) + return gp->part[MINOR(dev)].start_sect; + return 0; +} + +EXPORT_SYMBOL(get_start_sect); + +unsigned long +get_nr_sects(kdev_t dev) +{ + struct gendisk *gp; + + gp = get_gendisk(dev); + if (gp) + return gp->part[MINOR(dev)].nr_sects; + return 0; +} + #ifdef CONFIG_PROC_FS int get_partition_list(char *page, char **start, off_t offset, int count) @@ -165,7 +183,6 @@ extern int fusion_init(void); #endif extern int net_dev_init(void); -extern void console_map_init(void); extern int soc_probe(void); extern int atmdev_init(void); extern int i2o_init(void); @@ -194,9 +211,6 @@ #endif #ifdef CONFIG_ATM (void) atmdev_init(); -#endif -#ifdef CONFIG_VT - console_map_init(); #endif return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/block/ida_cmd.h linux/drivers/block/ida_cmd.h --- v2.5.0/linux/drivers/block/ida_cmd.h Fri Nov 2 17:45:42 2001 +++ linux/drivers/block/ida_cmd.h Thu Dec 6 14:02:56 2001 @@ -67,7 +67,7 @@ __u8 reserved; } rhdr_t; -#define SG_MAX 32 +#define SG_MAX 31 typedef struct { rhdr_t hdr; sg_t sg[SG_MAX]; diff -u --recursive --new-file v2.5.0/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v2.5.0/linux/drivers/block/ll_rw_blk.c Mon Oct 29 12:11:17 2001 +++ linux/drivers/block/ll_rw_blk.c Sun Dec 16 12:20:20 2001 @@ -6,6 +6,7 @@ * Elevator latency, (C) 2000 Andrea Arcangeli SuSE * Queue request tables / lock, selectable elevator, Jens Axboe * kernel-doc documentation started by NeilBrown - July2000 + * bio rewrite, highmem i/o, etc, Jens Axboe - may 2001 */ /* @@ -22,7 +23,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -50,27 +54,13 @@ */ DECLARE_TASK_QUEUE(tq_disk); -/* - * Protect the request list against multiple users.. - * - * With this spinlock the Linux block IO subsystem is 100% SMP threaded - * from the IRQ event side, and almost 100% SMP threaded from the syscall - * side (we still have protect against block device array operations, and - * the do_request() side is casually still unsafe. The kernel lock protects - * this part currently.). - * - * there is a fair chance that things will work just OK if these functions - * are called with no global kernel lock held ... - */ -spinlock_t io_request_lock = SPIN_LOCK_UNLOCKED; - /* This specifies how many sectors to read ahead on the disk. */ int read_ahead[MAX_BLKDEV]; /* blk_dev_struct is: - * *request_fn - * *current_request + * request_queue + * *queue */ struct blk_dev_struct blk_dev[MAX_BLKDEV]; /* initialized by blk_dev_init() */ @@ -94,42 +84,29 @@ int * blksize_size[MAX_BLKDEV]; /* - * hardsect_size contains the size of the hardware sector of a device. - * - * hardsect_size[MAJOR][MINOR] - * - * if (!hardsect_size[MAJOR]) - * then 512 bytes is assumed. - * else - * sector_size is hardsect_size[MAJOR][MINOR] - * This is currently set by some scsi devices and read by the msdos fs driver. - * Other uses may appear later. - */ -int * hardsect_size[MAX_BLKDEV]; - -/* * The following tunes the read-ahead algorithm in mm/filemap.c */ int * max_readahead[MAX_BLKDEV]; /* - * Max number of sectors per request - */ -int * max_sectors[MAX_BLKDEV]; - -/* * How many reqeusts do we allocate per queue, * and how many do we "batch" on freeing them? */ -static int queue_nr_requests, batch_requests; - -static inline int get_max_sectors(kdev_t dev) -{ - if (!max_sectors[MAJOR(dev)]) - return MAX_SECTORS; - return max_sectors[MAJOR(dev)][MINOR(dev)]; -} +int queue_nr_requests, batch_requests; +unsigned long blk_max_low_pfn, blk_max_pfn; +int blk_nohighio = 0; +/** + * blk_get_queue: - return the queue that matches the given device + * @dev: device + * + * Description: + * Given a specific device, return the queue that will hold I/O + * for it. This is either a &struct blk_dev_struct lookup and a + * call to the ->queue() function defined, or the default queue + * stored in the same location. + * + **/ inline request_queue_t *blk_get_queue(kdev_t dev) { struct blk_dev_struct *bdev = blk_dev + MAJOR(dev); @@ -140,147 +117,490 @@ return &blk_dev[MAJOR(dev)].request_queue; } -static int __blk_cleanup_queue(struct request_list *list) +/** + * blk_queue_make_request - define an alternate make_request function for a device + * @q: the request queue for the device to be affected + * @mfn: the alternate make_request function + * + * Description: + * The normal way for &struct bios to be passed to a device + * driver is for them to be collected into requests on a request + * queue, and then to allow the device driver to select requests + * off that queue when it is ready. This works well for many block + * devices. However some block devices (typically virtual devices + * such as md or lvm) do not benefit from the processing on the + * request queue, and are served best by having the requests passed + * directly to them. This can be achieved by providing a function + * to blk_queue_make_request(). + * + * Caveat: + * The driver that does this *must* be able to deal appropriately + * with buffers in "highmemory". This can be accomplished by either calling + * bio_kmap() to get a temporary kernel mapping, or by calling + * blk_queue_bounce() to create a buffer in normal memory. + **/ +void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn) { - struct list_head *head = &list->free; - struct request *rq; - int i = 0; - - while (!list_empty(head)) { - rq = list_entry(head->next, struct request, queue); - list_del(&rq->queue); - kmem_cache_free(request_cachep, rq); - i++; - }; - - if (i != list->count) - printk("request list leak!\n"); + /* + * set defaults + */ + q->max_phys_segments = MAX_PHYS_SEGMENTS; + q->max_hw_segments = MAX_HW_SEGMENTS; + q->make_request_fn = mfn; + blk_queue_max_sectors(q, MAX_SECTORS); + blk_queue_hardsect_size(q, 512); - list->count = 0; - return i; + init_waitqueue_head(&q->queue_wait); } /** - * blk_cleanup_queue: - release a &request_queue_t when it is no longer needed - * @q: the request queue to be released + * blk_queue_bounce_limit - set bounce buffer limit for queue + * @q: the request queue for the device + * @dma_addr: bus address limit * * Description: - * blk_cleanup_queue is the pair to blk_init_queue(). It should - * be called when a request queue is being released; typically - * when a block device is being de-registered. Currently, its - * primary task it to free all the &struct request structures that - * were allocated to the queue. - * Caveat: - * Hopefully the low level driver will have finished any - * outstanding requests first... + * Different hardware can have different requirements as to what pages + * it can do I/O directly to. A low level driver can call + * blk_queue_bounce_limit to have lower memory pages allocated as bounce + * buffers for doing I/O to pages residing above @page. By default + * the block layer sets this to the highest numbered "low" memory page. **/ -void blk_cleanup_queue(request_queue_t * q) +void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr) { - int count = queue_nr_requests; + unsigned long bounce_pfn = dma_addr >> PAGE_SHIFT; + unsigned long mb = dma_addr >> 20; + static request_queue_t *last_q; - count -= __blk_cleanup_queue(&q->rq[READ]); - count -= __blk_cleanup_queue(&q->rq[WRITE]); + /* + * set appropriate bounce gfp mask -- unfortunately we don't have a + * full 4GB zone, so we have to resort to low memory for any bounces. + * ISA has its own < 16MB zone. + */ + if (dma_addr == BLK_BOUNCE_ISA) { + init_emergency_isa_pool(); + q->bounce_gfp = GFP_NOIO | GFP_DMA; + printk("isa pfn %lu, max low %lu, max %lu\n", bounce_pfn, blk_max_low_pfn, blk_max_pfn); + } else + q->bounce_gfp = GFP_NOHIGHIO; - if (count) - printk("blk_cleanup_queue: leaked requests (%d)\n", count); + /* + * keep this for debugging for now... + */ + if (dma_addr != BLK_BOUNCE_HIGH && q != last_q) { + printk("blk: queue %p, ", q); + if (dma_addr == BLK_BOUNCE_ANY) + printk("no I/O memory limit\n"); + else + printk("I/O limit %luMb (mask 0x%Lx)\n", mb, (long long) dma_addr); + } - memset(q, 0, sizeof(*q)); + q->bounce_pfn = bounce_pfn; + last_q = q; } + /** - * blk_queue_headactive - indicate whether head of request queue may be active - * @q: The queue which this applies to. - * @active: A flag indication where the head of the queue is active. + * blk_queue_max_sectors - set max sectors for a request for this queue + * @q: the request queue for the device + * @max_sectors: max sectors in the usual 512b unit * * Description: - * The driver for a block device may choose to leave the currently active - * request on the request queue, removing it only when it has completed. - * The queue handling routines assume this by default for safety reasons - * and will not involve the head of the request queue in any merging or - * reordering of requests when the queue is unplugged (and thus may be - * working on this particular request). - * - * If a driver removes requests from the queue before processing them, then - * it may indicate that it does so, there by allowing the head of the queue - * to be involved in merging and reordering. This is done be calling - * blk_queue_headactive() with an @active flag of %0. + * Enables a low level driver to set an upper limit on the size of + * received requests. + **/ +void blk_queue_max_sectors(request_queue_t *q, unsigned short max_sectors) +{ + q->max_sectors = max_sectors; +} + +/** + * blk_queue_max_phys_segments - set max phys segments for a request for this queue + * @q: the request queue for the device + * @max_segments: max number of segments * - * If a driver processes several requests at once, it must remove them (or - * at least all but one of them) from the request queue. + * Description: + * Enables a low level driver to set an upper limit on the number of + * physical data segments in a request. This would be the largest sized + * scatter list the driver could handle. + **/ +void blk_queue_max_phys_segments(request_queue_t *q, unsigned short max_segments) +{ + q->max_phys_segments = max_segments; +} + +/** + * blk_queue_max_hw_segments - set max hw segments for a request for this queue + * @q: the request queue for the device + * @max_segments: max number of segments * - * When a queue is plugged the head will be assumed to be inactive. + * Description: + * Enables a low level driver to set an upper limit on the number of + * hw data segments in a request. This would be the largest number of + * address/length pairs the host adapter can actually give as once + * to the device. **/ - -void blk_queue_headactive(request_queue_t * q, int active) +void blk_queue_max_hw_segments(request_queue_t *q, unsigned short max_segments) { - q->head_active = active; + q->max_hw_segments = max_segments; } /** - * blk_queue_make_request - define an alternate make_request function for a device - * @q: the request queue for the device to be affected - * @mfn: the alternate make_request function + * blk_queue_max_segment_size - set max segment size for blk_rq_map_sg + * @q: the request queue for the device + * @max_size: max size of segment in bytes * * Description: - * The normal way for &struct buffer_heads to be passed to a device - * driver is for them to be collected into requests on a request - * queue, and then to allow the device driver to select requests - * off that queue when it is ready. This works well for many block - * devices. However some block devices (typically virtual devices - * such as md or lvm) do not benefit from the processing on the - * request queue, and are served best by having the requests passed - * directly to them. This can be achieved by providing a function - * to blk_queue_make_request(). + * Enables a low level driver to set an upper limit on the size of a + * coalesced segment + **/ +void blk_queue_max_segment_size(request_queue_t *q, unsigned int max_size) +{ + q->max_segment_size = max_size; +} + +/** + * blk_queue_hardsect_size - set hardware sector size for the queue + * @q: the request queue for the device + * @size: the hardware sector size, in bytes * - * Caveat: - * The driver that does this *must* be able to deal appropriately - * with buffers in "highmemory", either by calling bh_kmap() to get - * a kernel mapping, to by calling create_bounce() to create a - * buffer in normal memory. + * Description: + * This should typically be set to the lowest possible sector size + * that the hardware can operate on (possible without reverting to + * even internal read-modify-write operations). Usually the default + * of 512 covers most hardware. **/ +void blk_queue_hardsect_size(request_queue_t *q, unsigned short size) +{ + q->hardsect_size = size; +} -void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn) +/** + * blk_queue_segment_boundary - set boundary rules for segment merging + * @q: the request queue for the device + * @mask: the memory boundary mask + **/ +void blk_queue_segment_boundary(request_queue_t *q, unsigned long mask) { - q->make_request_fn = mfn; + q->seg_boundary_mask = mask; } -static inline int ll_new_segment(request_queue_t *q, struct request *req, int max_segments) +void blk_queue_assign_lock(request_queue_t *q, spinlock_t *lock) { - if (req->nr_segments < max_segments) { - req->nr_segments++; - return 1; + spin_lock_init(lock); + q->queue_lock = lock; +} + +static char *rq_flags[] = { "REQ_RW", "REQ_RW_AHEAD", "REQ_BARRIER", + "REQ_CMD", "REQ_NOMERGE", "REQ_STARTED", + "REQ_DONTPREP", "REQ_DRIVE_CMD", "REQ_DRIVE_TASK", + "REQ_PC", "REQ_BLOCK_PC", "REQ_SENSE", + "REQ_SPECIAL" }; + +void blk_dump_rq_flags(struct request *rq, char *msg) +{ + int bit; + + printk("%s: dev %x: ", msg, rq->rq_dev); + bit = 0; + do { + if (rq->flags & (1 << bit)) + printk("%s ", rq_flags[bit]); + bit++; + } while (bit < __REQ_NR_BITS); + + if (rq->flags & REQ_CMD) + printk("sector %lu, nr/cnr %lu/%u\n", rq->sector, + rq->nr_sectors, + rq->current_nr_sectors); + + printk("\n"); +} + +/* + * standard prep_rq_fn that builds 10 byte cmds + */ +static int ll_10byte_cmd_build(request_queue_t *q, struct request *rq) +{ + int hard_sect = get_hardsect_size(rq->rq_dev); + sector_t block = rq->hard_sector / (hard_sect >> 9); + unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9); + + if (!(rq->flags & REQ_CMD)) + return 0; + + memset(rq->cmd, 0, sizeof(rq->cmd)); + + if (rq_data_dir(rq) == READ) + rq->cmd[0] = READ_10; + else + rq->cmd[0] = WRITE_10; + + /* + * fill in lba + */ + rq->cmd[2] = (block >> 24) & 0xff; + rq->cmd[3] = (block >> 16) & 0xff; + rq->cmd[4] = (block >> 8) & 0xff; + rq->cmd[5] = block & 0xff; + + /* + * and transfer length + */ + rq->cmd[7] = (blocks >> 8) & 0xff; + rq->cmd[8] = blocks & 0xff; + + return 0; +} + +void blk_recount_segments(request_queue_t *q, struct bio *bio) +{ + struct bio_vec *bv, *bvprv = NULL; + int i, nr_phys_segs, nr_hw_segs, seg_size, cluster; + + if (unlikely(!bio->bi_io_vec)) + return; + + cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); + seg_size = nr_phys_segs = nr_hw_segs = 0; + bio_for_each_segment(bv, bio, i) { + if (bvprv && cluster) { + int phys, seg; + + if (seg_size + bv->bv_len > q->max_segment_size) { + nr_phys_segs++; + goto new_segment; + } + + phys = BIOVEC_PHYS_MERGEABLE(bvprv, bv); + seg = BIOVEC_SEG_BOUNDARY(q, bvprv, bv); + if (!phys || !seg) + nr_phys_segs++; + if (!seg) + goto new_segment; + + if (!BIOVEC_VIRT_MERGEABLE(bvprv, bv)) + goto new_segment; + + seg_size += bv->bv_len; + bvprv = bv; + continue; + } else { + nr_phys_segs++; + } +new_segment: + nr_hw_segs++; + bvprv = bv; + seg_size = bv->bv_len; } + + bio->bi_phys_segments = nr_phys_segs; + bio->bi_hw_segments = nr_hw_segs; + bio->bi_flags |= (1 << BIO_SEG_VALID); +} + + +inline int blk_phys_contig_segment(request_queue_t *q, struct bio *bio, + struct bio *nxt) +{ + if (!(q->queue_flags & (1 << QUEUE_FLAG_CLUSTER))) + return 0; + + if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt))) + return 0; + if (bio->bi_size + nxt->bi_size > q->max_segment_size) + return 0; + + /* + * bio and nxt are contigous in memory, check if the queue allows + * these two to be merged into one + */ + if (BIO_SEG_BOUNDARY(q, bio, nxt)) + return 1; + return 0; } -static int ll_back_merge_fn(request_queue_t *q, struct request *req, - struct buffer_head *bh, int max_segments) +inline int blk_hw_contig_segment(request_queue_t *q, struct bio *bio, + struct bio *nxt) { - if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data) + if (!(q->queue_flags & (1 << QUEUE_FLAG_CLUSTER))) + return 0; + + if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt))) + return 0; + if (bio->bi_size + nxt->bi_size > q->max_segment_size) + return 0; + + /* + * bio and nxt are contigous in memory, check if the queue allows + * these two to be merged into one + */ + if (BIO_SEG_BOUNDARY(q, bio, nxt)) return 1; - return ll_new_segment(q, req, max_segments); + + return 0; +} + +/* + * map a request to scatterlist, return number of sg entries setup. Caller + * must make sure sg can hold rq->nr_phys_segments entries + */ +int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist *sg) +{ + struct bio_vec *bvec, *bvprv; + struct bio *bio; + int nsegs, i, cluster; + + nsegs = 0; + cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); + + /* + * for each bio in rq + */ + bvprv = NULL; + rq_for_each_bio(bio, rq) { + /* + * for each segment in bio + */ + bio_for_each_segment(bvec, bio, i) { + int nbytes = bvec->bv_len; + + if (bvprv && cluster) { + if (sg[nsegs - 1].length + nbytes > q->max_segment_size) + goto new_segment; + + if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) + goto new_segment; + if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec)) + goto new_segment; + + sg[nsegs - 1].length += nbytes; + } else { +new_segment: + sg[nsegs].address = NULL; + sg[nsegs].page = bvec->bv_page; + sg[nsegs].length = nbytes; + sg[nsegs].offset = bvec->bv_offset; + + nsegs++; + } + bvprv = bvec; + } /* segments in bio */ + } /* bios in rq */ + + return nsegs; +} + +/* + * the standard queue merge functions, can be overridden with device + * specific ones if so desired + */ + +static inline int ll_new_mergeable(request_queue_t *q, + struct request *req, + struct bio *bio) +{ + int nr_phys_segs = bio_phys_segments(q, bio); + + if (req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) { + req->flags |= REQ_NOMERGE; + return 0; + } + + /* + * A hw segment is just getting larger, bump just the phys + * counter. + */ + req->nr_phys_segments += nr_phys_segs; + return 1; +} + +static inline int ll_new_hw_segment(request_queue_t *q, + struct request *req, + struct bio *bio) +{ + int nr_hw_segs = bio_hw_segments(q, bio); + + if (req->nr_hw_segments + nr_hw_segs > q->max_hw_segments) { + req->flags |= REQ_NOMERGE; + return 0; + } + + /* + * This will form the start of a new hw segment. Bump both + * counters. + */ + req->nr_hw_segments += nr_hw_segs; + req->nr_phys_segments += bio_phys_segments(q, bio); + return 1; +} + +static int ll_back_merge_fn(request_queue_t *q, struct request *req, + struct bio *bio) +{ + if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) { + req->flags |= REQ_NOMERGE; + return 0; + } + + if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), + __BVEC_START(bio))) + return ll_new_mergeable(q, req, bio); + + return ll_new_hw_segment(q, req, bio); } static int ll_front_merge_fn(request_queue_t *q, struct request *req, - struct buffer_head *bh, int max_segments) + struct bio *bio) { - if (bh->b_data + bh->b_size == req->bh->b_data) - return 1; - return ll_new_segment(q, req, max_segments); + if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) { + req->flags |= REQ_NOMERGE; + return 0; + } + + if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), + __BVEC_START(req->bio))) + return ll_new_mergeable(q, req, bio); + + return ll_new_hw_segment(q, req, bio); } static int ll_merge_requests_fn(request_queue_t *q, struct request *req, - struct request *next, int max_segments) + struct request *next) { - int total_segments = req->nr_segments + next->nr_segments; + int total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; + int total_hw_segments = req->nr_hw_segments + next->nr_hw_segments; + + /* + * First check if the either of the requests are re-queued + * requests. Can't merge them if they are. + */ + if (req->special || next->special) + return 0; - if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) - total_segments--; + /* + * Will it become to large? + */ + if ((req->nr_sectors + next->nr_sectors) > q->max_sectors) + return 0; + + total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; + if (blk_phys_contig_segment(q, req->biotail, next->bio)) + total_phys_segments--; + + if (total_phys_segments > q->max_phys_segments) + return 0; + + total_hw_segments = req->nr_hw_segments + next->nr_hw_segments; + if (blk_hw_contig_segment(q, req->biotail, next->bio)) + total_hw_segments--; - if (total_segments > max_segments) + if (total_hw_segments > q->max_hw_segments) return 0; - req->nr_segments = total_segments; + /* Merge is OK... */ + req->nr_phys_segments = total_phys_segments; + req->nr_hw_segments = total_hw_segments; return 1; } @@ -292,42 +612,110 @@ * This is called with interrupts off and no requests on the queue. * (and with the request spinlock acquired) */ -static void generic_plug_device(request_queue_t *q, kdev_t dev) +void blk_plug_device(request_queue_t *q) +{ + /* + * common case + */ + if (!elv_queue_empty(q)) + return; + + if (!test_and_set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) + queue_task(&q->plug_tq, &tq_disk); +} + +/* + * remove the plug and let it rip.. + */ +static inline void __generic_unplug_device(request_queue_t *q) +{ + /* + * not plugged + */ + if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) + return; + + /* + * was plugged, fire request_fn if queue has stuff to do + */ + if (!elv_queue_empty(q)) + q->request_fn(q); +} + +/** + * generic_unplug_device - fire a request queue + * @q: The &request_queue_t in question + * + * Description: + * Linux uses plugging to build bigger requests queues before letting + * the device have at them. If a queue is plugged, the I/O scheduler + * is still adding and merging requests on the queue. Once the queue + * gets unplugged (either by manually calling this function, or by + * running the tq_disk task queue), the request_fn defined for the + * queue is invoked and transfers started. + **/ +void generic_unplug_device(void *data) +{ + request_queue_t *q = (request_queue_t *) data; + unsigned long flags; + + spin_lock_irqsave(q->queue_lock, flags); + __generic_unplug_device(q); + spin_unlock_irqrestore(q->queue_lock, flags); +} + +static int __blk_cleanup_queue(struct request_list *list) +{ + struct list_head *head = &list->free; + struct request *rq; + int i = 0; + + while (!list_empty(head)) { + rq = list_entry(head->next, struct request, queuelist); + list_del(&rq->queuelist); + kmem_cache_free(request_cachep, rq); + i++; + } + + if (i != list->count) + printk("request list leak!\n"); + + list->count = 0; + return i; +} + +/** + * blk_cleanup_queue: - release a &request_queue_t when it is no longer needed + * @q: the request queue to be released + * + * Description: + * blk_cleanup_queue is the pair to blk_init_queue(). It should + * be called when a request queue is being released; typically + * when a block device is being de-registered. Currently, its + * primary task it to free all the &struct request structures that + * were allocated to the queue. + * Caveat: + * Hopefully the low level driver will have finished any + * outstanding requests first... + **/ +void blk_cleanup_queue(request_queue_t * q) { - /* - * no need to replug device - */ - if (!list_empty(&q->queue_head) || q->plugged) - return; + int count = queue_nr_requests; - q->plugged = 1; - queue_task(&q->plug_tq, &tq_disk); -} + count -= __blk_cleanup_queue(&q->rq[READ]); + count -= __blk_cleanup_queue(&q->rq[WRITE]); -/* - * remove the plug and let it rip.. - */ -static inline void __generic_unplug_device(request_queue_t *q) -{ - if (q->plugged) { - q->plugged = 0; - if (!list_empty(&q->queue_head)) - q->request_fn(q); - } -} + if (count) + printk("blk_cleanup_queue: leaked requests (%d)\n", count); -void generic_unplug_device(void *data) -{ - request_queue_t *q = (request_queue_t *) data; - unsigned long flags; + elevator_exit(q, &q->elevator); - spin_lock_irqsave(&io_request_lock, flags); - __generic_unplug_device(q); - spin_unlock_irqrestore(&io_request_lock, flags); + memset(q, 0, sizeof(*q)); } -static void blk_init_free_list(request_queue_t *q) +static int blk_init_free_list(request_queue_t *q) { + struct request_list *rl; struct request *rq; int i; @@ -339,24 +727,33 @@ /* * Divide requests in half between read and write */ + rl = &q->rq[READ]; for (i = 0; i < queue_nr_requests; i++) { rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL); - if (rq == NULL) { - /* We'll get a `leaked requests' message from blk_cleanup_queue */ - printk(KERN_EMERG "blk_init_free_list: error allocating requests\n"); - break; - } + if (!rq) + goto nomem; + + /* + * half way through, switch to WRITE list + */ + if (i == queue_nr_requests / 2) + rl = &q->rq[WRITE]; + memset(rq, 0, sizeof(struct request)); rq->rq_status = RQ_INACTIVE; - list_add(&rq->queue, &q->rq[i&1].free); - q->rq[i&1].count++; + list_add(&rq->queuelist, &rl->free); + rl->count++; } - init_waitqueue_head(&q->wait_for_request); - spin_lock_init(&q->queue_lock); + init_waitqueue_head(&q->rq[READ].wait); + init_waitqueue_head(&q->rq[WRITE].wait); + return 0; +nomem: + blk_cleanup_queue(q); + return 1; } -static int __make_request(request_queue_t * q, int rw, struct buffer_head * bh); +static int __make_request(request_queue_t *, struct bio *); /** * blk_init_queue - prepare a request queue for use with a block device @@ -379,45 +776,51 @@ * requests on the queue, it is responsible for arranging that the requests * get dealt with eventually. * - * A global spin lock $io_request_lock must be held while manipulating the - * requests on the request queue. - * - * The request on the head of the queue is by default assumed to be - * potentially active, and it is not considered for re-ordering or merging - * whenever the given queue is unplugged. This behaviour can be changed with - * blk_queue_headactive(). + * The queue spin lock must be held while manipulating the requests on the + * request queue. * * Note: * blk_init_queue() must be paired with a blk_cleanup_queue() call * when the block device is deactivated (such as at module unload). **/ -void blk_init_queue(request_queue_t * q, request_fn_proc * rfn) +int blk_init_queue(request_queue_t *q, request_fn_proc *rfn, spinlock_t *lock) { - INIT_LIST_HEAD(&q->queue_head); - elevator_init(&q->elevator, ELEVATOR_LINUS); - blk_init_free_list(q); - q->request_fn = rfn; + int ret; + + if (blk_init_free_list(q)) + return -ENOMEM; + + if ((ret = elevator_init(q, &q->elevator, ELEVATOR_LINUS))) { + blk_cleanup_queue(q); + return ret; + } + + q->request_fn = rfn; q->back_merge_fn = ll_back_merge_fn; q->front_merge_fn = ll_front_merge_fn; q->merge_requests_fn = ll_merge_requests_fn; - q->make_request_fn = __make_request; + q->prep_rq_fn = ll_10byte_cmd_build; q->plug_tq.sync = 0; q->plug_tq.routine = &generic_unplug_device; q->plug_tq.data = q; - q->plugged = 0; + q->queue_flags = (1 << QUEUE_FLAG_CLUSTER); + q->queue_lock = lock; + /* - * These booleans describe the queue properties. We set the - * default (and most common) values here. Other drivers can - * use the appropriate functions to alter the queue properties. - * as appropriate. + * by default assume old behaviour and bounce for any highmem page */ - q->plug_device_fn = generic_plug_device; - q->head_active = 1; + blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH); + + blk_queue_segment_boundary(q, 0xffffffff); + + blk_queue_make_request(q, __make_request); + blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE); + return 0; } -#define blkdev_free_rq(list) list_entry((list)->next, struct request, queue); +#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist) /* - * Get a free request. io_request_lock must be held and interrupts + * Get a free request. queue lock must be held and interrupts * disabled on the way in. */ static inline struct request *get_request(request_queue_t *q, int rw) @@ -427,11 +830,13 @@ if (!list_empty(&rl->free)) { rq = blkdev_free_rq(&rl->free); - list_del(&rq->queue); + list_del(&rq->queuelist); rl->count--; + rq->flags = 0; rq->rq_status = RQ_ACTIVE; rq->special = NULL; rq->q = q; + rq->rl = rl; } return rq; @@ -440,36 +845,46 @@ /* * No available requests for this queue, unplug the device. */ -static struct request *__get_request_wait(request_queue_t *q, int rw) +static struct request *get_request_wait(request_queue_t *q, int rw) { - register struct request *rq; DECLARE_WAITQUEUE(wait, current); + struct request_list *rl = &q->rq[rw]; + struct request *rq; + + spin_lock_prefetch(q->queue_lock); generic_unplug_device(q); - add_wait_queue(&q->wait_for_request, &wait); + add_wait_queue(&rl->wait, &wait); do { set_current_state(TASK_UNINTERRUPTIBLE); - if (q->rq[rw].count < batch_requests) + if (rl->count < batch_requests) schedule(); - spin_lock_irq(&io_request_lock); - rq = get_request(q,rw); - spin_unlock_irq(&io_request_lock); + spin_lock_irq(q->queue_lock); + rq = get_request(q, rw); + spin_unlock_irq(q->queue_lock); } while (rq == NULL); - remove_wait_queue(&q->wait_for_request, &wait); + remove_wait_queue(&rl->wait, &wait); current->state = TASK_RUNNING; return rq; } -static inline struct request *get_request_wait(request_queue_t *q, int rw) +struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask) { - register struct request *rq; + struct request *rq; + + BUG_ON(rw != READ && rw != WRITE); - spin_lock_irq(&io_request_lock); rq = get_request(q, rw); - spin_unlock_irq(&io_request_lock); - if (rq) - return rq; - return __get_request_wait(q, rw); + + if (!rq && (gfp_mask & __GFP_WAIT)) + rq = get_request_wait(q, rw); + + return rq; +} + +void blk_put_request(struct request *rq) +{ + blkdev_release_request(rq); } /* RO fail safe mechanism */ @@ -497,13 +912,13 @@ else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31)); } -inline void drive_stat_acct (kdev_t dev, int rw, - unsigned long nr_sectors, int new_io) +void drive_stat_acct(struct request *rq, int nr_sectors, int new_io) { - unsigned int major = MAJOR(dev); + unsigned int major = MAJOR(rq->rq_dev); + int rw = rq_data_dir(rq); unsigned int index; - index = disk_index(dev); + index = disk_index(rq->rq_dev); if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR)) return; @@ -520,204 +935,229 @@ /* * add-request adds a request to the linked list. - * io_request_lock is held and interrupts disabled, as we muck with the + * queue lock is held and interrupts disabled, as we muck with the * request queue list. - * - * By this point, req->cmd is always either READ/WRITE, never READA, - * which is important for drive_stat_acct() above. */ static inline void add_request(request_queue_t * q, struct request * req, struct list_head *insert_here) { - drive_stat_acct(req->rq_dev, req->cmd, req->nr_sectors, 1); + drive_stat_acct(req, req->nr_sectors, 1); + + /* + * debug stuff... + */ + if (insert_here == &q->queue_head) { + struct request *__rq = __elv_next_request(q); - if (!q->plugged && q->head_active && insert_here == &q->queue_head) { - spin_unlock_irq(&io_request_lock); - BUG(); + BUG_ON(__rq && (__rq->flags & REQ_STARTED)); } /* * elevator indicated where it wants this request to be * inserted at elevator_merge time */ - list_add(&req->queue, insert_here); + q->elevator.elevator_add_req_fn(q, req, insert_here); } /* - * Must be called with io_request_lock held and interrupts disabled + * Must be called with queue lock held and interrupts disabled */ -inline void blkdev_release_request(struct request *req) +void blkdev_release_request(struct request *req) { - request_queue_t *q = req->q; - int rw = req->cmd; + struct request_list *rl = req->rl; req->rq_status = RQ_INACTIVE; req->q = NULL; + req->rl = NULL; /* * Request may not have originated from ll_rw_blk. if not, - * assume it has free buffers and check waiters + * it didn't come out of our reserved rq pools */ - if (q) { - list_add(&req->queue, &q->rq[rw].free); - if (++q->rq[rw].count >= batch_requests && waitqueue_active(&q->wait_for_request)) - wake_up(&q->wait_for_request); + if (rl) { + list_add(&req->queuelist, &rl->free); + + if (++rl->count >= batch_requests &&waitqueue_active(&rl->wait)) + wake_up(&rl->wait); } } /* * Has to be called with the request spinlock acquired */ -static void attempt_merge(request_queue_t * q, - struct request *req, - int max_sectors, - int max_segments) -{ - struct request *next; - - next = blkdev_next_request(req); +static void attempt_merge(request_queue_t *q, struct request *req) +{ + struct request *next = blkdev_next_request(req); + + /* + * not a rw command + */ + if (!(next->flags & REQ_CMD)) + return; + + /* + * not contigious + */ if (req->sector + req->nr_sectors != next->sector) return; - if (req->cmd != next->cmd + + /* + * don't touch NOMERGE rq, or one that has been started by driver + */ + if (next->flags & (REQ_NOMERGE | REQ_STARTED)) + return; + + if (rq_data_dir(req) != rq_data_dir(next) || req->rq_dev != next->rq_dev - || req->nr_sectors + next->nr_sectors > max_sectors - || next->waiting) + || req->nr_sectors + next->nr_sectors > q->max_sectors + || next->waiting || next->special) return; + /* * If we are not allowed to merge these requests, then * return. If we are allowed to merge, then the count * will have been updated to the appropriate number, * and we shouldn't do it here too. */ - if (!q->merge_requests_fn(q, req, next, max_segments)) - return; + if (q->merge_requests_fn(q, req, next)) { + q->elevator.elevator_merge_req_fn(req, next); - q->elevator.elevator_merge_req_fn(req, next); - req->bhtail->b_reqnext = next->bh; - req->bhtail = next->bhtail; - req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors; - list_del(&next->queue); - blkdev_release_request(next); + blkdev_dequeue_request(next); + + req->biotail->bi_next = next->bio; + req->biotail = next->biotail; + + req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors; + + blkdev_release_request(next); + } } -static inline void attempt_back_merge(request_queue_t * q, - struct request *req, - int max_sectors, - int max_segments) +static inline void attempt_back_merge(request_queue_t *q, struct request *rq) { - if (&req->queue == q->queue_head.prev) - return; - attempt_merge(q, req, max_sectors, max_segments); + if (&rq->queuelist != q->queue_head.prev) + attempt_merge(q, rq); } -static inline void attempt_front_merge(request_queue_t * q, - struct list_head * head, - struct request *req, - int max_sectors, - int max_segments) +static inline void attempt_front_merge(request_queue_t *q, + struct list_head *head, + struct request *rq) { - struct list_head * prev; + struct list_head *prev = rq->queuelist.prev; - prev = req->queue.prev; - if (head == prev) - return; - attempt_merge(q, blkdev_entry_to_request(prev), max_sectors, max_segments); + if (prev != head) + attempt_merge(q, blkdev_entry_to_request(prev)); } -static int __make_request(request_queue_t * q, int rw, - struct buffer_head * bh) +static inline void __blk_attempt_remerge(request_queue_t *q, struct request *rq) { - unsigned int sector, count; - int max_segments = MAX_SEGMENTS; - struct request * req, *freereq = NULL; - int rw_ahead, max_sectors, el_ret; - struct list_head *head, *insert_here; - int latency; - elevator_t *elevator = &q->elevator; + if (rq->queuelist.next != &q->queue_head) + attempt_merge(q, rq); +} - count = bh->b_size >> 9; - sector = bh->b_rsector; +/** + * blk_attempt_remerge - attempt to remerge active head with next request + * @q: The &request_queue_t belonging to the device + * @rq: The head request (usually) + * + * Description: + * For head-active devices, the queue can easily be unplugged so quickly + * that proper merging is not done on the front request. This may hurt + * performance greatly for some devices. The block layer cannot safely + * do merging on that first request for these queues, but the driver can + * call this function and make it happen any way. Only the driver knows + * when it is safe to do so. + **/ +void blk_attempt_remerge(request_queue_t *q, struct request *rq) +{ + unsigned long flags; - rw_ahead = 0; /* normal case; gets changed below for READA */ - switch (rw) { - case READA: - rw_ahead = 1; - rw = READ; /* drop into READ */ - case READ: - case WRITE: - latency = elevator_request_latency(elevator, rw); - break; - default: - BUG(); - goto end_io; - } + spin_lock_irqsave(q->queue_lock, flags); + __blk_attempt_remerge(q, rq); + spin_unlock_irqrestore(q->queue_lock, flags); +} - /* We'd better have a real physical mapping! - Check this bit only if the buffer was dirty and just locked - down by us so at this point flushpage will block and - won't clear the mapped bit under us. */ - if (!buffer_mapped(bh)) - BUG(); +static int __make_request(request_queue_t *q, struct bio *bio) +{ + struct request *req, *freereq = NULL; + int el_ret, latency = 0, rw, nr_sectors, cur_nr_sectors, barrier; + struct list_head *head, *insert_here; + elevator_t *elevator = &q->elevator; + sector_t sector; - /* - * Temporary solution - in 2.5 this will be done by the lowlevel - * driver. Create a bounce buffer if the buffer data points into - * high memory - keep the original buffer otherwise. - */ -#if CONFIG_HIGHMEM - bh = create_bounce(rw, bh); -#endif + sector = bio->bi_sector; + nr_sectors = bio_sectors(bio); + cur_nr_sectors = bio_iovec(bio)->bv_len >> 9; + rw = bio_data_dir(bio); -/* look for a free request. */ /* - * Try to coalesce the new request with old requests + * low level driver can indicate that it wants pages above a + * certain limit bounced to low memory (ie for highmem, or even + * ISA dma in theory) */ - max_sectors = get_max_sectors(bh->b_rdev); + blk_queue_bounce(q, &bio); + + spin_lock_prefetch(q->queue_lock); + + latency = elevator_request_latency(elevator, rw); + barrier = test_bit(BIO_RW_BARRIER, &bio->bi_rw); again: req = NULL; head = &q->queue_head; - /* - * Now we acquire the request spinlock, we have to be mega careful - * not to schedule or do something nonatomic - */ - spin_lock_irq(&io_request_lock); + + spin_lock_irq(q->queue_lock); insert_here = head->prev; - if (list_empty(head)) { - q->plug_device_fn(q, bh->b_rdev); /* is atomic */ + if (blk_queue_empty(q) || barrier) { + blk_plug_device(q); goto get_rq; - } else if (q->head_active && !q->plugged) - head = head->next; + } else if ((req = __elv_next_request(q))) { + if (req->flags & REQ_STARTED) + head = head->next; - el_ret = elevator->elevator_merge_fn(q, &req, head, bh, rw,max_sectors); - switch (el_ret) { + req = NULL; + } + el_ret = elevator->elevator_merge_fn(q, &req, head, bio); + switch (el_ret) { case ELEVATOR_BACK_MERGE: - if (!q->back_merge_fn(q, req, bh, max_segments)) + BUG_ON(req->flags & REQ_STARTED); + BUG_ON(req->flags & REQ_NOMERGE); + if (!q->back_merge_fn(q, req, bio)) break; - elevator->elevator_merge_cleanup_fn(q, req, count); - req->bhtail->b_reqnext = bh; - req->bhtail = bh; - req->nr_sectors = req->hard_nr_sectors += count; - blk_started_io(count); - drive_stat_acct(req->rq_dev, req->cmd, count, 0); - attempt_back_merge(q, req, max_sectors, max_segments); + + elevator->elevator_merge_cleanup_fn(q, req, nr_sectors); + + req->biotail->bi_next = bio; + req->biotail = bio; + req->nr_sectors = req->hard_nr_sectors += nr_sectors; + drive_stat_acct(req, nr_sectors, 0); + attempt_back_merge(q, req); goto out; case ELEVATOR_FRONT_MERGE: - if (!q->front_merge_fn(q, req, bh, max_segments)) + BUG_ON(req->flags & REQ_STARTED); + BUG_ON(req->flags & REQ_NOMERGE); + if (!q->front_merge_fn(q, req, bio)) break; - elevator->elevator_merge_cleanup_fn(q, req, count); - bh->b_reqnext = req->bh; - req->bh = bh; - req->buffer = bh->b_data; - req->current_nr_sectors = count; + + elevator->elevator_merge_cleanup_fn(q, req, nr_sectors); + + bio->bi_next = req->bio; + req->bio = bio; + /* + * may not be valid. if the low level driver said + * it didn't need a bounce buffer then it better + * not touch req->buffer either... + */ + req->buffer = bio_data(bio); + req->current_nr_sectors = cur_nr_sectors; + req->hard_cur_sectors = cur_nr_sectors; req->sector = req->hard_sector = sector; - req->nr_sectors = req->hard_nr_sectors += count; - blk_started_io(count); - drive_stat_acct(req->rq_dev, req->cmd, count, 0); - attempt_front_merge(q, head, req, max_sectors, max_segments); + req->nr_sectors = req->hard_nr_sectors += nr_sectors; + drive_stat_acct(req, nr_sectors, 0); + attempt_front_merge(q, head, req); goto out; /* @@ -730,14 +1170,14 @@ * of the queue */ if (req) - insert_here = &req->queue; + insert_here = &req->queuelist; break; default: printk("elevator returned crap (%d)\n", el_ret); BUG(); } - + /* * Grab a free request from the freelist - if that is empty, check * if we are doing read ahead and abort instead of blocking for @@ -748,107 +1188,140 @@ req = freereq; freereq = NULL; } else if ((req = get_request(q, rw)) == NULL) { - spin_unlock_irq(&io_request_lock); - if (rw_ahead) + + spin_unlock_irq(q->queue_lock); + + /* + * READA bit set + */ + if (bio->bi_rw & (1 << BIO_RW_AHEAD)) { + set_bit(BIO_RW_BLOCK, &bio->bi_flags); goto end_io; + } - freereq = __get_request_wait(q, rw); + freereq = get_request_wait(q, rw); goto again; } -/* fill up the request-info, and add it to the queue */ + /* + * fill up the request-info, and add it to the queue + */ req->elevator_sequence = latency; - req->cmd = rw; + + /* + * first three bits are identical in rq->flags and bio->bi_rw, + * see bio.h and blkdev.h + */ + req->flags = (bio->bi_rw & 7) | REQ_CMD; + + /* + * REQ_BARRIER implies no merging, but lets make it explicit + */ + if (barrier) + req->flags |= (REQ_BARRIER | REQ_NOMERGE); + req->errors = 0; req->hard_sector = req->sector = sector; - req->hard_nr_sectors = req->nr_sectors = count; - req->current_nr_sectors = count; - req->nr_segments = 1; /* Always 1 for a new request. */ - req->nr_hw_segments = 1; /* Always 1 for a new request. */ - req->buffer = bh->b_data; + req->hard_nr_sectors = req->nr_sectors = nr_sectors; + req->current_nr_sectors = req->hard_cur_sectors = cur_nr_sectors; + req->nr_phys_segments = bio_phys_segments(q, bio); + req->nr_hw_segments = bio_hw_segments(q, bio); + req->buffer = bio_data(bio); /* see ->buffer comment above */ req->waiting = NULL; - req->bh = bh; - req->bhtail = bh; - req->rq_dev = bh->b_rdev; - blk_started_io(count); + req->bio = req->biotail = bio; + req->rq_dev = bio->bi_dev; add_request(q, req, insert_here); out: if (freereq) blkdev_release_request(freereq); - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(q->queue_lock); return 0; + end_io: - bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state)); + bio->bi_end_io(bio, nr_sectors); return 0; } + +/* + * If bio->bi_dev is a partition, remap the location + */ +static inline void blk_partition_remap(struct bio *bio) +{ + int major, minor, drive, minor0; + struct gendisk *g; + kdev_t dev0; + + major = MAJOR(bio->bi_dev); + if ((g = get_gendisk(bio->bi_dev))) { + minor = MINOR(bio->bi_dev); + drive = (minor >> g->minor_shift); + minor0 = (drive << g->minor_shift); /* whole disk device */ + /* that is, minor0 = (minor & ~((1<minor_shift)-1)); */ + dev0 = MKDEV(major, minor0); + if (dev0 != bio->bi_dev) { + bio->bi_dev = dev0; + bio->bi_sector += g->part[minor].start_sect; + } + /* lots of checks are possible */ + } +} + /** - * generic_make_request: hand a buffer head to it's device driver for I/O - * @rw: READ, WRITE, or READA - what sort of I/O is desired. - * @bh: The buffer head describing the location in memory and on the device. + * generic_make_request: hand a buffer to it's device driver for I/O + * @bio: The bio describing the location in memory and on the device. * * generic_make_request() is used to make I/O requests of block - * devices. It is passed a &struct buffer_head and a &rw value. The - * %READ and %WRITE options are (hopefully) obvious in meaning. The - * %READA value means that a read is required, but that the driver is - * free to fail the request if, for example, it cannot get needed - * resources immediately. + * devices. It is passed a &struct bio, which describes the I/O that needs + * to be done. * * generic_make_request() does not return any status. The * success/failure status of the request, along with notification of - * completion, is delivered asynchronously through the bh->b_end_io + * completion, is delivered asynchronously through the bio->bi_end_io * function described (one day) else where. * - * The caller of generic_make_request must make sure that b_page, - * b_addr, b_size are set to describe the memory buffer, that b_rdev - * and b_rsector are set to describe the device address, and the - * b_end_io and optionally b_private are set to describe how - * completion notification should be signaled. BH_Mapped should also - * be set (to confirm that b_dev and b_blocknr are valid). - * - * generic_make_request and the drivers it calls may use b_reqnext, - * and may change b_rdev and b_rsector. So the values of these fields + * The caller of generic_make_request must make sure that bi_io_vec + * are set to describe the memory buffer, and that bi_dev and bi_sector are + * set to describe the device address, and the + * bi_end_io and optionally bi_private are set to describe how + * completion notification should be signaled. + * + * generic_make_request and the drivers it calls may use bi_next if this + * bio happens to be merged with someone else, and may change bi_dev and + * bi_sector for remaps as it sees fit. So the values of these fields * should NOT be depended on after the call to generic_make_request. - * Because of this, the caller should record the device address - * information in b_dev and b_blocknr. * - * Apart from those fields mentioned above, no other fields, and in - * particular, no other flags, are changed by generic_make_request or - * any lower level drivers. * */ -void generic_make_request (int rw, struct buffer_head * bh) +void generic_make_request(struct bio *bio) { - int major = MAJOR(bh->b_rdev); - int minorsize = 0; + int major = MAJOR(bio->bi_dev); + int minor = MINOR(bio->bi_dev); request_queue_t *q; + sector_t minorsize = 0; + int nr_sectors = bio_sectors(bio); - if (!bh->b_end_io) - BUG(); - - /* Test device size, when known. */ + /* Test device or partition size, when known. */ if (blk_size[major]) - minorsize = blk_size[major][MINOR(bh->b_rdev)]; + minorsize = blk_size[major][minor]; if (minorsize) { unsigned long maxsector = (minorsize << 1) + 1; - unsigned long sector = bh->b_rsector; - unsigned int count = bh->b_size >> 9; + unsigned long sector = bio->bi_sector; - if (maxsector < count || maxsector - count < sector) { - /* Yecch */ - bh->b_state &= (1 << BH_Lock) | (1 << BH_Mapped); - - /* This may well happen - the kernel calls bread() - without checking the size of the device, e.g., - when mounting a device. */ - printk(KERN_INFO - "attempt to access beyond end of device\n"); - printk(KERN_INFO "%s: rw=%d, want=%ld, limit=%d\n", - kdevname(bh->b_rdev), rw, - (sector + count)>>1, minorsize); - - /* Yecch again */ - bh->b_end_io(bh, 0); - return; + if (maxsector < nr_sectors || maxsector - nr_sectors < sector) { + if (blk_size[major][minor]) { + + /* This may well happen - the kernel calls + * bread() without checking the size of the + * device, e.g., when mounting a device. */ + printk(KERN_INFO + "attempt to access beyond end of device\n"); + printk(KERN_INFO "%s: rw=%ld, want=%ld, limit=%Lu\n", + kdevname(bio->bi_dev), bio->bi_rw, + (sector + nr_sectors)>>1, + (long long) blk_size[major][minor]); + } + set_bit(BIO_EOF, &bio->bi_flags); + goto end_io; } } @@ -856,63 +1329,115 @@ * Resolve the mapping until finished. (drivers are * still free to implement/resolve their own stacking * by explicitly returning 0) - */ - /* NOTE: we don't repeat the blk_size check for each new device. + * + * NOTE: we don't repeat the blk_size check for each new device. * Stacking drivers are expected to know what they are doing. */ do { - q = blk_get_queue(bh->b_rdev); + q = blk_get_queue(bio->bi_dev); if (!q) { printk(KERN_ERR - "generic_make_request: Trying to access " - "nonexistent block-device %s (%ld)\n", - kdevname(bh->b_rdev), bh->b_rsector); - buffer_IO_error(bh); + "generic_make_request: Trying to access nonexistent block-device %s (%Lu)\n", + kdevname(bio->bi_dev), (long long) bio->bi_sector); +end_io: + bio->bi_end_io(bio, nr_sectors); break; } - } while (q->make_request_fn(q, rw, bh)); + + BUG_ON(bio_sectors(bio) > q->max_sectors); + + /* + * If this device has partitions, remap block n + * of partition p to block n+start(p) of the disk. + */ + blk_partition_remap(bio); + + } while (q->make_request_fn(q, bio)); } +/* + * our default bio end_io callback handler for a buffer_head mapping. + */ +static int end_bio_bh_io_sync(struct bio *bio, int nr_sectors) +{ + struct buffer_head *bh = bio->bi_private; + + BIO_BUG_ON(nr_sectors != (bh->b_size >> 9)); + + bh->b_end_io(bh, test_bit(BIO_UPTODATE, &bio->bi_flags)); + bio_put(bio); + return 0; +} /** - * submit_bh: submit a buffer_head to the block device later for I/O + * submit_bio: submit a bio to the block device layer for I/O * @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead) - * @bh: The &struct buffer_head which describes the I/O + * @bio: The &struct bio which describes the I/O * - * submit_bh() is very similar in purpose to generic_make_request(), and - * uses that function to do most of the work. + * submit_bio() is very similar in purpose to generic_make_request(), and + * uses that function to do most of the work. Both are fairly rough + * interfaces, @bio must be presetup and ready for I/O. * - * The extra functionality provided by submit_bh is to determine - * b_rsector from b_blocknr and b_size, and to set b_rdev from b_dev. - * This is is appropriate for IO requests that come from the buffer - * cache and page cache which (currently) always use aligned blocks. */ -void submit_bh(int rw, struct buffer_head * bh) +int submit_bio(int rw, struct bio *bio) +{ + int count = bio_sectors(bio); + + /* + * do some validity checks... + */ + BUG_ON(!bio->bi_end_io); + + BIO_BUG_ON(!bio->bi_size); + BIO_BUG_ON(!bio->bi_io_vec); + + bio->bi_rw = rw; + + if (rw & WRITE) + kstat.pgpgout += count; + else + kstat.pgpgin += count; + + generic_make_request(bio); + return 1; +} + +/** + * submit_bh: submit a buffer_head to the block device layer for I/O + * @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead) + * @bh: The &struct buffer_head which describes the I/O + * + **/ +int submit_bh(int rw, struct buffer_head * bh) { - int count = bh->b_size >> 9; + struct bio *bio; - if (!test_bit(BH_Lock, &bh->b_state)) - BUG(); + BUG_ON(!test_bit(BH_Lock, &bh->b_state)); + BUG_ON(!buffer_mapped(bh)); + BUG_ON(!bh->b_end_io); set_bit(BH_Req, &bh->b_state); /* - * First step, 'identity mapping' - RAID or LVM might - * further remap this. + * from here on down, it's all bio -- do the initial mapping, + * submit_bio -> generic_make_request may further map this bio around */ - bh->b_rdev = bh->b_dev; - bh->b_rsector = bh->b_blocknr * count; + bio = bio_alloc(GFP_NOIO, 1); - generic_make_request(rw, bh); + bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9); + bio->bi_dev = bh->b_dev; + bio->bi_io_vec[0].bv_page = bh->b_page; + bio->bi_io_vec[0].bv_len = bh->b_size; + bio->bi_io_vec[0].bv_offset = bh_offset(bh); + + bio->bi_vcnt = 1; + bio->bi_idx = 0; + bio->bi_size = bh->b_size; - switch (rw) { - case WRITE: - kstat.pgpgout += count; - break; - default: - kstat.pgpgin += count; - break; - } + bio->bi_end_io = end_bio_bh_io_sync; + bio->bi_private = bh; + + return submit_bio(rw, bio); } /** @@ -944,8 +1469,9 @@ * * Caveat: * All of the buffers must be for the same device, and must also be - * of the current approved size for the device. */ - + * a multiple of the current approved size for the device. + * + **/ void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]) { unsigned int major; @@ -963,7 +1489,7 @@ /* Verify requested block sizes. */ for (i = 0; i < nr; i++) { struct buffer_head *bh = bhs[i]; - if (bh->b_size % correct_size) { + if (bh->b_size & (correct_size - 1)) { printk(KERN_NOTICE "ll_rw_block: device %s: " "only %d-char blocks implemented (%u)\n", kdevname(bhs[0]->b_dev), @@ -1024,12 +1550,51 @@ extern int stram_device_init (void); #endif +inline void blk_recalc_rq_segments(struct request *rq) +{ + struct bio *bio; + int nr_phys_segs, nr_hw_segs; + + rq->buffer = bio_data(rq->bio); + + nr_phys_segs = nr_hw_segs = 0; + rq_for_each_bio(bio, rq) { + /* Force bio hw/phys segs to be recalculated. */ + bio->bi_flags &= ~(1 << BIO_SEG_VALID); + + nr_phys_segs += bio_phys_segments(rq->q, bio); + nr_hw_segs += bio_hw_segments(rq->q, bio); + } + + rq->nr_phys_segments = nr_phys_segs; + rq->nr_hw_segments = nr_hw_segs; +} + +inline void blk_recalc_rq_sectors(struct request *rq, int nsect) +{ + rq->hard_sector += nsect; + rq->hard_nr_sectors -= nsect; + rq->sector = rq->hard_sector; + rq->nr_sectors = rq->hard_nr_sectors; + + rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9; + rq->hard_cur_sectors = rq->current_nr_sectors; + + /* + * if total number of sectors is less than the first segment + * size, something has gone terribly wrong + */ + if (rq->nr_sectors < rq->current_nr_sectors) { + printk("blk: request botched\n"); + rq->nr_sectors = rq->current_nr_sectors; + } +} /** * end_that_request_first - end I/O on one buffer. * @req: the request being processed * @uptodate: 0 for I/O error - * @name: the name printed for an I/O error + * @nr_sectors: number of sectors to end I/O on * * Description: * Ends I/O on the first buffer attached to @req, and sets it up @@ -1038,49 +1603,75 @@ * Return: * 0 - we are done with this request, call end_that_request_last() * 1 - still buffers pending for this request - * - * Caveat: - * Drivers implementing their own end_request handling must call - * blk_finished_io() appropriately. **/ -int end_that_request_first (struct request *req, int uptodate, char *name) +int end_that_request_first(struct request *req, int uptodate, int nr_sectors) { - struct buffer_head * bh; - int nsect; + int nsect, total_nsect; + struct bio *bio; req->errors = 0; if (!uptodate) - printk("end_request: I/O error, dev %s (%s), sector %lu\n", - kdevname(req->rq_dev), name, req->sector); + printk("end_request: I/O error, dev %s, sector %lu\n", + kdevname(req->rq_dev), req->sector); - if ((bh = req->bh) != NULL) { - nsect = bh->b_size >> 9; - blk_finished_io(nsect); - req->bh = bh->b_reqnext; - bh->b_reqnext = NULL; - bh->b_end_io(bh, uptodate); - if ((bh = req->bh) != NULL) { - req->hard_sector += nsect; - req->hard_nr_sectors -= nsect; - req->sector = req->hard_sector; - req->nr_sectors = req->hard_nr_sectors; - - req->current_nr_sectors = bh->b_size >> 9; - if (req->nr_sectors < req->current_nr_sectors) { - req->nr_sectors = req->current_nr_sectors; - printk("end_request: buffer-list destroyed\n"); - } - req->buffer = bh->b_data; + total_nsect = 0; + while ((bio = req->bio)) { + nsect = bio_iovec(bio)->bv_len >> 9; + + BIO_BUG_ON(bio_iovec(bio)->bv_len > bio->bi_size); + + /* + * not a complete bvec done + */ + if (unlikely(nsect > nr_sectors)) { + int residual = (nsect - nr_sectors) << 9; + + bio->bi_size -= residual; + bio_iovec(bio)->bv_offset += residual; + bio_iovec(bio)->bv_len -= residual; + blk_recalc_rq_sectors(req, nr_sectors); + blk_recalc_rq_segments(req); return 1; } + + /* + * account transfer + */ + bio->bi_size -= bio_iovec(bio)->bv_len; + bio->bi_idx++; + + nr_sectors -= nsect; + total_nsect += nsect; + + if (!bio->bi_size) { + req->bio = bio->bi_next; + + if (unlikely(bio_endio(bio, uptodate, total_nsect))) + BUG(); + + total_nsect = 0; + } + + if ((bio = req->bio)) { + blk_recalc_rq_sectors(req, nsect); + + /* + * end more in this run, or just return 'not-done' + */ + if (unlikely(nr_sectors <= 0)) { + blk_recalc_rq_segments(req); + return 1; + } + } } + return 0; } void end_that_request_last(struct request *req) { - if (req->waiting != NULL) + if (req->waiting) complete(req->waiting); blkdev_release_request(req); @@ -1105,7 +1696,6 @@ memset(ro_bits,0,sizeof(ro_bits)); memset(max_readahead, 0, sizeof(max_readahead)); - memset(max_sectors, 0, sizeof(max_sectors)); total_ram = nr_free_pages() << (PAGE_SHIFT - 10); @@ -1115,129 +1705,53 @@ */ queue_nr_requests = 64; if (total_ram > MB(32)) - queue_nr_requests = 128; + queue_nr_requests = 256; /* * Batch frees according to queue length */ - batch_requests = queue_nr_requests/4; + if ((batch_requests = queue_nr_requests / 4) > 32) + batch_requests = 32; printk("block: %d slots per queue, batch=%d\n", queue_nr_requests, batch_requests); -#ifdef CONFIG_AMIGA_Z2RAM - z2_init(); -#endif -#ifdef CONFIG_STRAM_SWAP - stram_device_init(); -#endif -#ifdef CONFIG_BLK_DEV_RAM - rd_init(); -#endif -#ifdef CONFIG_ISP16_CDI - isp16_init(); -#endif + blk_max_low_pfn = max_low_pfn; + blk_max_pfn = max_pfn; + #if defined(CONFIG_IDE) && defined(CONFIG_BLK_DEV_IDE) ide_init(); /* this MUST precede hd_init */ #endif #if defined(CONFIG_IDE) && defined(CONFIG_BLK_DEV_HD) hd_init(); #endif -#ifdef CONFIG_BLK_DEV_PS2 - ps2esdi_init(); -#endif -#ifdef CONFIG_BLK_DEV_XD - xd_init(); -#endif -#ifdef CONFIG_BLK_DEV_MFM - mfm_init(); -#endif -#ifdef CONFIG_PARIDE - { extern void paride_init(void); paride_init(); }; -#endif -#ifdef CONFIG_MAC_FLOPPY - swim3_init(); -#endif -#ifdef CONFIG_BLK_DEV_SWIM_IOP - swimiop_init(); -#endif -#ifdef CONFIG_AMIGA_FLOPPY - amiga_floppy_init(); -#endif -#ifdef CONFIG_ATARI_FLOPPY - atari_floppy_init(); -#endif -#ifdef CONFIG_BLK_DEV_FD - floppy_init(); -#else #if defined(__i386__) /* Do we even need this? */ outb_p(0xc, 0x3f2); #endif -#endif -#ifdef CONFIG_CDU31A - cdu31a_init(); -#endif -#ifdef CONFIG_ATARI_ACSI - acsi_init(); -#endif -#ifdef CONFIG_MCD - mcd_init(); -#endif -#ifdef CONFIG_MCDX - mcdx_init(); -#endif -#ifdef CONFIG_SBPCD - sbpcd_init(); -#endif -#ifdef CONFIG_AZTCD - aztcd_init(); -#endif -#ifdef CONFIG_CDU535 - sony535_init(); -#endif -#ifdef CONFIG_GSCD - gscd_init(); -#endif -#ifdef CONFIG_CM206 - cm206_init(); -#endif -#ifdef CONFIG_OPTCD - optcd_init(); -#endif -#ifdef CONFIG_SJCD - sjcd_init(); -#endif -#ifdef CONFIG_APBLOCK - ap_init(); -#endif -#ifdef CONFIG_DDV - ddv_init(); -#endif -#ifdef CONFIG_MDISK - mdisk_init(); -#endif -#ifdef CONFIG_DASD - dasd_init(); -#endif -#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_BLOCK) - tapeblock_init(); -#endif -#ifdef CONFIG_BLK_DEV_XPRAM - xpram_init(); -#endif -#ifdef CONFIG_SUN_JSFLASH - jsfd_init(); -#endif return 0; }; -EXPORT_SYMBOL(io_request_lock); EXPORT_SYMBOL(end_that_request_first); EXPORT_SYMBOL(end_that_request_last); EXPORT_SYMBOL(blk_init_queue); EXPORT_SYMBOL(blk_get_queue); EXPORT_SYMBOL(blk_cleanup_queue); -EXPORT_SYMBOL(blk_queue_headactive); EXPORT_SYMBOL(blk_queue_make_request); +EXPORT_SYMBOL(blk_queue_bounce_limit); EXPORT_SYMBOL(generic_make_request); EXPORT_SYMBOL(blkdev_release_request); EXPORT_SYMBOL(generic_unplug_device); +EXPORT_SYMBOL(blk_attempt_remerge); +EXPORT_SYMBOL(blk_max_low_pfn); +EXPORT_SYMBOL(blk_queue_max_sectors); +EXPORT_SYMBOL(blk_queue_max_phys_segments); +EXPORT_SYMBOL(blk_queue_max_hw_segments); +EXPORT_SYMBOL(blk_queue_max_segment_size); +EXPORT_SYMBOL(blk_queue_hardsect_size); +EXPORT_SYMBOL(blk_queue_segment_boundary); +EXPORT_SYMBOL(blk_rq_map_sg); +EXPORT_SYMBOL(blk_nohighio); +EXPORT_SYMBOL(blk_dump_rq_flags); +EXPORT_SYMBOL(submit_bio); +EXPORT_SYMBOL(blk_queue_assign_lock); +EXPORT_SYMBOL(blk_phys_contig_segment); +EXPORT_SYMBOL(blk_hw_contig_segment); diff -u --recursive --new-file v2.5.0/linux/drivers/block/loop.c linux/drivers/block/loop.c --- v2.5.0/linux/drivers/block/loop.c Mon Nov 19 14:48:02 2001 +++ linux/drivers/block/loop.c Fri Nov 30 08:33:50 2001 @@ -168,8 +168,7 @@ lo->lo_device); } -static int lo_send(struct loop_device *lo, struct buffer_head *bh, int bsize, - loff_t pos) +static int lo_send(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos) { struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ struct address_space *mapping = file->f_dentry->d_inode->i_mapping; @@ -183,8 +182,8 @@ down(&mapping->host->i_sem); index = pos >> PAGE_CACHE_SHIFT; offset = pos & (PAGE_CACHE_SIZE - 1); - len = bh->b_size; - data = bh->b_data; + len = bio->bi_size; + data = bio_data(bio); while (len > 0) { int IV = index * (PAGE_CACHE_SIZE/bsize) + offset/bsize; int transfer_result; @@ -263,18 +262,17 @@ return size; } -static int lo_receive(struct loop_device *lo, struct buffer_head *bh, int bsize, - loff_t pos) +static int lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos) { struct lo_read_data cookie; read_descriptor_t desc; struct file *file; cookie.lo = lo; - cookie.data = bh->b_data; + cookie.data = bio_data(bio); cookie.bsize = bsize; desc.written = 0; - desc.count = bh->b_size; + desc.count = bio->bi_size; desc.buf = (char*)&cookie; desc.error = 0; spin_lock_irq(&lo->lo_lock); @@ -310,46 +308,52 @@ return IV; } -static int do_bh_filebacked(struct loop_device *lo, struct buffer_head *bh, int rw) +static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) { loff_t pos; int ret; - pos = ((loff_t) bh->b_rsector << 9) + lo->lo_offset; + pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; - if (rw == WRITE) - ret = lo_send(lo, bh, loop_get_bs(lo), pos); - else - ret = lo_receive(lo, bh, loop_get_bs(lo), pos); + do { + if (bio_rw(bio) == WRITE) + ret = lo_send(lo, bio, loop_get_bs(lo), pos); + else + ret = lo_receive(lo, bio, loop_get_bs(lo), pos); + + } while (++bio->bi_idx < bio->bi_vcnt); return ret; } -static void loop_end_io_transfer(struct buffer_head *bh, int uptodate); -static void loop_put_buffer(struct buffer_head *bh) +static int loop_end_io_transfer(struct bio *, int); +static void loop_put_buffer(struct bio *bio) { /* - * check b_end_io, may just be a remapped bh and not an allocated one + * check bi_end_io, may just be a remapped bio */ - if (bh && bh->b_end_io == loop_end_io_transfer) { - __free_page(bh->b_page); - kmem_cache_free(bh_cachep, bh); + if (bio && bio->bi_end_io == loop_end_io_transfer) { + int i; + for (i = 0; i < bio->bi_vcnt; i++) + __free_page(bio->bi_io_vec[i].bv_page); + + bio_put(bio); } } /* - * Add buffer_head to back of pending list + * Add bio to back of pending list */ -static void loop_add_bh(struct loop_device *lo, struct buffer_head *bh) +static void loop_add_bio(struct loop_device *lo, struct bio *bio) { unsigned long flags; spin_lock_irqsave(&lo->lo_lock, flags); - if (lo->lo_bhtail) { - lo->lo_bhtail->b_reqnext = bh; - lo->lo_bhtail = bh; + if (lo->lo_biotail) { + lo->lo_biotail->bi_next = bio; + lo->lo_biotail = bio; } else - lo->lo_bh = lo->lo_bhtail = bh; + lo->lo_bio = lo->lo_biotail = bio; spin_unlock_irqrestore(&lo->lo_lock, flags); up(&lo->lo_bh_mutex); @@ -358,112 +362,84 @@ /* * Grab first pending buffer */ -static struct buffer_head *loop_get_bh(struct loop_device *lo) +static struct bio *loop_get_bio(struct loop_device *lo) { - struct buffer_head *bh; + struct bio *bio; spin_lock_irq(&lo->lo_lock); - if ((bh = lo->lo_bh)) { - if (bh == lo->lo_bhtail) - lo->lo_bhtail = NULL; - lo->lo_bh = bh->b_reqnext; - bh->b_reqnext = NULL; + if ((bio = lo->lo_bio)) { + if (bio == lo->lo_biotail) + lo->lo_biotail = NULL; + lo->lo_bio = bio->bi_next; + bio->bi_next = NULL; } spin_unlock_irq(&lo->lo_lock); - return bh; + return bio; } /* - * when buffer i/o has completed. if BH_Dirty is set, this was a WRITE - * and lo->transfer stuff has already been done. if not, it was a READ - * so queue it for the loop thread and let it do the transfer out of - * b_end_io context (we don't want to do decrypt of a page with irqs + * if this was a WRITE lo->transfer stuff has already been done. for READs, + * queue it for the loop thread and let it do the transfer out of + * bi_end_io context (we don't want to do decrypt of a page with irqs * disabled) */ -static void loop_end_io_transfer(struct buffer_head *bh, int uptodate) +static int loop_end_io_transfer(struct bio *bio, int nr_sectors) { - struct loop_device *lo = &loop_dev[MINOR(bh->b_dev)]; + struct loop_device *lo = &loop_dev[MINOR(bio->bi_dev)]; + int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - if (!uptodate || test_bit(BH_Dirty, &bh->b_state)) { - struct buffer_head *rbh = bh->b_private; + if (!uptodate || bio_rw(bio) == WRITE) { + struct bio *rbh = bio->bi_private; - rbh->b_end_io(rbh, uptodate); + bio_endio(rbh, uptodate, nr_sectors); if (atomic_dec_and_test(&lo->lo_pending)) up(&lo->lo_bh_mutex); - loop_put_buffer(bh); + loop_put_buffer(bio); } else - loop_add_bh(lo, bh); + loop_add_bio(lo, bio); + + return 0; } -static struct buffer_head *loop_get_buffer(struct loop_device *lo, - struct buffer_head *rbh) +static struct bio *loop_get_buffer(struct loop_device *lo, struct bio *rbh) { - struct buffer_head *bh; + struct bio *bio; /* * for xfer_funcs that can operate on the same bh, do that */ if (lo->lo_flags & LO_FLAGS_BH_REMAP) { - bh = rbh; + bio = rbh; goto out_bh; } - do { - bh = kmem_cache_alloc(bh_cachep, SLAB_NOIO); - if (bh) - break; - - run_task_queue(&tq_disk); - schedule_timeout(HZ); - } while (1); - memset(bh, 0, sizeof(*bh)); - - bh->b_size = rbh->b_size; - bh->b_dev = rbh->b_rdev; - bh->b_state = (1 << BH_Req) | (1 << BH_Mapped) | (1 << BH_Lock); + bio = bio_copy(rbh, GFP_NOIO, rbh->bi_rw & WRITE); - /* - * easy way out, although it does waste some memory for < PAGE_SIZE - * blocks... if highmem bounce buffering can get away with it, - * so can we :-) - */ - do { - bh->b_page = alloc_page(GFP_NOIO); - if (bh->b_page) - break; - - run_task_queue(&tq_disk); - schedule_timeout(HZ); - } while (1); - - bh->b_data = page_address(bh->b_page); - bh->b_end_io = loop_end_io_transfer; - bh->b_private = rbh; - init_waitqueue_head(&bh->b_wait); + bio->bi_end_io = loop_end_io_transfer; + bio->bi_private = rbh; out_bh: - bh->b_rsector = rbh->b_rsector + (lo->lo_offset >> 9); + bio->bi_sector = rbh->bi_sector + (lo->lo_offset >> 9); + bio->bi_rw = rbh->bi_rw; spin_lock_irq(&lo->lo_lock); - bh->b_rdev = lo->lo_device; + bio->bi_dev = lo->lo_device; spin_unlock_irq(&lo->lo_lock); - return bh; + return bio; } -static int loop_make_request(request_queue_t *q, int rw, struct buffer_head *rbh) +static int loop_make_request(request_queue_t *q, struct bio *rbh) { - struct buffer_head *bh = NULL; + struct bio *bh = NULL; struct loop_device *lo; unsigned long IV; + int rw = bio_rw(rbh); - if (!buffer_locked(rbh)) - BUG(); - - if (MINOR(rbh->b_rdev) >= max_loop) + if (MINOR(rbh->bi_dev) >= max_loop) goto out; - lo = &loop_dev[MINOR(rbh->b_rdev)]; + lo = &loop_dev[MINOR(rbh->bi_dev)]; spin_lock_irq(&lo->lo_lock); if (lo->lo_state != Lo_bound) goto inactive; @@ -476,25 +452,17 @@ } else if (rw == READA) { rw = READ; } else if (rw != READ) { - printk(KERN_ERR "loop: unknown command (%d)\n", rw); + printk(KERN_ERR "loop: unknown command (%x)\n", rw); goto err; } -#if CONFIG_HIGHMEM - rbh = create_bounce(rw, rbh); -#endif + blk_queue_bounce(q, &rbh); /* * file backed, queue for loop_thread to handle */ if (lo->lo_flags & LO_FLAGS_DO_BMAP) { - /* - * rbh locked at this point, noone else should clear - * the dirty flag - */ - if (rw == WRITE) - set_bit(BH_Dirty, &rbh->b_state); - loop_add_bh(lo, rbh); + loop_add_bio(lo, rbh); return 0; } @@ -502,15 +470,14 @@ * piggy old buffer on original, and submit for I/O */ bh = loop_get_buffer(lo, rbh); - IV = loop_get_iv(lo, rbh->b_rsector); + IV = loop_get_iv(lo, rbh->bi_sector); if (rw == WRITE) { - set_bit(BH_Dirty, &bh->b_state); - if (lo_do_transfer(lo, WRITE, bh->b_data, rbh->b_data, - bh->b_size, IV)) + if (lo_do_transfer(lo, WRITE, bio_data(bh), bio_data(rbh), + bh->bi_size, IV)) goto err; } - generic_make_request(rw, bh); + generic_make_request(bh); return 0; err: @@ -518,14 +485,32 @@ up(&lo->lo_bh_mutex); loop_put_buffer(bh); out: - buffer_IO_error(rbh); + bio_io_error(rbh); return 0; inactive: spin_unlock_irq(&lo->lo_lock); goto out; } -static inline void loop_handle_bh(struct loop_device *lo,struct buffer_head *bh) +static int do_bio_blockbacked(struct loop_device *lo, struct bio *bio, + struct bio *rbh) +{ + unsigned long IV = loop_get_iv(lo, rbh->bi_sector); + struct bio_vec *to; + char *vto, *vfrom; + int ret = 0, i; + + bio_for_each_segment(to, bio, i) { + vfrom = page_address(rbh->bi_io_vec[i].bv_page) + rbh->bi_io_vec[i].bv_offset; + vto = page_address(to->bv_page) + to->bv_offset; + ret |= lo_do_transfer(lo, bio_data_dir(bio), vto, vfrom, + to->bv_len, IV); + } + + return ret; +} + +static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio) { int ret; @@ -533,19 +518,15 @@ * For block backed loop, we know this is a READ */ if (lo->lo_flags & LO_FLAGS_DO_BMAP) { - int rw = !!test_and_clear_bit(BH_Dirty, &bh->b_state); - - ret = do_bh_filebacked(lo, bh, rw); - bh->b_end_io(bh, !ret); + ret = do_bio_filebacked(lo, bio); + bio_endio(bio, !ret, bio_sectors(bio)); } else { - struct buffer_head *rbh = bh->b_private; - unsigned long IV = loop_get_iv(lo, rbh->b_rsector); + struct bio *rbh = bio->bi_private; - ret = lo_do_transfer(lo, READ, bh->b_data, rbh->b_data, - bh->b_size, IV); + ret = do_bio_blockbacked(lo, bio, rbh); - rbh->b_end_io(rbh, !ret); - loop_put_buffer(bh); + bio_endio(rbh, !ret, bio_sectors(bio)); + loop_put_buffer(bio); } } @@ -558,7 +539,7 @@ static int loop_thread(void *data) { struct loop_device *lo = data; - struct buffer_head *bh; + struct bio *bio; daemonize(); exit_files(current); @@ -592,12 +573,12 @@ if (!atomic_read(&lo->lo_pending)) break; - bh = loop_get_bh(lo); - if (!bh) { - printk("loop: missing bh\n"); + bio = loop_get_bio(lo); + if (!bio) { + printk("loop: missing bio\n"); continue; } - loop_handle_bh(lo, bh); + loop_handle_bio(lo, bio); /* * upped both for pending work and tear-down, lo_pending @@ -683,7 +664,7 @@ set_blocksize(dev, bs); - lo->lo_bh = lo->lo_bhtail = NULL; + lo->lo_bio = lo->lo_biotail = NULL; kernel_thread(loop_thread, lo, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); down(&lo->lo_sem); @@ -873,7 +854,7 @@ err = -ENXIO; break; } - err = put_user((unsigned long)loop_sizes[lo->lo_number] << 1, (unsigned long *) arg); + err = put_user((unsigned long) loop_sizes[lo->lo_number] << 1, (unsigned long *) arg); break; case BLKGETSIZE64: if (lo->lo_state != Lo_bound) { @@ -1019,11 +1000,11 @@ loop_sizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL); if (!loop_sizes) - goto out_sizes; + goto out_mem; loop_blksizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL); if (!loop_blksizes) - goto out_blksizes; + goto out_mem; blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), loop_make_request); @@ -1047,9 +1028,8 @@ printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop); return 0; -out_sizes: +out_mem: kfree(loop_dev); -out_blksizes: kfree(loop_sizes); printk(KERN_ERR "loop: ran out of memory\n"); return -ENOMEM; diff -u --recursive --new-file v2.5.0/linux/drivers/block/nbd.c linux/drivers/block/nbd.c --- v2.5.0/linux/drivers/block/nbd.c Fri Oct 26 15:39:02 2001 +++ linux/drivers/block/nbd.c Sun Dec 16 12:20:20 2001 @@ -62,6 +62,8 @@ static struct nbd_device nbd_dev[MAX_NBD]; static devfs_handle_t devfs_handle; +static spinlock_t nbd_lock = SPIN_LOCK_UNLOCKED; + #define DEBUG( s ) /* #define DEBUG( s ) printk( s ) */ @@ -149,30 +151,41 @@ void nbd_send_req(struct socket *sock, struct request *req) { - int result; + int result, rw, i, flags; struct nbd_request request; unsigned long size = req->nr_sectors << 9; DEBUG("NBD: sending control, "); request.magic = htonl(NBD_REQUEST_MAGIC); - request.type = htonl(req->cmd); + request.type = htonl(req->flags); request.from = cpu_to_be64( (u64) req->sector << 9); request.len = htonl(size); memcpy(request.handle, &req, sizeof(req)); - result = nbd_xmit(1, sock, (char *) &request, sizeof(request), req->cmd == WRITE ? MSG_MORE : 0); + rw = rq_data_dir(req); + + result = nbd_xmit(1, sock, (char *) &request, sizeof(request), rw & WRITE ? MSG_MORE : 0); if (result <= 0) FAIL("Sendmsg failed for control."); - if (req->cmd == WRITE) { - struct buffer_head *bh = req->bh; - DEBUG("data, "); - do { - result = nbd_xmit(1, sock, bh->b_data, bh->b_size, bh->b_reqnext == NULL ? 0 : MSG_MORE); - if (result <= 0) - FAIL("Send data failed."); - bh = bh->b_reqnext; - } while(bh); + if (rw & WRITE) { + struct bio *bio; + /* + * we are really probing at internals to determine + * whether to set MSG_MORE or not... + */ + rq_for_each_bio(bio, req) { + struct bio_vec *bvec; + bio_for_each_segment(bvec, bio, i) { + flags = 0; + if ((i < (bio->bi_vcnt - 1)) || bio->bi_next) + flags = MSG_MORE; + DEBUG("data, "); + result = nbd_xmit(1, sock, page_address(bvec->bv_page) + bvec->bv_offset, bvec->bv_len, flags); + if (result <= 0) + FAIL("Send data failed."); + } + } } return; @@ -204,15 +217,15 @@ HARDFAIL("Not enough magic."); if (ntohl(reply.error)) FAIL("Other side returned error."); - if (req->cmd == READ) { - struct buffer_head *bh = req->bh; + if (rq_data_dir(req) == READ) { + struct bio *bio = req->bio; DEBUG("data, "); do { - result = nbd_xmit(0, lo->sock, bh->b_data, bh->b_size, MSG_WAITALL); + result = nbd_xmit(0, lo->sock, bio_data(bio), bio->bi_size, MSG_WAITALL); if (result <= 0) HARDFAIL("Recv data failed."); - bh = bh->b_reqnext; - } while(bh); + bio = bio->bi_next; + } while(bio); } DEBUG("done.\n"); return req; @@ -250,7 +263,7 @@ goto out; } #endif - list_del(&req->queue); + blkdev_dequeue_request(req); up (&lo->queue_lock); nbd_end_request(req); @@ -285,7 +298,7 @@ } #endif req->errors++; - list_del(&req->queue); + blkdev_dequeue_request(req); up(&lo->queue_lock); nbd_end_request(req); @@ -321,10 +334,13 @@ if (dev >= MAX_NBD) FAIL("Minor too big."); /* Probably can not happen */ #endif + if (!(req->flags & REQ_CMD)) + goto error_out; + lo = &nbd_dev[dev]; if (!lo->file) FAIL("Request when not-ready."); - if ((req->cmd == WRITE) && (lo->flags & NBD_READ_ONLY)) + if ((rq_data_dir(req) == WRITE) && (lo->flags & NBD_READ_ONLY)) FAIL("Write on read-only"); #ifdef PARANOIA if (lo->magic != LO_MAGIC) @@ -333,22 +349,22 @@ #endif req->errors = 0; blkdev_dequeue_request(req); - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(q->queue_lock); down (&lo->queue_lock); - list_add(&req->queue, &lo->queue_head); + list_add(&req->queuelist, &lo->queue_head); nbd_send_req(lo->sock, req); /* Why does this block? */ up (&lo->queue_lock); - spin_lock_irq(&io_request_lock); + spin_lock_irq(q->queue_lock); continue; error_out: req->errors++; blkdev_dequeue_request(req); - spin_unlock(&io_request_lock); + spin_unlock(q->queue_lock); nbd_end_request(req); - spin_lock(&io_request_lock); + spin_lock(q->queue_lock); } return; } @@ -374,7 +390,7 @@ switch (cmd) { case NBD_DISCONNECT: printk("NBD_DISCONNECT\n") ; - sreq.cmd=2 ; /* shutdown command */ + sreq.flags = REQ_SPECIAL; /* FIXME: interpet as shutdown cmd */ if (!lo->sock) return -EINVAL ; nbd_send_req(lo->sock,&sreq) ; return 0 ; @@ -501,8 +517,7 @@ #endif blksize_size[MAJOR_NR] = nbd_blksizes; blk_size[MAJOR_NR] = nbd_sizes; - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_nbd_request); - blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_nbd_request, &nbd_lock); for (i = 0; i < MAX_NBD; i++) { nbd_dev[i].refcnt = 0; nbd_dev[i].file = NULL; diff -u --recursive --new-file v2.5.0/linux/drivers/block/paride/pcd.c linux/drivers/block/paride/pcd.c --- v2.5.0/linux/drivers/block/paride/pcd.c Sat Oct 27 02:03:47 2001 +++ linux/drivers/block/paride/pcd.c Wed Dec 12 13:51:57 2001 @@ -146,6 +146,8 @@ #include +static spinlock_t pcd_lock; + #ifndef MODULE #include "setup.h" @@ -355,7 +357,7 @@ } } - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST, &pcd_lock); read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */ for (i=0;irq_status == RQ_INACTIVE)) return; INIT_REQUEST; - if (CURRENT->cmd == READ) { + if (rq_data_dir(CURRENT) == READ) { unit = MINOR(CURRENT->rq_dev); if (unit != pcd_unit) { pcd_bufblk = -1; @@ -821,11 +823,11 @@ if (pcd_command(unit,rd_cmd,2048,"read block")) { pcd_bufblk = -1; - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pcd_lock,saved_flags); pcd_busy = 0; end_request(0); do_pcd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pcd_lock,saved_flags); return; } @@ -845,11 +847,11 @@ pcd_retries = 0; pcd_transfer(); if (!pcd_count) { - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pcd_lock,saved_flags); end_request(1); pcd_busy = 0; do_pcd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pcd_lock,saved_flags); return; } @@ -868,19 +870,19 @@ pi_do_claimed(PI,pcd_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pcd_lock,saved_flags); pcd_busy = 0; pcd_bufblk = -1; end_request(0); do_pcd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pcd_lock,saved_flags); return; } do_pcd_read(); - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pcd_lock,saved_flags); do_pcd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pcd_lock,saved_flags); } /* the audio_ioctl stuff is adapted from sr_ioctl.c */ diff -u --recursive --new-file v2.5.0/linux/drivers/block/paride/pd.c linux/drivers/block/paride/pd.c --- v2.5.0/linux/drivers/block/paride/pd.c Fri Nov 9 13:58:03 2001 +++ linux/drivers/block/paride/pd.c Sun Dec 16 15:38:31 2001 @@ -166,6 +166,8 @@ #include +static spinlock_t pd_lock = SPIN_LOCK_UNLOCKED; + #ifndef MODULE #include "setup.h" @@ -287,7 +289,6 @@ static struct hd_struct pd_hd[PD_DEVS]; static int pd_sizes[PD_DEVS]; static int pd_blocksizes[PD_DEVS]; -static int pd_maxsectors[PD_DEVS]; #define PD_NAMELEN 8 @@ -330,7 +331,6 @@ static int pd_cmd; /* current command READ/WRITE */ static int pd_unit; /* unit of current request */ static int pd_dev; /* minor of current request */ -static int pd_poffs; /* partition offset of current minor */ static char * pd_buf; /* buffer for request in progress */ static DECLARE_WAIT_QUEUE_HEAD(pd_wait_open); @@ -396,7 +396,8 @@ return -1; } q = BLK_DEFAULT_QUEUE(MAJOR_NR); - blk_init_queue(q, DEVICE_REQUEST); + blk_init_queue(q, DEVICE_REQUEST, &pd_lock); + blk_queue_max_sectors(q, cluster); read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */ pd_gendisk.major = major; @@ -406,9 +407,6 @@ for(i=0;ii_rdev)) return -EINVAL; - dev = MINOR(inode->i_rdev); + if (!inode || !inode->i_rdev) + return -EINVAL; unit = DEVICE_NR(inode->i_rdev); - if (dev >= PD_DEVS) return -EINVAL; - if (!PD.present) return -ENODEV; + if (!PD.present) + return -ENODEV; - switch (cmd) { + switch (cmd) { case CDROMEJECT: if (PD.access == 1) pd_eject(unit); return 0; - case HDIO_GETGEO: - if (!geo) return -EINVAL; - err = verify_area(VERIFY_WRITE,geo,sizeof(*geo)); - if (err) return err; + case HDIO_GETGEO: + if (!geo) return -EINVAL; + err = verify_area(VERIFY_WRITE,geo,sizeof(*geo)); + if (err) return err; if (PD.alt_geom) { - put_user(PD.capacity/(PD_LOG_HEADS*PD_LOG_SECTS), + put_user(PD.capacity/(PD_LOG_HEADS*PD_LOG_SECTS), (short *) &geo->cylinders); - put_user(PD_LOG_HEADS, (char *) &geo->heads); - put_user(PD_LOG_SECTS, (char *) &geo->sectors); + put_user(PD_LOG_HEADS, (char *) &geo->heads); + put_user(PD_LOG_SECTS, (char *) &geo->sectors); } else { - put_user(PD.cylinders, (short *) &geo->cylinders); - put_user(PD.heads, (char *) &geo->heads); - put_user(PD.sectors, (char *) &geo->sectors); + put_user(PD.cylinders, (short *) &geo->cylinders); + put_user(PD.heads, (char *) &geo->heads); + put_user(PD.sectors, (char *) &geo->sectors); } - put_user(pd_hd[dev].start_sect,(long *)&geo->start); - return 0; - case BLKRRPART: + put_user(get_start_sect(inode->i_rdev), (long *)&geo->start); + return 0; + case BLKRRPART: if (!capable(CAP_SYS_ADMIN)) return -EACCES; - return pd_revalidate(inode->i_rdev); + return pd_revalidate(inode->i_rdev); case BLKGETSIZE: case BLKGETSIZE64: case BLKROSET: @@ -488,9 +486,9 @@ case BLKFLSBUF: case BLKPG: return blk_ioctl(inode->i_rdev, cmd, arg); - default: - return -EINVAL; - } + default: + return -EINVAL; + } } static int pd_release (struct inode *inode, struct file *file) @@ -526,36 +524,32 @@ } static int pd_revalidate(kdev_t dev) +{ + int unit, res; + long flags; -{ int p, unit, minor; - long flags; - - unit = DEVICE_NR(dev); - if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV; + unit = DEVICE_NR(dev); + if ((unit >= PD_UNITS) || !PD.present) + return -ENODEV; - save_flags(flags); - cli(); - if (PD.access > 1) { - restore_flags(flags); - return -EBUSY; - } - pd_valid = 0; - restore_flags(flags); - - for (p=(PD_PARTNS-1);p>=0;p--) { - minor = p + unit*PD_PARTNS; - invalidate_device(MKDEV(MAJOR_NR, minor), 1); - pd_hd[minor].start_sect = 0; - pd_hd[minor].nr_sects = 0; - } + save_flags(flags); + cli(); + if (PD.access > 1) { + restore_flags(flags); + return -EBUSY; + } + pd_valid = 0; + restore_flags(flags); - if (pd_identify(unit)) - grok_partitions(&pd_gendisk,unit,1<nr_sectors; pd_count = CURRENT->current_nr_sectors; - bh = CURRENT->bh; - if ((pd_dev >= PD_DEVS) || ((pd_block+pd_count) > pd_hd[pd_dev].nr_sects)) { end_request(0); goto repeat; } - pd_cmd = CURRENT->cmd; - pd_poffs = pd_hd[pd_dev].start_sect; - pd_block += pd_poffs; + pd_cmd = rq_data_dir(CURRENT); pd_buf = CURRENT->buffer; pd_retries = 0; @@ -890,25 +877,25 @@ { long saved_flags; - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pd_lock,saved_flags); end_request(1); - if (!pd_run) { spin_unlock_irqrestore(&io_request_lock,saved_flags); + if (!pd_run) { spin_unlock_irqrestore(&pd_lock,saved_flags); return; } /* paranoia */ if (QUEUE_EMPTY || - (CURRENT->cmd != pd_cmd) || + (rq_data_dir(CURRENT) != pd_cmd) || (MINOR(CURRENT->rq_dev) != pd_dev) || (CURRENT->rq_status == RQ_INACTIVE) || - (CURRENT->sector+pd_poffs != pd_block)) + (CURRENT->sector != pd_block)) printk("%s: OUCH: request list changed unexpectedly\n", PD.name); pd_count = CURRENT->current_nr_sectors; pd_buf = CURRENT->buffer; - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pd_lock,saved_flags); } static void do_pd_read( void ) @@ -931,11 +918,11 @@ pi_do_claimed(PI,do_pd_read_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pd_lock,saved_flags); end_request(0); pd_busy = 0; do_pd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pd_lock,saved_flags); return; } pd_ide_command(unit,IDE_READ,pd_block,pd_run); @@ -955,11 +942,11 @@ pi_do_claimed(PI,do_pd_read_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pd_lock,saved_flags); end_request(0); pd_busy = 0; do_pd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pd_lock,saved_flags); return; } pi_read_block(PI,pd_buf,512); @@ -970,11 +957,11 @@ if (!pd_count) pd_next_buf(unit); } pi_disconnect(PI); - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pd_lock,saved_flags); end_request(1); pd_busy = 0; do_pd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pd_lock,saved_flags); } static void do_pd_write( void ) @@ -997,11 +984,11 @@ pi_do_claimed(PI,do_pd_write_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pd_lock,saved_flags); end_request(0); pd_busy = 0; do_pd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pd_lock,saved_flags); return; } pd_ide_command(unit,IDE_WRITE,pd_block,pd_run); @@ -1013,11 +1000,11 @@ pi_do_claimed(PI,do_pd_write_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pd_lock,saved_flags); end_request(0); pd_busy = 0; do_pd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pd_lock,saved_flags); return; } pi_write_block(PI,pd_buf,512); @@ -1042,19 +1029,19 @@ pi_do_claimed(PI,do_pd_write_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pd_lock,saved_flags); end_request(0); pd_busy = 0; do_pd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pd_lock,saved_flags); return; } pi_disconnect(PI); - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pd_lock,saved_flags); end_request(1); pd_busy = 0; do_pd_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pd_lock,saved_flags); } /* end of pd.c */ diff -u --recursive --new-file v2.5.0/linux/drivers/block/paride/pf.c linux/drivers/block/paride/pf.c --- v2.5.0/linux/drivers/block/paride/pf.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/block/paride/pf.c Sun Dec 16 12:20:20 2001 @@ -164,6 +164,8 @@ #include +static spinlock_t pf_spin_lock; + #ifndef MODULE #include "setup.h" @@ -340,56 +342,6 @@ } } -static inline int pf_new_segment(request_queue_t *q, struct request *req, int max_segments) -{ - if (max_segments > cluster) - max_segments = cluster; - - if (req->nr_segments < max_segments) { - req->nr_segments++; - return 1; - } - return 0; -} - -static int pf_back_merge_fn(request_queue_t *q, struct request *req, - struct buffer_head *bh, int max_segments) -{ - if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data) - return 1; - return pf_new_segment(q, req, max_segments); -} - -static int pf_front_merge_fn(request_queue_t *q, struct request *req, - struct buffer_head *bh, int max_segments) -{ - if (bh->b_data + bh->b_size == req->bh->b_data) - return 1; - return pf_new_segment(q, req, max_segments); -} - -static int pf_merge_requests_fn(request_queue_t *q, struct request *req, - struct request *next, int max_segments) -{ - int total_segments = req->nr_segments + next->nr_segments; - int same_segment; - - if (max_segments > cluster) - max_segments = cluster; - - same_segment = 0; - if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) { - total_segments--; - same_segment = 1; - } - - if (total_segments > max_segments) - return 0; - - req->nr_segments = total_segments; - return 1; -} - int pf_init (void) /* preliminary initialisation */ { int i; @@ -408,10 +360,9 @@ return -1; } q = BLK_DEFAULT_QUEUE(MAJOR_NR); - blk_init_queue(q, DEVICE_REQUEST); - q->back_merge_fn = pf_back_merge_fn; - q->front_merge_fn = pf_front_merge_fn; - q->merge_requests_fn = pf_merge_requests_fn; + blk_init_queue(q, DEVICE_REQUEST, &pf_spin_lock); + blk_queue_max_phys_segments(q, cluster); + blk_queue_max_hw_segments(q, cluster); read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */ for (i=0;inr_sectors; pf_count = CURRENT->current_nr_sectors; - bh = CURRENT->bh; - if ((pf_unit >= PF_UNITS) || (pf_block+pf_count > PF.capacity)) { end_request(0); goto repeat; } - pf_cmd = CURRENT->cmd; + pf_cmd = rq_data_dir(CURRENT); pf_buf = CURRENT->buffer; pf_retries = 0; @@ -931,16 +879,16 @@ { long saved_flags; - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pf_spin_lock,saved_flags); end_request(1); - if (!pf_run) { spin_unlock_irqrestore(&io_request_lock,saved_flags); + if (!pf_run) { spin_unlock_irqrestore(&pf_spin_lock,saved_flags); return; } /* paranoia */ if (QUEUE_EMPTY || - (CURRENT->cmd != pf_cmd) || + (rq_data_dir(CURRENT) != pf_cmd) || (DEVICE_NR(CURRENT->rq_dev) != pf_unit) || (CURRENT->rq_status == RQ_INACTIVE) || (CURRENT->sector != pf_block)) @@ -949,7 +897,7 @@ pf_count = CURRENT->current_nr_sectors; pf_buf = CURRENT->buffer; - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pf_spin_lock,saved_flags); } static void do_pf_read( void ) @@ -973,11 +921,11 @@ pi_do_claimed(PI,do_pf_read_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pf_spin_lock,saved_flags); end_request(0); pf_busy = 0; do_pf_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pf_spin_lock,saved_flags); return; } pf_mask = STAT_DRQ; @@ -999,11 +947,11 @@ pi_do_claimed(PI,do_pf_read_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pf_spin_lock,saved_flags); end_request(0); pf_busy = 0; do_pf_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pf_spin_lock,saved_flags); return; } pi_read_block(PI,pf_buf,512); @@ -1014,11 +962,11 @@ if (!pf_count) pf_next_buf(unit); } pi_disconnect(PI); - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pf_spin_lock,saved_flags); end_request(1); pf_busy = 0; do_pf_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pf_spin_lock,saved_flags); } static void do_pf_write( void ) @@ -1040,11 +988,11 @@ pi_do_claimed(PI,do_pf_write_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pf_spin_lock,saved_flags); end_request(0); pf_busy = 0; do_pf_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pf_spin_lock,saved_flags); return; } @@ -1057,11 +1005,11 @@ pi_do_claimed(PI,do_pf_write_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pf_spin_lock,saved_flags); end_request(0); pf_busy = 0; do_pf_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pf_spin_lock,saved_flags); return; } pi_write_block(PI,pf_buf,512); @@ -1087,19 +1035,19 @@ pi_do_claimed(PI,do_pf_write_start); return; } - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pf_spin_lock,saved_flags); end_request(0); pf_busy = 0; do_pf_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pf_spin_lock,saved_flags); return; } pi_disconnect(PI); - spin_lock_irqsave(&io_request_lock,saved_flags); + spin_lock_irqsave(&pf_spin_lock,saved_flags); end_request(1); pf_busy = 0; do_pf_request(NULL); - spin_unlock_irqrestore(&io_request_lock,saved_flags); + spin_unlock_irqrestore(&pf_spin_lock,saved_flags); } /* end of pf.c */ diff -u --recursive --new-file v2.5.0/linux/drivers/block/paride/pg.c linux/drivers/block/paride/pg.c --- v2.5.0/linux/drivers/block/paride/pg.c Thu Oct 11 09:04:57 2001 +++ linux/drivers/block/paride/pg.c Fri Nov 30 08:26:04 2001 @@ -276,7 +276,7 @@ pg_drive_count = 0; for (unit=0;unit= PG_UNITS) || (!PG.present)) return -ENODEV; - PG.access++; - - if (PG.access > 1) { - PG.access--; + if ( test_and_set_bit(0, &PG.access) ) { return -EBUSY; } @@ -590,7 +587,7 @@ PG.bufptr = kmalloc(PG_MAX_DATA,GFP_KERNEL); if (PG.bufptr == NULL) { - PG.access--; + clear_bit( 0, &PG.access ) ; printk("%s: buffer allocation failed\n",PG.name); return -ENOMEM; } @@ -602,15 +599,13 @@ { int unit = DEVICE_NR(inode->i_rdev); - if ((unit >= PG_UNITS) || (PG.access <= 0)) + if ( unit >= PG_UNITS || !test_bit(0,&PG.access) ) return -EINVAL; - lock_kernel(); - PG.access--; + clear_bit( 0, &PG.access); kfree(PG.bufptr); PG.bufptr = NULL; - unlock_kernel(); return 0; diff -u --recursive --new-file v2.5.0/linux/drivers/block/paride/pt.c linux/drivers/block/paride/pt.c --- v2.5.0/linux/drivers/block/paride/pt.c Thu Oct 11 09:04:57 2001 +++ linux/drivers/block/paride/pt.c Fri Nov 30 08:26:04 2001 @@ -244,7 +244,7 @@ int flags; /* various state flags */ int last_sense; /* result of last request sense */ int drive; /* drive */ - int access; /* count of active opens ... */ + atomic_t available; /* 1 if access is available 0 otherwise */ int bs; /* block size */ int capacity; /* Size of tape in KB */ int present; /* device present ? */ @@ -279,7 +279,7 @@ pt_drive_count = 0; for (unit=0;unit= PT_UNITS) || (!PT.present)) return -ENODEV; - PT.access++; - - if (PT.access > 1) { - PT.access--; + if ( !atomic_dec_and_test(&PT.available) ) { + atomic_inc( &PT.available ); return -EBUSY; } pt_identify(unit); if (!PT.flags & PT_MEDIA) { - PT.access--; + atomic_inc( &PT.available ); return -ENODEV; } if ((!PT.flags & PT_WRITE_OK) && (file ->f_mode & 2)) { - PT.access--; + atomic_inc( &PT.available ); return -EROFS; } @@ -720,7 +718,7 @@ PT.bufptr = kmalloc(PT_BUFSIZE,GFP_KERNEL); if (PT.bufptr == NULL) { - PT.access--; + atomic_inc( &PT.available ); printk("%s: buffer allocation failed\n",PT.name); return -ENOMEM; } @@ -775,20 +773,18 @@ { int unit = DEVICE_NR(inode->i_rdev); - if ((unit >= PT_UNITS) || (PT.access <= 0)) + if ((unit >= PT_UNITS) || (atomic_read(&PT.available) > 1)) return -EINVAL; - lock_kernel(); if (PT.flags & PT_WRITING) pt_write_fm(unit); if (PT.flags & PT_REWIND) pt_rewind(unit); - PT.access--; - kfree(PT.bufptr); PT.bufptr = NULL; - unlock_kernel(); + atomic_inc( &PT.available ); + return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c --- v2.5.0/linux/drivers/block/ps2esdi.c Fri Nov 9 14:01:21 2001 +++ linux/drivers/block/ps2esdi.c Sun Dec 16 12:20:20 2001 @@ -66,7 +66,6 @@ #define TYPE_0_CMD_BLK_LENGTH 2 #define TYPE_1_CMD_BLK_LENGTH 4 - static void reset_ctrl(void); int ps2esdi_init(void); @@ -118,7 +117,6 @@ static char ps2esdi_valid[MAX_HD]; static int ps2esdi_sizes[MAX_HD << 6]; static int ps2esdi_blocksizes[MAX_HD << 6]; -static int ps2esdi_maxsect[MAX_HD << 6]; static int ps2esdi_drives; static struct hd_struct ps2esdi[MAX_HD << 6]; static u_short io_base; @@ -130,6 +128,7 @@ struct ps2esdi_i_struct { unsigned int head, sect, cyl, wpcom, lzone, ctl; }; +static spinlock_t ps2esdi_lock = SPIN_LOCK_UNLOCKED; #if 0 #if 0 /* try both - I don't know which one is better... UB */ @@ -180,7 +179,7 @@ return -1; } /* set up some global information - indicating device specific info */ - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST, &ps2esdi_lock); read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */ /* some minor housekeeping - setup the global gendisk structure */ @@ -189,6 +188,8 @@ return 0; } /* ps2esdi_init */ +module_init(ps2esdi_init); + #ifdef MODULE static int cyl[MAX_HD] = {-1,-1}; @@ -221,8 +222,7 @@ } void -cleanup_module(void) -{ +cleanup_module(void) { if(ps2esdi_slot) { mca_mark_as_unused(ps2esdi_slot); mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL); @@ -231,8 +231,9 @@ free_dma(dma_arb_level); free_irq(PS2ESDI_IRQ, NULL); devfs_unregister_blkdev(MAJOR_NR, "ed"); - del_gendisk(&ps2esdi_gendisk); blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); + del_gendisk(&ps2esdi_gendisk); + blk_clear(MAJOR_NR); } #endif /* MODULE */ @@ -415,16 +416,13 @@ ps2esdi_gendisk.nr_real = ps2esdi_drives; - /* 128 was old default, maybe maxsect=255 is ok too? - Paul G. */ - for (i = 0; i < (MAX_HD << 6); i++) { - ps2esdi_maxsect[i] = 128; + for (i = 0; i < (MAX_HD << 6); i++) ps2esdi_blocksizes[i] = 1024; - } request_dma(dma_arb_level, "ed"); request_region(io_base, 4, "ed"); blksize_size[MAJOR_NR] = ps2esdi_blocksizes; - max_sectors[MAJOR_NR] = ps2esdi_maxsect; + blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), 128); for (i = 0; i < ps2esdi_drives; i++) { register_disk(&ps2esdi_gendisk,MKDEV(MAJOR_NR,i<<6),1<<6, @@ -486,7 +484,8 @@ } /* check for above 16Mb dmas */ else if ((CURRENT_DEV < ps2esdi_drives) && (CURRENT->sector + CURRENT->current_nr_sectors <= - ps2esdi[MINOR(CURRENT->rq_dev)].nr_sects)) { + ps2esdi[MINOR(CURRENT->rq_dev)].nr_sects) && + CURRENT->flags & REQ_CMD) { #if 0 printk("%s:got request. device : %d minor : %d command : %d sector : %ld count : %ld\n", DEVICE_NAME, @@ -495,14 +494,10 @@ CURRENT->current_nr_sectors); #endif - - block = CURRENT->sector + ps2esdi[MINOR(CURRENT->rq_dev)].start_sect; - -#if 0 - printk("%s: blocknumber : %d\n", DEVICE_NAME, block); -#endif + block = CURRENT->sector; count = CURRENT->current_nr_sectors; - switch (CURRENT->cmd) { + + switch (rq_data_dir(CURRENT)) { case READ: ps2esdi_readwrite(READ, CURRENT_DEV, block, count); break; @@ -958,10 +953,10 @@ break; } if(ending != -1) { - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(ps2esdi_LOCK, flags); end_request(ending); do_ps2esdi_request(BLK_DEFAULT_QUEUE(MAJOR_NR)); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(ps2esdi_LOCK, flags); } } /* handle interrupts */ @@ -1100,10 +1095,10 @@ put_user(ps2esdi_info[dev].head, (char *) &geometry->heads); put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors); put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders); - put_user(ps2esdi[MINOR(inode->i_rdev)].start_sect, + put_user(get_start_sect(inode->i_rdev), (long *) &geometry->start); - return (0); + return 0; } break; @@ -1132,8 +1127,7 @@ static int ps2esdi_reread_partitions(kdev_t dev) { int target = DEVICE_NR(dev); - int start = target << ps2esdi_gendisk.minor_shift; - int partition; + int res; cli(); ps2esdi_valid[target] = (access_count[target] != 1); @@ -1141,21 +1135,16 @@ if (ps2esdi_valid[target]) return (-EBUSY); - for (partition = ps2esdi_gendisk.max_p - 1; - partition >= 0; partition--) { - int minor = (start | partition); - invalidate_device(MKDEV(MAJOR_NR, minor), 1); - ps2esdi_gendisk.part[minor].start_sect = 0; - ps2esdi_gendisk.part[minor].nr_sects = 0; - } - - grok_partitions(&ps2esdi_gendisk, target, 1<<6, - ps2esdi_info[target].head * ps2esdi_info[target].cyl * ps2esdi_info[target].sect); - + res = wipe_partitions(dev); + if (res == 0) + grok_partitions(dev, ps2esdi_info[target].head + * ps2esdi_info[target].cyl + * ps2esdi_info[target].sect); + ps2esdi_valid[target] = 1; wake_up(&ps2esdi_wait_open); - return (0); + return (res); } static void ps2esdi_reset_timer(unsigned long unused) diff -u --recursive --new-file v2.5.0/linux/drivers/block/rd.c linux/drivers/block/rd.c --- v2.5.0/linux/drivers/block/rd.c Fri Nov 9 14:15:00 2001 +++ linux/drivers/block/rd.c Wed Dec 12 09:28:27 2001 @@ -44,9 +44,6 @@ #include #include -#include -#include -#include #include #include #include @@ -79,17 +76,9 @@ /* The RAM disk size is now a parameter */ #define NUM_RAMDISKS 16 /* This cannot be overridden (yet) */ -#ifndef MODULE -/* We don't have to load RAM disks or gunzip them in a module. */ -#define RD_LOADER -#define BUILD_CRAMDISK - -void rd_load(void); -static int crd_load(struct file *fp, struct file *outfp); - #ifdef CONFIG_BLK_DEV_INITRD static int initrd_users; -#endif +static spinlock_t initrd_users_lock = SPIN_LOCK_UNLOCKED; #endif /* Various static variables go here. Most are used only in the RAM disk code. @@ -98,7 +87,7 @@ static unsigned long rd_length[NUM_RAMDISKS]; /* Size of RAM disks in bytes */ static int rd_hardsec[NUM_RAMDISKS]; /* Size of real blocks in bytes */ static int rd_blocksizes[NUM_RAMDISKS]; /* Size of 1024 byte blocks :) */ -static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */ +static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */ static devfs_handle_t devfs_handle; static struct block_device *rd_bdev[NUM_RAMDISKS];/* Protected device data */ @@ -227,19 +216,19 @@ commit_write: ramdisk_commit_write, }; -static int rd_blkdev_pagecache_IO(int rw, struct buffer_head * sbh, int minor) +static int rd_blkdev_pagecache_IO(int rw, struct bio_vec *vec, + sector_t sector, int minor) { struct address_space * mapping; unsigned long index; int offset, size, err; - err = -EIO; err = 0; mapping = rd_bdev[minor]->bd_inode->i_mapping; - index = sbh->b_rsector >> (PAGE_CACHE_SHIFT - 9); - offset = (sbh->b_rsector << 9) & ~PAGE_CACHE_MASK; - size = sbh->b_size; + index = sector >> (PAGE_CACHE_SHIFT - 9); + offset = (sector << 9) & ~PAGE_CACHE_MASK; + size = vec->bv_len; do { int count; @@ -276,18 +265,18 @@ if (rw == READ) { src = kmap(page); src += offset; - dst = bh_kmap(sbh); + dst = kmap(vec->bv_page) + vec->bv_offset; } else { dst = kmap(page); dst += offset; - src = bh_kmap(sbh); + src = kmap(vec->bv_page) + vec->bv_offset; } offset = 0; memcpy(dst, src, count); kunmap(page); - bh_kunmap(sbh); + kunmap(vec->bv_page); if (rw == READ) { flush_dcache_page(page); @@ -303,6 +292,22 @@ return err; } +static int rd_blkdev_bio_IO(struct bio *bio, unsigned int minor) +{ + struct bio_vec *bvec; + sector_t sector; + int ret = 0, i, rw; + + sector = bio->bi_sector; + rw = bio_data_dir(bio); + bio_for_each_segment(bvec, bio, i) { + ret |= rd_blkdev_pagecache_IO(rw, bvec, sector, minor); + sector += bvec->bv_len >> 9; + } + + return ret; +} + /* * Basically, my strategy here is to set up a buffer-head which can't be * deleted, and make that my Ramdisk. If the request is outside of the @@ -311,19 +316,19 @@ * 19-JAN-1998 Richard Gooch Added devfs support * */ -static int rd_make_request(request_queue_t * q, int rw, struct buffer_head *sbh) +static int rd_make_request(request_queue_t * q, struct bio *sbh) { unsigned int minor; unsigned long offset, len; + int rw = sbh->bi_rw; - minor = MINOR(sbh->b_rdev); + minor = MINOR(sbh->bi_dev); if (minor >= NUM_RAMDISKS) goto fail; - - offset = sbh->b_rsector << 9; - len = sbh->b_size; + offset = sbh->bi_sector << 9; + len = sbh->bi_size; if ((offset + len) > rd_length[minor]) goto fail; @@ -335,13 +340,14 @@ goto fail; } - if (rd_blkdev_pagecache_IO(rw, sbh, minor)) + if (rd_blkdev_bio_IO(sbh, minor)) goto fail; - sbh->b_end_io(sbh,1); + set_bit(BIO_UPTODATE, &sbh->bi_flags); + sbh->bi_end_io(sbh, len >> 9); return 0; fail: - sbh->b_end_io(sbh,0); + bio_io_error(sbh); return 0; } @@ -408,12 +414,15 @@ { extern void free_initrd_mem(unsigned long, unsigned long); - lock_kernel(); + spin_lock(&initrd_users_lock); if (!--initrd_users) { + spin_unlock(&initrd_users_lock); free_initrd_mem(initrd_start, initrd_end); initrd_start = 0; + } else { + spin_unlock(&initrd_users_lock); } - unlock_kernel(); + blkdev_put(inode->i_bdev, BDEV_FILE); return 0; } @@ -433,8 +442,11 @@ #ifdef CONFIG_BLK_DEV_INITRD if (unit == INITRD_MINOR) { - if (!initrd_start) return -ENODEV; + spin_lock(&initrd_users_lock); initrd_users++; + spin_unlock(&initrd_users_lock); + if (!initrd_start) + return -ENODEV; filp->f_op = &initrd_fops; return 0; } @@ -461,7 +473,6 @@ ioctl: rd_ioctl, }; -#ifdef MODULE /* Before freeing the module, invalidate all of the protected buffers! */ static void __exit rd_cleanup (void) { @@ -477,11 +488,8 @@ devfs_unregister (devfs_handle); unregister_blkdev( MAJOR_NR, "ramdisk" ); - hardsect_size[MAJOR_NR] = NULL; - blksize_size[MAJOR_NR] = NULL; - blk_size[MAJOR_NR] = NULL; + blk_clear(MAJOR_NR); } -#endif /* This is the registration and initialization section of the RAM disk driver */ int __init rd_init (void) @@ -522,9 +530,10 @@ #ifdef CONFIG_BLK_DEV_INITRD /* We ought to separate initrd operations here */ register_disk(NULL, MKDEV(MAJOR_NR,INITRD_MINOR), 1, &rd_bd_op, rd_size<<1); + devfs_register(devfs_handle, "initrd", DEVFS_FL_DEFAULT, MAJOR_NR, + INITRD_MINOR, S_IFBLK | S_IRUSR, &rd_bd_op, NULL); #endif - hardsect_size[MAJOR_NR] = rd_hardsec; /* Size of the RAM disk blocks */ blksize_size[MAJOR_NR] = rd_blocksizes; /* Avoid set_blocksize() check */ blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */ @@ -536,10 +545,8 @@ return 0; } -#ifdef MODULE module_init(rd_init); module_exit(rd_cleanup); -#endif /* loadable module support */ MODULE_PARM (rd_size, "1i"); @@ -548,462 +555,3 @@ MODULE_PARM_DESC(rd_blocksize, "Blocksize of each RAM disk in bytes."); MODULE_LICENSE("GPL"); - -/* End of non-loading portions of the RAM disk driver */ - -#ifdef RD_LOADER -/* - * This routine tries to find a RAM disk image to load, and returns the - * number of blocks to read for a non-compressed image, 0 if the image - * is a compressed image, and -1 if an image with the right magic - * numbers could not be found. - * - * We currently check for the following magic numbers: - * minix - * ext2 - * romfs - * gzip - */ -static int __init -identify_ramdisk_image(kdev_t device, struct file *fp, int start_block) -{ - const int size = 512; - struct minix_super_block *minixsb; - struct ext2_super_block *ext2sb; - struct romfs_super_block *romfsb; - int nblocks = -1; - unsigned char *buf; - - buf = kmalloc(size, GFP_KERNEL); - if (buf == 0) - return -1; - - minixsb = (struct minix_super_block *) buf; - ext2sb = (struct ext2_super_block *) buf; - romfsb = (struct romfs_super_block *) buf; - memset(buf, 0xe5, size); - - /* - * Read block 0 to test for gzipped kernel - */ - if (fp->f_op->llseek) - fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0); - fp->f_pos = start_block * BLOCK_SIZE; - - fp->f_op->read(fp, buf, size, &fp->f_pos); - - /* - * If it matches the gzip magic numbers, return -1 - */ - if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) { - printk(KERN_NOTICE - "RAMDISK: Compressed image found at block %d\n", - start_block); - nblocks = 0; - goto done; - } - - /* romfs is at block zero too */ - if (romfsb->word0 == ROMSB_WORD0 && - romfsb->word1 == ROMSB_WORD1) { - printk(KERN_NOTICE - "RAMDISK: romfs filesystem found at block %d\n", - start_block); - nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; - goto done; - } - - /* - * Read block 1 to test for minix and ext2 superblock - */ - if (fp->f_op->llseek) - fp->f_op->llseek(fp, (start_block+1) * BLOCK_SIZE, 0); - fp->f_pos = (start_block+1) * BLOCK_SIZE; - - fp->f_op->read(fp, buf, size, &fp->f_pos); - - /* Try minix */ - if (minixsb->s_magic == MINIX_SUPER_MAGIC || - minixsb->s_magic == MINIX_SUPER_MAGIC2) { - printk(KERN_NOTICE - "RAMDISK: Minix filesystem found at block %d\n", - start_block); - nblocks = minixsb->s_nzones << minixsb->s_log_zone_size; - goto done; - } - - /* Try ext2 */ - if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { - printk(KERN_NOTICE - "RAMDISK: ext2 filesystem found at block %d\n", - start_block); - nblocks = le32_to_cpu(ext2sb->s_blocks_count); - goto done; - } - - printk(KERN_NOTICE - "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n", - start_block); - -done: - if (fp->f_op->llseek) - fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0); - fp->f_pos = start_block * BLOCK_SIZE; - - kfree(buf); - return nblocks; -} - -/* - * This routine loads in the RAM disk image. - */ -static void __init rd_load_image(kdev_t device, int offset, int unit) -{ - struct inode *inode, *out_inode; - struct file infile, outfile; - struct dentry in_dentry, out_dentry; - mm_segment_t fs; - kdev_t ram_device; - int nblocks, i; - char *buf; - unsigned short rotate = 0; - unsigned short devblocks = 0; -#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES) - char rotator[4] = { '|' , '/' , '-' , '\\' }; -#endif - ram_device = MKDEV(MAJOR_NR, unit); - - if ((inode = get_empty_inode()) == NULL) - return; - memset(&infile, 0, sizeof(infile)); - memset(&in_dentry, 0, sizeof(in_dentry)); - infile.f_mode = 1; /* read only */ - infile.f_dentry = &in_dentry; - in_dentry.d_inode = inode; - infile.f_op = &def_blk_fops; - init_special_inode(inode, S_IFBLK | S_IRUSR, kdev_t_to_nr(device)); - - if ((out_inode = get_empty_inode()) == NULL) - goto free_inode; - memset(&outfile, 0, sizeof(outfile)); - memset(&out_dentry, 0, sizeof(out_dentry)); - outfile.f_mode = 3; /* read/write */ - outfile.f_dentry = &out_dentry; - out_dentry.d_inode = out_inode; - outfile.f_op = &def_blk_fops; - init_special_inode(out_inode, S_IFBLK | S_IRUSR | S_IWUSR, kdev_t_to_nr(ram_device)); - - if (blkdev_open(inode, &infile) != 0) { - iput(out_inode); - goto free_inode; - } - if (blkdev_open(out_inode, &outfile) != 0) - goto free_inodes; - - fs = get_fs(); - set_fs(KERNEL_DS); - - nblocks = identify_ramdisk_image(device, &infile, offset); - if (nblocks < 0) - goto done; - - if (nblocks == 0) { -#ifdef BUILD_CRAMDISK - if (crd_load(&infile, &outfile) == 0) - goto successful_load; -#else - printk(KERN_NOTICE - "RAMDISK: Kernel does not support compressed " - "RAM disk images\n"); -#endif - goto done; - } - - /* - * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so - * rd_load_image will work only with filesystem BLOCK_SIZE wide! - * So make sure to use 1k blocksize while generating ext2fs - * ramdisk-images. - */ - if (nblocks > (rd_length[unit] >> BLOCK_SIZE_BITS)) { - printk("RAMDISK: image too big! (%d/%ld blocks)\n", - nblocks, rd_length[unit] >> BLOCK_SIZE_BITS); - goto done; - } - - /* - * OK, time to copy in the data - */ - buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); - if (buf == 0) { - printk(KERN_ERR "RAMDISK: could not allocate buffer\n"); - goto done; - } - - if (blk_size[MAJOR(device)]) - devblocks = blk_size[MAJOR(device)][MINOR(device)]; - -#ifdef CONFIG_BLK_DEV_INITRD - if (MAJOR(device) == MAJOR_NR && MINOR(device) == INITRD_MINOR) - devblocks = nblocks; -#endif - - if (devblocks == 0) { - printk(KERN_ERR "RAMDISK: could not determine device size\n"); - goto done; - } - - printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ", - nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : ""); - for (i=0; i < nblocks; i++) { - if (i && (i % devblocks == 0)) { - printk("done disk #%d.\n", i/devblocks); - rotate = 0; - if (infile.f_op->release(inode, &infile) != 0) { - printk("Error closing the disk.\n"); - goto noclose_input; - } - printk("Please insert disk #%d and press ENTER\n", i/devblocks+1); - wait_for_keypress(); - if (blkdev_open(inode, &infile) != 0) { - printk("Error opening disk.\n"); - goto noclose_input; - } - infile.f_pos = 0; - printk("Loading disk #%d... ", i/devblocks+1); - } - infile.f_op->read(&infile, buf, BLOCK_SIZE, &infile.f_pos); - outfile.f_op->write(&outfile, buf, BLOCK_SIZE, &outfile.f_pos); -#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES) - if (!(i % 16)) { - printk("%c\b", rotator[rotate & 0x3]); - rotate++; - } -#endif - } - printk("done.\n"); - kfree(buf); - -successful_load: - ROOT_DEV = MKDEV(MAJOR_NR, unit); - if (ROOT_DEVICE_NAME != NULL) strcpy (ROOT_DEVICE_NAME, "rd/0"); - -done: - infile.f_op->release(inode, &infile); -noclose_input: - blkdev_close(out_inode, &outfile); - iput(inode); - iput(out_inode); - set_fs(fs); - return; -free_inodes: /* free inodes on error */ - iput(out_inode); - infile.f_op->release(inode, &infile); -free_inode: - iput(inode); -} - -#ifdef CONFIG_MAC_FLOPPY -int swim3_fd_eject(int devnum); -#endif - -static void __init rd_load_disk(int n) -{ - - if (rd_doload == 0) - return; - - if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR -#ifdef CONFIG_BLK_DEV_INITRD - && MAJOR(real_root_dev) != FLOPPY_MAJOR -#endif - ) - return; - - if (rd_prompt) { -#ifdef CONFIG_BLK_DEV_FD - floppy_eject(); -#endif -#ifdef CONFIG_MAC_FLOPPY - if(MAJOR(ROOT_DEV) == FLOPPY_MAJOR) - swim3_fd_eject(MINOR(ROOT_DEV)); - else if(MAJOR(real_root_dev) == FLOPPY_MAJOR) - swim3_fd_eject(MINOR(real_root_dev)); -#endif - printk(KERN_NOTICE - "VFS: Insert root floppy disk to be loaded into RAM disk and press ENTER\n"); - wait_for_keypress(); - } - - rd_load_image(ROOT_DEV,rd_image_start, n); - -} - -void __init rd_load(void) -{ - rd_load_disk(0); -} - -void __init rd_load_secondary(void) -{ - rd_load_disk(1); -} - -#ifdef CONFIG_BLK_DEV_INITRD -void __init initrd_load(void) -{ - rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),rd_image_start,0); -} -#endif - -#endif /* RD_LOADER */ - -#ifdef BUILD_CRAMDISK - -/* - * gzip declarations - */ - -#define OF(args) args - -#ifndef memzero -#define memzero(s, n) memset ((s), 0, (n)) -#endif - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define INBUFSIZ 4096 -#define WSIZE 0x8000 /* window size--must be a power of two, and */ - /* at least 32K for zip's deflate method */ - -static uch *inbuf; -static uch *window; - -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ -static int exit_code; -static long bytes_out; -static struct file *crd_infp, *crd_outfp; - -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - -/* Diagnostic functions (stubbed out) */ -#define Assert(cond,msg) -#define Trace(x) -#define Tracev(x) -#define Tracevv(x) -#define Tracec(c,x) -#define Tracecv(c,x) - -#define STATIC static - -static int fill_inbuf(void); -static void flush_window(void); -static void *malloc(int size); -static void free(void *where); -static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); - -#include "../../lib/inflate.c" - -static void __init *malloc(int size) -{ - return kmalloc(size, GFP_KERNEL); -} - -static void __init free(void *where) -{ - kfree(where); -} - -static void __init gzip_mark(void **ptr) -{ -} - -static void __init gzip_release(void **ptr) -{ -} - - -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - */ -static int __init fill_inbuf(void) -{ - if (exit_code) return -1; - - insize = crd_infp->f_op->read(crd_infp, inbuf, INBUFSIZ, - &crd_infp->f_pos); - if (insize == 0) return -1; - - inptr = 1; - - return inbuf[0]; -} - -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -static void __init flush_window(void) -{ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, ch; - - crd_outfp->f_op->write(crd_outfp, window, outcnt, &crd_outfp->f_pos); - in = window; - for (n = 0; n < outcnt; n++) { - ch = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - outcnt = 0; -} - -static void __init error(char *x) -{ - printk(KERN_ERR "%s", x); - exit_code = 1; -} - -static int __init -crd_load(struct file * fp, struct file *outfp) -{ - int result; - - insize = 0; /* valid bytes in inbuf */ - inptr = 0; /* index of next byte to be processed in inbuf */ - outcnt = 0; /* bytes in output buffer */ - exit_code = 0; - bytes_out = 0; - crc = (ulg)0xffffffffL; /* shift register contents */ - - crd_infp = fp; - crd_outfp = outfp; - inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); - if (inbuf == 0) { - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); - return -1; - } - window = kmalloc(WSIZE, GFP_KERNEL); - if (window == 0) { - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); - kfree(inbuf); - return -1; - } - makecrc(); - result = gunzip(); - kfree(inbuf); - kfree(window); - return result; -} - -#endif /* BUILD_CRAMDISK */ - diff -u --recursive --new-file v2.5.0/linux/drivers/block/swim3.c linux/drivers/block/swim3.c --- v2.5.0/linux/drivers/block/swim3.c Wed Jun 27 13:37:35 2001 +++ linux/drivers/block/swim3.c Sun Dec 16 12:23:05 2001 @@ -203,6 +203,7 @@ static struct floppy_state floppy_states[MAX_FLOPPIES]; static int floppy_count = 0; +static spinlock_t swim3_lock = SPIN_LOCK_UNLOCKED; static unsigned short write_preamble[] = { 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, /* gap field */ @@ -807,16 +808,6 @@ return err; } -int swim3_fd_eject(int devnum) -{ - if (devnum >= floppy_count) - return -ENODEV; - /* Do not check this - this function should ONLY be called early - * in the boot process! */ - /* if (floppy_states[devnum].ref_count != 1) return -EBUSY; */ - return fd_eject(&floppy_states[devnum]); -} - static struct floppy_struct floppy_type = { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */ @@ -1041,7 +1032,7 @@ MAJOR_NR); return -EBUSY; } - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST,&swim3_lock); blksize_size[MAJOR_NR] = floppy_blocksizes; blk_size[MAJOR_NR] = floppy_sizes; } diff -u --recursive --new-file v2.5.0/linux/drivers/block/swim_iop.c linux/drivers/block/swim_iop.c --- v2.5.0/linux/drivers/block/swim_iop.c Sat May 19 17:43:05 2001 +++ linux/drivers/block/swim_iop.c Sun Dec 16 12:20:20 2001 @@ -84,6 +84,8 @@ static int floppy_blocksizes[2] = {512,512}; static int floppy_sizes[2] = {2880,2880}; +static spinlock_t swim_iop_lock = SPIN_LOCK_UNLOCKED; + static char *drive_names[7] = { "not installed", /* DRV_NONE */ "unknown (1)", /* DRV_UNKNOWN */ @@ -147,7 +149,7 @@ MAJOR_NR); return -EBUSY; } - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST, &swim_iop_lock); blksize_size[MAJOR_NR] = floppy_blocksizes; blk_size[MAJOR_NR] = floppy_sizes; diff -u --recursive --new-file v2.5.0/linux/drivers/block/xd.c linux/drivers/block/xd.c --- v2.5.0/linux/drivers/block/xd.c Fri Nov 9 14:01:21 2001 +++ linux/drivers/block/xd.c Sun Dec 16 12:20:20 2001 @@ -121,7 +121,8 @@ static struct hd_struct xd_struct[XD_MAXDRIVES << 6]; static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES]; static int xd_blocksizes[XD_MAXDRIVES << 6]; -static int xd_maxsect[XD_MAXDRIVES << 6]; + +static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED; extern struct block_device_operations xd_fops; @@ -171,7 +172,7 @@ return -1; } devfs_handle = devfs_mk_dir (NULL, xd_gendisk.major_name, NULL); - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST, &xd_lock); read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */ add_gendisk(&xd_gendisk); xd_geninit(); @@ -246,8 +247,7 @@ } /* xd_maxsectors depends on controller - so set after detection */ - for(i=0; i<(XD_MAXDRIVES << 6); i++) xd_maxsect[i] = xd_maxsectors; - max_sectors[MAJOR_NR] = xd_maxsect; + blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), xd_maxsectors); for (i = 0; i < xd_drives; i++) { xd_valid[i] = 1; @@ -257,7 +257,6 @@ } xd_gendisk.nr_real = xd_drives; - } /* xd_open: open a device */ @@ -292,14 +291,14 @@ if (CURRENT_DEV < xd_drives && CURRENT->sector + CURRENT->nr_sectors <= xd_struct[MINOR(CURRENT->rq_dev)].nr_sects) { - block = CURRENT->sector + xd_struct[MINOR(CURRENT->rq_dev)].start_sect; + block = CURRENT->sector; count = CURRENT->nr_sectors; - switch (CURRENT->cmd) { + switch (rq_data_dir(CURRENT)) { case READ: case WRITE: for (retry = 0; (retry < XD_RETRIES) && !code; retry++) - code = xd_readwrite(CURRENT->cmd,CURRENT_DEV,CURRENT->buffer,block,count); + code = xd_readwrite(rq_data_dir(CURRENT),CURRENT_DEV,CURRENT->buffer,block,count); break; default: printk("do_xd_request: unknown request\n"); @@ -329,7 +328,7 @@ g.heads = xd_info[dev].heads; g.sectors = xd_info[dev].sectors; g.cylinders = xd_info[dev].cylinders; - g.start = xd_struct[MINOR(inode->i_rdev)].start_sect; + g.start = get_start_sect(inode->i_rdev); return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0; } case HDIO_SET_DMA: @@ -337,7 +336,8 @@ if (xdc_busy) return -EBUSY; nodma = !arg; if (nodma && xd_dma_buffer) { - xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200); + xd_dma_mem_free((unsigned long)xd_dma_buffer, + xd_maxsectors * 0x200); xd_dma_buffer = 0; } return 0; @@ -378,11 +378,9 @@ static int xd_reread_partitions(kdev_t dev) { int target; - int start; - int partition; + int res; target = DEVICE_NR(dev); - start = target << xd_gendisk.minor_shift; cli(); xd_valid[target] = (xd_access[target] != 1); @@ -390,20 +388,16 @@ if (xd_valid[target]) return -EBUSY; - for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) { - int minor = (start | partition); - invalidate_device(MKDEV(MAJOR_NR, minor), 1); - xd_gendisk.part[minor].start_sect = 0; - xd_gendisk.part[minor].nr_sects = 0; - }; - - grok_partitions(&xd_gendisk, target, 1<<6, - xd_info[target].heads * xd_info[target].cylinders * xd_info[target].sectors); + res = wipe_partitions(dev); + if (!res) + grok_partitions(dev, xd_info[target].heads + * xd_info[target].cylinders + * xd_info[target].sectors); xd_valid[target] = 1; wake_up(&xd_wait_open); - return 0; + return res; } /* xd_readwrite: handle a read/write request */ @@ -1105,12 +1099,9 @@ static void xd_done (void) { - blksize_size[MAJOR_NR] = NULL; blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); - blk_size[MAJOR_NR] = NULL; - hardsect_size[MAJOR_NR] = NULL; - read_ahead[MAJOR_NR] = 0; del_gendisk(&xd_gendisk); + blk_clear(MAJOR_NR); release_region(xd_iobase,4); } diff -u --recursive --new-file v2.5.0/linux/drivers/block/z2ram.c linux/drivers/block/z2ram.c --- v2.5.0/linux/drivers/block/z2ram.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/block/z2ram.c Sun Dec 16 12:20:20 2001 @@ -68,6 +68,8 @@ static int list_count = 0; static int current_device = -1; +static spinlock_t z2ram_lock = SPIN_LOCK_UNLOCKED; + static void do_z2_request( request_queue_t * q ) { @@ -364,7 +366,7 @@ } } - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUES, &z2ram_lock); blksize_size[ MAJOR_NR ] = z2_blocksizes; blk_size[ MAJOR_NR ] = z2_sizes; diff -u --recursive --new-file v2.5.0/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- v2.5.0/linux/drivers/cdrom/cdrom.c Fri Nov 16 10:14:08 2001 +++ linux/drivers/cdrom/cdrom.c Thu Dec 6 14:02:56 2001 @@ -247,7 +247,7 @@ /* Define this to remove _all_ the debugging messages */ /* #define ERRLOGMASK CD_NOTHING */ -#define ERRLOGMASK (CD_WARNING) +#define ERRLOGMASK CD_WARNING /* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */ /* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */ @@ -1987,7 +1987,7 @@ return -EINVAL; /* FIXME: we need upper bound checking, too!! */ - if (lba < 0 || ra.nframes <= 0) + if (lba < 0 || ra.nframes <= 0 || ra.nframes > 64) return -EINVAL; /* diff -u --recursive --new-file v2.5.0/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c --- v2.5.0/linux/drivers/cdrom/cdu31a.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/cdrom/cdu31a.c Tue Nov 27 09:23:27 2001 @@ -1583,7 +1583,10 @@ /* Make sure we have a valid TOC. */ sony_get_toc(); - spin_unlock_irq(&io_request_lock); + /* + * jens: driver has lots of races + */ + spin_unlock_irq(&q->queue_lock); /* Make sure the timer is cancelled. */ del_timer(&cdu31a_abort_timer); @@ -1730,7 +1733,7 @@ } end_do_cdu31a_request: - spin_lock_irq(&io_request_lock); + spin_lock_irq(&q->queue_lock); #if 0 /* After finished, cancel any pending operations. */ abort_read(); diff -u --recursive --new-file v2.5.0/linux/drivers/cdrom/cm206.c linux/drivers/cdrom/cm206.c --- v2.5.0/linux/drivers/cdrom/cm206.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/cdrom/cm206.c Tue Nov 27 09:23:27 2001 @@ -866,7 +866,7 @@ end_request(0); continue; } - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&q->queue_lock); error = 0; for (i = 0; i < CURRENT->nr_sectors; i++) { int e1, e2; @@ -893,7 +893,7 @@ debug(("cm206_request: %d %d\n", e1, e2)); } } - spin_lock_irq(&io_request_lock); + spin_lock_irq(&q->queue_lock); end_request(!error); } } diff -u --recursive --new-file v2.5.0/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c --- v2.5.0/linux/drivers/cdrom/sbpcd.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/cdrom/sbpcd.c Sat Dec 8 20:02:47 2001 @@ -4930,7 +4930,7 @@ sbpcd_end_request(req, 0); if (req -> sector == -1) sbpcd_end_request(req, 0); - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&q->queue_lock); down(&ioctl_read_sem); if (req->cmd != READ) @@ -4970,7 +4970,7 @@ xnr, req, req->sector, req->nr_sectors, jiffies); #endif up(&ioctl_read_sem); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&q->queue_lock); sbpcd_end_request(req, 1); goto request_loop; } @@ -5011,7 +5011,7 @@ xnr, req, req->sector, req->nr_sectors, jiffies); #endif up(&ioctl_read_sem); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&q->queue_lock); sbpcd_end_request(req, 1); goto request_loop; } @@ -5027,7 +5027,7 @@ #endif up(&ioctl_read_sem); sbp_sleep(0); /* wait a bit, try again */ - spin_lock_irq(&io_request_lock); + spin_lock_irq(&q->queue_lock); sbpcd_end_request(req, 0); goto request_loop; } @@ -5870,7 +5870,6 @@ (BLK_DEFAULT_QUEUE(MAJOR_NR))->front_merge_fn = dont_bh_merge_fn; (BLK_DEFAULT_QUEUE(MAJOR_NR))->merge_requests_fn = dont_merge_requests_fn; #endif - blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); read_ahead[MAJOR_NR] = buffers * (CD_FRAMESIZE / 512); request_region(CDo_command,4,major_name); diff -u --recursive --new-file v2.5.0/linux/drivers/char/acquirewdt.c linux/drivers/char/acquirewdt.c --- v2.5.0/linux/drivers/char/acquirewdt.c Thu Sep 13 15:21:32 2001 +++ linux/drivers/char/acquirewdt.c Fri Nov 30 08:26:04 2001 @@ -141,7 +141,6 @@ static int acq_close(struct inode *inode, struct file *file) { - lock_kernel(); if(MINOR(inode->i_rdev)==WATCHDOG_MINOR) { spin_lock(&acq_lock); @@ -151,7 +150,6 @@ acq_is_open=0; spin_unlock(&acq_lock); } - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/advantechwdt.c linux/drivers/char/advantechwdt.c --- v2.5.0/linux/drivers/char/advantechwdt.c Thu Sep 13 15:21:32 2001 +++ linux/drivers/char/advantechwdt.c Fri Nov 30 08:26:04 2001 @@ -151,7 +151,6 @@ static int advwdt_close(struct inode *inode, struct file *file) { - lock_kernel(); if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) { spin_lock(&advwdt_lock); #ifndef CONFIG_WATCHDOG_NOWAYOUT @@ -160,7 +159,6 @@ advwdt_is_open = 0; spin_unlock(&advwdt_lock); } - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/agp/agp.h linux/drivers/char/agp/agp.h --- v2.5.0/linux/drivers/char/agp/agp.h Fri Nov 9 14:01:21 2001 +++ linux/drivers/char/agp/agp.h Tue Nov 27 16:46:57 2001 @@ -276,6 +276,8 @@ #define I830_RDRAM_ND(x) (((x) & 0x20) >> 5) #define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3) +#define INTEL_I830_ERRSTS 0x92 + /* intel i820 registers */ #define INTEL_I820_RDCR 0x51 #define INTEL_I820_ERRSTS 0xc8 diff -u --recursive --new-file v2.5.0/linux/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c --- v2.5.0/linux/drivers/char/agp/agpgart_be.c Fri Nov 16 10:11:22 2001 +++ linux/drivers/char/agp/agpgart_be.c Fri Nov 30 08:52:41 2001 @@ -1399,10 +1399,6 @@ } #endif /* CONFIG_AGP_I810 */ - - #ifdef CONFIG_AGP_INTEL - -#endif /* CONFIG_AGP_I810 */ #ifdef CONFIG_AGP_INTEL @@ -1705,6 +1701,38 @@ return 0; } +static int intel_830mp_configure(void) +{ + u32 temp; + u16 temp2; + aper_size_info_8 *current_size; + + current_size = A_SIZE_8(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, + agp_bridge.gatt_bus_addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + + /* gmch */ + pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2); + pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, + temp2 | (1 << 9)); + /* clear any possible AGP-related error conditions */ + pci_write_config_word(agp_bridge.dev, INTEL_I830_ERRSTS, 0x1c); + return 0; +} + static unsigned long intel_mask_memory(unsigned long addr, int type) { /* Memory type is ignored */ @@ -1745,6 +1773,14 @@ {4, 1024, 0, 63} }; +static aper_size_info_8 intel_830mp_sizes[4] = +{ + {256, 65536, 6, 0}, + {128, 32768, 5, 32}, + {64, 16384, 4, 48}, + {32, 8192, 3, 56} +}; + static int __init intel_generic_setup (struct pci_dev *pdev) { agp_bridge.masks = intel_generic_masks; @@ -1809,6 +1845,35 @@ (void) pdev; /* unused */ } +static int __init intel_830mp_setup (struct pci_dev *pdev) +{ + agp_bridge.masks = intel_generic_masks; + agp_bridge.num_of_masks = 1; + agp_bridge.aperture_sizes = (void *) intel_830mp_sizes; + agp_bridge.size_type = U8_APER_SIZE; + agp_bridge.num_aperture_sizes = 4; + agp_bridge.dev_private_data = NULL; + agp_bridge.needs_scratch_page = FALSE; + agp_bridge.configure = intel_830mp_configure; + agp_bridge.fetch_size = intel_8xx_fetch_size; + agp_bridge.cleanup = intel_8xx_cleanup; + agp_bridge.tlb_flush = intel_8xx_tlbflush; + agp_bridge.mask_memory = intel_mask_memory; + agp_bridge.agp_enable = agp_generic_agp_enable; + agp_bridge.cache_flush = global_cache_flush; + agp_bridge.create_gatt_table = agp_generic_create_gatt_table; + agp_bridge.free_gatt_table = agp_generic_free_gatt_table; + agp_bridge.insert_memory = agp_generic_insert_memory; + agp_bridge.remove_memory = agp_generic_remove_memory; + agp_bridge.alloc_by_type = agp_generic_alloc_by_type; + agp_bridge.free_by_type = agp_generic_free_by_type; + agp_bridge.agp_alloc_page = agp_generic_alloc_page; + agp_bridge.agp_destroy_page = agp_generic_destroy_page; + + return 0; + + (void) pdev; /* unused */ +} static int __init intel_840_setup (struct pci_dev *pdev) { @@ -3495,12 +3560,6 @@ "AMD", "Irongate", amd_irongate_setup }, - { PCI_DEVICE_ID_AMD_762_0, - PCI_VENDOR_ID_AMD, - AMD_IRONGATE, - "AMD", - "AMD 760MP", - amd_irongate_setup }, { PCI_DEVICE_ID_AMD_761_0, PCI_VENDOR_ID_AMD, AMD_761, @@ -3557,7 +3616,7 @@ INTEL_I830_M, "Intel", "i830M", - intel_generic_setup }, + intel_830mp_setup }, { PCI_DEVICE_ID_INTEL_840_0, PCI_VENDOR_ID_INTEL, INTEL_I840, @@ -3879,18 +3938,17 @@ i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_830_M_1, NULL); - if(PCI_FUNC(i810_dev->devfn) != 0) { + if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) { i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_830_M_1, i810_dev); } if (i810_dev == NULL) { - printk(KERN_ERR PFX "Detected an " - "Intel 830M, but could not find the" - " secondary device.\n"); - agp_bridge.type = NOT_SUPPORTED; - return -ENODEV; + /* Intel 830MP with external graphic card */ + /* It will be initialized later */ + agp_bridge.type = INTEL_I830_M; + break; } printk(KERN_INFO PFX "Detected an Intel " "830M Chipset.\n"); diff -u --recursive --new-file v2.5.0/linux/drivers/char/agp/agpgart_fe.c linux/drivers/char/agp/agpgart_fe.c --- v2.5.0/linux/drivers/char/agp/agpgart_fe.c Sun Aug 12 10:38:48 2001 +++ linux/drivers/char/agp/agpgart_fe.c Fri Nov 30 08:26:04 2001 @@ -606,17 +606,14 @@ agp_file_private *priv = (agp_file_private *) file->private_data; agp_kern_info kerninfo; - lock_kernel(); AGP_LOCK(); if (agp_fe.backend_acquired != TRUE) { AGP_UNLOCK(); - unlock_kernel(); return -EPERM; } if (!(test_bit(AGP_FF_IS_VALID, &priv->access_flags))) { AGP_UNLOCK(); - unlock_kernel(); return -EPERM; } agp_copy_info(&kerninfo); @@ -628,51 +625,42 @@ if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) { if ((size + offset) > current_size) { AGP_UNLOCK(); - unlock_kernel(); return -EINVAL; } client = agp_find_client_by_pid(current->pid); if (client == NULL) { AGP_UNLOCK(); - unlock_kernel(); return -EPERM; } if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot)) { AGP_UNLOCK(); - unlock_kernel(); return -EINVAL; } if (remap_page_range(vma->vm_start, (kerninfo.aper_base + offset), size, vma->vm_page_prot)) { AGP_UNLOCK(); - unlock_kernel(); return -EAGAIN; } AGP_UNLOCK(); - unlock_kernel(); return 0; } if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) { if (size != current_size) { AGP_UNLOCK(); - unlock_kernel(); return -EINVAL; } if (remap_page_range(vma->vm_start, kerninfo.aper_base, size, vma->vm_page_prot)) { AGP_UNLOCK(); - unlock_kernel(); return -EAGAIN; } AGP_UNLOCK(); - unlock_kernel(); return 0; } AGP_UNLOCK(); - unlock_kernel(); return -EPERM; } @@ -680,7 +668,6 @@ { agp_file_private *priv = (agp_file_private *) file->private_data; - lock_kernel(); AGP_LOCK(); if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) { @@ -702,7 +689,6 @@ agp_remove_file_private(priv); kfree(priv); AGP_UNLOCK(); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c --- v2.5.0/linux/drivers/char/busmouse.c Fri Sep 7 09:28:38 2001 +++ linux/drivers/char/busmouse.c Fri Nov 30 08:26:04 2001 @@ -171,6 +171,7 @@ lock_kernel(); busmouse_fasync(-1, file, 0); + down(&mouse_sem); /* to protect mse->active */ if (--mse->active == 0) { if (mse->ops->release) ret = mse->ops->release(inode, file); @@ -179,7 +180,8 @@ mse->ready = 0; } unlock_kernel(); - + up( &mouse_sem); + return ret; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/dtlk.c linux/drivers/char/dtlk.c --- v2.5.0/linux/drivers/char/dtlk.c Thu Sep 13 15:21:32 2001 +++ linux/drivers/char/dtlk.c Fri Nov 30 08:26:04 2001 @@ -328,10 +328,8 @@ break; } TRACE_RET; - - lock_kernel(); + del_timer(&dtlk_timer); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/ftape/zftape/zftape-init.c linux/drivers/char/ftape/zftape/zftape-init.c --- v2.5.0/linux/drivers/char/ftape/zftape/zftape-init.c Thu Sep 13 15:21:32 2001 +++ linux/drivers/char/ftape/zftape/zftape-init.c Fri Nov 30 12:33:17 2001 @@ -68,7 +68,8 @@ /* Local vars. */ -static int busy_flag = 0; +static int busy_flag; + static sigset_t orig_sigmask; /* the interface to the kernel vfs layer @@ -113,14 +114,13 @@ TRACE_FUN(ft_t_flow); TRACE(ft_t_flow, "called for minor %d", MINOR(ino->i_rdev)); - if (busy_flag) { + if ( test_and_set_bit(0,&busy_flag) ) { TRACE_ABORT(-EBUSY, ft_t_warn, "failed: already busy"); } - busy_flag = 1; if ((MINOR(ino->i_rdev) & ~(ZFT_MINOR_OP_MASK | FTAPE_NO_REWIND)) > FTAPE_SEL_D) { - busy_flag = 0; + clear_bit(0,&busy_flag); TRACE_ABORT(-ENXIO, ft_t_err, "failed: illegal unit nr"); } orig_sigmask = current->blocked; @@ -128,7 +128,7 @@ result = _zft_open(MINOR(ino->i_rdev), filep->f_flags & O_ACCMODE); if (result < 0) { current->blocked = orig_sigmask; /* restore mask */ - busy_flag = 0; + clear_bit(0,&busy_flag); TRACE_ABORT(result, ft_t_err, "_ftape_open failed"); } else { /* Mask signals that will disturb proper operation of the @@ -147,10 +147,8 @@ int result; TRACE_FUN(ft_t_flow); - lock_kernel(); - if (!busy_flag || MINOR(ino->i_rdev) != zft_unit) { + if ( !test_bit(0,&busy_flag) || MINOR(ino->i_rdev) != zft_unit) { TRACE(ft_t_err, "failed: not busy or wrong unit"); - unlock_kernel(); TRACE_EXIT 0; } sigfillset(¤t->blocked); @@ -159,8 +157,7 @@ TRACE(ft_t_err, "_zft_close failed"); } current->blocked = orig_sigmask; /* restore before open state */ - busy_flag = 0; - unlock_kernel(); + clear_bit(0,&busy_flag); TRACE_EXIT 0; } @@ -173,7 +170,7 @@ sigset_t old_sigmask; TRACE_FUN(ft_t_flow); - if (!busy_flag || MINOR(ino->i_rdev) != zft_unit || ft_failure) { + if ( !test_bit(0,&busy_flag) || MINOR(ino->i_rdev) != zft_unit || ft_failure) { TRACE_ABORT(-EIO, ft_t_err, "failed: not busy, failure or wrong unit"); } @@ -193,7 +190,7 @@ sigset_t old_sigmask; TRACE_FUN(ft_t_flow); - if (!busy_flag || + if ( !test_bit(0,&busy_flag) || MINOR(filep->f_dentry->d_inode->i_rdev) != zft_unit || ft_failure) { @@ -202,14 +199,12 @@ } old_sigmask = current->blocked; /* save mask */ sigfillset(¤t->blocked); - lock_kernel(); if ((result = ftape_mmap(vma)) >= 0) { #ifndef MSYNC_BUG_WAS_FIXED static struct vm_operations_struct dummy = { NULL, }; vma->vm_ops = &dummy; #endif } - unlock_kernel(); current->blocked = old_sigmask; /* restore mask */ TRACE_EXIT result; } @@ -225,7 +220,7 @@ TRACE_FUN(ft_t_flow); TRACE(ft_t_data_flow, "called with count: %ld", (unsigned long)req_len); - if (!busy_flag || MINOR(ino->i_rdev) != zft_unit || ft_failure) { + if (!test_bit(0,&busy_flag) || MINOR(ino->i_rdev) != zft_unit || ft_failure) { TRACE_ABORT(-EIO, ft_t_err, "failed: not busy, failure or wrong unit"); } @@ -248,7 +243,7 @@ TRACE_FUN(ft_t_flow); TRACE(ft_t_flow, "called with count: %ld", (unsigned long)req_len); - if (!busy_flag || MINOR(ino->i_rdev) != zft_unit || ft_failure) { + if (!test_bit(0,&busy_flag) || MINOR(ino->i_rdev) != zft_unit || ft_failure) { TRACE_ABORT(-EIO, ft_t_err, "failed: not busy, failure or wrong unit"); } @@ -403,7 +398,7 @@ */ static int can_unload(void) { - return (GET_USE_COUNT(THIS_MODULE)||zft_dirty()||busy_flag)?-EBUSY:0; + return (GET_USE_COUNT(THIS_MODULE)||zft_dirty()||test_bit(0,&busy_flag))?-EBUSY:0; } /* Called by modules package when installing the driver */ diff -u --recursive --new-file v2.5.0/linux/drivers/char/joystick/ns558.c linux/drivers/char/joystick/ns558.c --- v2.5.0/linux/drivers/char/joystick/ns558.c Wed Sep 12 15:34:06 2001 +++ linux/drivers/char/joystick/ns558.c Sun Nov 25 09:43:42 2001 @@ -153,11 +153,7 @@ return port; } -#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE)) -#define NSS558_ISAPNP -#endif - -#ifdef NSS558_ISAPNP +#ifdef __ISAPNP__ static struct isapnp_device_id pnp_devids[] = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('@','P','@'), ISAPNP_DEVICE(0x0001), 0 }, @@ -229,7 +225,7 @@ int __init ns558_init(void) { int i = 0; -#ifdef NSS558_ISAPNP +#ifdef __ISAPNP__ struct isapnp_device_id *devid; struct pci_dev *dev = NULL; #endif @@ -245,7 +241,7 @@ * Probe for PnP ports. */ -#ifdef NSS558_ISAPNP +#ifdef __ISAPNP__ for (devid = pnp_devids; devid->vendor; devid++) { while ((dev = isapnp_find_dev(NULL, devid->vendor, devid->function, dev))) { ns558 = ns558_pnp_probe(dev, ns558); @@ -264,7 +260,7 @@ gameport_unregister_port(&port->gameport); switch (port->type) { -#ifdef NSS558_ISAPNP +#ifdef __ISAPNP__ case NS558_PNP: if (port->dev->deactivate) port->dev->deactivate(port->dev); diff -u --recursive --new-file v2.5.0/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v2.5.0/linux/drivers/char/lp.c Thu Oct 25 00:07:39 2001 +++ linux/drivers/char/lp.c Fri Nov 30 08:26:04 2001 @@ -494,11 +494,9 @@ parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT); lp_table[minor].current_mode = IEEE1284_MODE_COMPAT; lp_release_parport (&lp_table[minor]); - lock_kernel(); kfree(lp_table[minor].lp_buffer); lp_table[minor].lp_buffer = NULL; LP_F(minor) &= ~LP_BUSY; - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/mixcomwd.c linux/drivers/char/mixcomwd.c --- v2.5.0/linux/drivers/char/mixcomwd.c Thu Sep 13 15:21:32 2001 +++ linux/drivers/char/mixcomwd.c Fri Nov 30 08:26:04 2001 @@ -101,11 +101,9 @@ static int mixcomwd_release(struct inode *inode, struct file *file) { - lock_kernel(); #ifndef CONFIG_WATCHDOG_NOWAYOUT if(mixcomwd_timer_alive) { printk(KERN_ERR "mixcomwd: release called while internal timer alive"); - unlock_kernel(); return -EBUSY; } init_timer(&mixcomwd_timer); @@ -117,7 +115,6 @@ #endif clear_bit(0,&mixcomwd_opened); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/nvram.c linux/drivers/char/nvram.c --- v2.5.0/linux/drivers/char/nvram.c Fri Sep 14 14:40:00 2001 +++ linux/drivers/char/nvram.c Fri Nov 30 08:26:04 2001 @@ -108,7 +108,10 @@ #include static int nvram_open_cnt; /* #times opened */ -static int nvram_open_mode; /* special open modes */ +static int nvram_open_mode; /* special open modes */ +static spinlock_t nvram_open_lock = SPIN_LOCK_UNLOCKED; + /* guards nvram_open_cnt and + nvram_open_mode */ #define NVRAM_WRITE 1 /* opened for writing (exclusive) */ #define NVRAM_EXCL 2 /* opened with O_EXCL */ @@ -326,29 +329,33 @@ static int nvram_open( struct inode *inode, struct file *file ) { + spin_lock( &nvram_open_lock ); if ((nvram_open_cnt && (file->f_flags & O_EXCL)) || (nvram_open_mode & NVRAM_EXCL) || ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) + { + spin_unlock( &nvram_open_lock ); return( -EBUSY ); + } if (file->f_flags & O_EXCL) nvram_open_mode |= NVRAM_EXCL; if (file->f_mode & 2) nvram_open_mode |= NVRAM_WRITE; nvram_open_cnt++; + spin_unlock( &nvram_open_lock ); return( 0 ); } static int nvram_release( struct inode *inode, struct file *file ) { - lock_kernel(); + spin_lock( &nvram_open_lock ); nvram_open_cnt--; if (file->f_flags & O_EXCL) nvram_open_mode &= ~NVRAM_EXCL; if (file->f_mode & 2) nvram_open_mode &= ~NVRAM_WRITE; - unlock_kernel(); - + spin_unlock( &nvram_open_lock ); return( 0 ); } diff -u --recursive --new-file v2.5.0/linux/drivers/char/pc110pad.c linux/drivers/char/pc110pad.c --- v2.5.0/linux/drivers/char/pc110pad.c Fri Sep 7 09:28:38 2001 +++ linux/drivers/char/pc110pad.c Wed Nov 28 21:46:03 2001 @@ -68,7 +68,9 @@ /* driver/filesystem interface management */ static wait_queue_head_t queue; static struct fasync_struct *asyncptr; -static int active; /* number of concurrent open()s */ +static int active_count = 0; /* number of concurrent open()s */ +static spinlock_t pc110_lock = SPIN_LOCK_UNLOCKED; +/* this lock should be held when referencing active_count */ static struct semaphore reader_lock; /** @@ -480,15 +482,14 @@ int thisd, thisdd, thisx, thisy; int b; unsigned long flags; - - save_flags(flags); - cli(); + + spin_lock_irqsave(&pc110_lock, flags); read_raw_pad(&thisd, &thisdd, &thisx, &thisy); d[0]=(thisd?0x80:0) | (thisdd?0x40:0) | bounce; d[1]=(recent_transition?0x80:0)+transition_count; read_button(&b); d[2]=(synthesize_tap<<4) | (b?0x01:0); - restore_flags(flags); + spin_unlock_irqrestore(&pc110_lock, flags); } /** @@ -584,11 +585,12 @@ static int close_pad(struct inode * inode, struct file * file) { - lock_kernel(); + unsigned long flags; fasync_pad(-1, file, 0); - if (!--active) + spin_lock_irqsave(&pc110_lock, flags); + if (!--active_count) outb(0x30, current_params.io+2); /* switch off digitiser */ - unlock_kernel(); + spin_unlock_irqrestore(&active_lock, flags); return 0; } @@ -608,11 +610,13 @@ { unsigned long flags; - if (active++) + spin_lock_irqsave(&pc110_lock, flags); + if (active_count++) + { + spin_unlock_irqrestore(&pc110_lock, flags); return 0; + } - save_flags(flags); - cli(); outb(0x30, current_params.io+2); /* switch off digitiser */ pad_irq(0,0,0); /* read to flush any pending bytes */ pad_irq(0,0,0); /* read to flush any pending bytes */ @@ -627,7 +631,7 @@ synthesize_tap=0; del_timer(&bounce_timer); del_timer(&tap_timer); - restore_flags(flags); + spin_unlock_irqrestore(&pc110_lock, flags); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c --- v2.5.0/linux/drivers/char/pc_keyb.c Fri Nov 9 14:01:21 2001 +++ linux/drivers/char/pc_keyb.c Fri Dec 7 16:21:05 2001 @@ -90,6 +90,7 @@ static struct aux_queue *queue; /* Mouse data buffer. */ static int aux_count; +static spinlock_t aux_count_lock = SPIN_LOCK_UNLOCKED; /* used when we send commands to the mouse that expect an ACK. */ static unsigned char mouse_reply_expected; @@ -405,8 +406,9 @@ if (rqst == PM_RESUME) { if (queue) { /* Aux port detected */ - if (aux_count == 0) { /* Mouse not in use */ - spin_lock_irqsave(&kbd_controller_lock, flags); + spin_lock_irqsave(&aux_count_lock, flags); + if ( aux_count == 0) { /* Mouse not in use */ + spin_lock(&kbd_controller_lock); /* * Dell Lat. C600 A06 enables mouse after resume. * When user touches the pad, it posts IRQ 12 @@ -418,8 +420,9 @@ kbd_write_command(KBD_CCMD_WRITE_MODE); kb_wait(); kbd_write_output(AUX_INTS_OFF); - spin_unlock_irqrestore(&kbd_controller_lock, flags); + spin_unlock(&kbd_controller_lock); } + spin_unlock_irqrestore(&aux_count_lock, flags); } } #endif @@ -430,6 +433,7 @@ static inline void handle_mouse_event(unsigned char scancode) { #ifdef CONFIG_PSMOUSE + unsigned long flags; static unsigned char prev_code; if (mouse_reply_expected) { if (scancode == AUX_ACK) { @@ -448,7 +452,8 @@ prev_code = scancode; add_mouse_randomness(scancode); - if (aux_count) { + spin_lock_irqsave(&aux_count_lock, flags); + if ( aux_count ) { int head = queue->head; queue->buf[head] = scancode; @@ -459,6 +464,7 @@ wake_up_interruptible(&queue->proc_list); } } + spin_unlock_irqrestore(&aux_count_lock, flags); #endif } @@ -1046,16 +1052,17 @@ static int release_aux(struct inode * inode, struct file * file) { - lock_kernel(); + unsigned long flags; fasync_aux(-1, file, 0); - if (--aux_count) { - unlock_kernel(); + spin_lock_irqsave(&aux_count_lock, flags); + if ( --aux_count ) { + spin_unlock_irqrestore(&aux_count_lock, flags); return 0; } + spin_unlock_irqrestore(&aux_count_lock, flags); kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */ kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE); aux_free_irq(AUX_DEV); - unlock_kernel(); return 0; } @@ -1066,14 +1073,24 @@ static int open_aux(struct inode * inode, struct file * file) { - if (aux_count++) { + unsigned long flags; + int ret; + + spin_lock_irqsave(&aux_count_lock, flags); + if ( aux_count++ ) { + spin_unlock_irqrestore(&aux_count_lock, flags); return 0; } queue->head = queue->tail = 0; /* Flush input queue */ - if (aux_request_irq(keyboard_interrupt, AUX_DEV)) { + spin_unlock_irqrestore(&aux_count_lock, flags); + ret = aux_request_irq(keyboard_interrupt, AUX_DEV); + spin_lock_irqsave(&aux_count_lock, flags); + if (ret) { aux_count--; + spin_unlock_irqrestore(&aux_count_lock, flags); return -EBUSY; } + spin_unlock_irqrestore(&aux_count_lock, flags); kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the auxiliary port on controller. */ @@ -1083,7 +1100,6 @@ mdelay(2); /* Ensure we follow the kbc access delay rules.. */ send_data(KBD_CMD_ENABLE); /* try to workaround toshiba4030cdt problem */ - return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/pcwd.c linux/drivers/char/pcwd.c --- v2.5.0/linux/drivers/char/pcwd.c Thu Sep 13 15:21:32 2001 +++ linux/drivers/char/pcwd.c Fri Nov 30 08:26:04 2001 @@ -100,7 +100,8 @@ #define WD_SRLY2 0x80 /* Software external relay triggered */ static int current_readport, revision, temp_panic; -static int is_open, initial_status, supports_temp, mode_debug; +static atomic_t open_allowed = ATOMIC_INIT(1); +static int initial_status, supports_temp, mode_debug; static spinlock_t io_lock; /* @@ -402,9 +403,12 @@ switch (MINOR(ino->i_rdev)) { case WATCHDOG_MINOR: - if (is_open) + if ( !atomic_dec_and_test(&open_allowed) ) + { + atomic_inc( &open_allowed ); return -EBUSY; - MOD_INC_USE_COUNT; + } + MOD_INC_USE_COUNT; /* Enable the port */ if (revision == PCWD_REVISION_C) { @@ -412,7 +416,6 @@ outb_p(0x00, current_readport + 3); spin_unlock(&io_lock); } - is_open = 1; return(0); case TEMP_MINOR: return(0); @@ -452,8 +455,6 @@ { if (MINOR(ino->i_rdev)==WATCHDOG_MINOR) { - lock_kernel(); - is_open = 0; #ifndef CONFIG_WATCHDOG_NOWAYOUT /* Disable the board */ if (revision == PCWD_REVISION_C) { @@ -462,8 +463,8 @@ outb_p(0xA5, current_readport + 3); spin_unlock(&io_lock); } + atomic_inc( &open_allowed ); #endif - unlock_kernel(); } return 0; } @@ -574,7 +575,7 @@ printk("pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER); /* Initial variables */ - is_open = 0; + set_bit( 0, &open_allowed ); supports_temp = 0; mode_debug = 0; temp_panic = 0; diff -u --recursive --new-file v2.5.0/linux/drivers/char/ppdev.c linux/drivers/char/ppdev.c --- v2.5.0/linux/drivers/char/ppdev.c Thu Sep 13 15:21:32 2001 +++ linux/drivers/char/ppdev.c Fri Nov 30 08:26:04 2001 @@ -646,7 +646,6 @@ struct pp_struct *pp = file->private_data; int compat_negot; - lock_kernel(); compat_negot = 0; if (!(pp->flags & PP_CLAIMED) && pp->pdev && (pp->state.mode != IEEE1284_MODE_COMPAT)) { @@ -695,7 +694,6 @@ printk (KERN_DEBUG CHRDEV "%x: unregistered pardevice\n", minor); } - unlock_kernel(); kfree (pp); diff -u --recursive --new-file v2.5.0/linux/drivers/char/qpmouse.c linux/drivers/char/qpmouse.c --- v2.5.0/linux/drivers/char/qpmouse.c Fri Sep 7 09:28:38 2001 +++ linux/drivers/char/qpmouse.c Fri Nov 30 08:26:04 2001 @@ -111,6 +111,7 @@ static int qp_present; static int qp_count; +static spinlock_t qp_count_lock = SPIN_LOCK_UNLOCKED; static int qp_data = QP_DATA; static int qp_status = QP_STATUS; @@ -141,8 +142,8 @@ { unsigned char status; - lock_kernel(); fasync_qp(-1, file, 0); + spin_lock( &qp_count_lock ); if (!--qp_count) { if (!poll_qp_status()) printk(KERN_WARNING "Warning: Mouse device busy in release_qp()\n"); @@ -152,7 +153,7 @@ printk(KERN_WARNING "Warning: Mouse device busy in release_qp()\n"); free_irq(QP_IRQ, NULL); } - unlock_kernel(); + spin_unlock( &qp_count_lock ); return 0; } @@ -168,8 +169,13 @@ if (!qp_present) return -EINVAL; + spin_lock( &qp_count_lock ); if (qp_count++) + { + spin_unlock( &qp_count_lock ); return 0; + } + spin_unlock( &qp_count_lock ); if (request_irq(QP_IRQ, qp_interrupt, 0, "PS/2 Mouse", NULL)) { qp_count--; diff -u --recursive --new-file v2.5.0/linux/drivers/char/qtronix.c linux/drivers/char/qtronix.c --- v2.5.0/linux/drivers/char/qtronix.c Sun Sep 9 10:43:02 2001 +++ linux/drivers/char/qtronix.c Fri Nov 30 08:26:04 2001 @@ -492,10 +492,8 @@ static int release_aux(struct inode * inode, struct file * file) { - lock_kernel(); fasync_aux(-1, file, 0); aux_count--; - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/raw.c linux/drivers/char/raw.c --- v2.5.0/linux/drivers/char/raw.c Sat Sep 22 20:35:43 2001 +++ linux/drivers/char/raw.c Tue Nov 27 09:23:27 2001 @@ -126,10 +126,8 @@ if (is_mounted(rdev)) { if (blksize_size[MAJOR(rdev)]) sector_size = blksize_size[MAJOR(rdev)][MINOR(rdev)]; - } else { - if (hardsect_size[MAJOR(rdev)]) - sector_size = hardsect_size[MAJOR(rdev)][MINOR(rdev)]; - } + } else + sector_size = get_hardsect_size(rdev); set_blocksize(rdev, sector_size); raw_devices[minor].sector_size = sector_size; @@ -273,16 +271,14 @@ struct kiobuf * iobuf; int new_iobuf; int err = 0; - unsigned long blocknr, blocks; + unsigned long blocks; size_t transferred; int iosize; - int i; int minor; kdev_t dev; unsigned long limit; - int sector_size, sector_bits, sector_mask; - int max_sectors; + sector_t blocknr; /* * First, a few checks on device size limits @@ -307,7 +303,6 @@ sector_size = raw_devices[minor].sector_size; sector_bits = raw_devices[minor].sector_bits; sector_mask = sector_size- 1; - max_sectors = KIO_MAX_SECTORS >> (sector_bits - 9); if (blk_size[MAJOR(dev)]) limit = (((loff_t) blk_size[MAJOR(dev)][MINOR(dev)]) << BLOCK_SIZE_BITS) >> sector_bits; @@ -325,18 +320,10 @@ if ((*offp >> sector_bits) >= limit) goto out_free; - /* - * Split the IO into KIO_MAX_SECTORS chunks, mapping and - * unmapping the single kiobuf as we go to perform each chunk of - * IO. - */ - transferred = 0; blocknr = *offp >> sector_bits; while (size > 0) { blocks = size >> sector_bits; - if (blocks > max_sectors) - blocks = max_sectors; if (blocks > limit - blocknr) blocks = limit - blocknr; if (!blocks) @@ -348,10 +335,7 @@ if (err) break; - for (i=0; i < blocks; i++) - iobuf->blocks[i] = blocknr++; - - err = brw_kiovec(rw, 1, &iobuf, dev, iobuf->blocks, sector_size); + err = brw_kiovec(rw, 1, &iobuf, dev, &blocknr, sector_size); if (rw == READ && err > 0) mark_dirty_kiobuf(iobuf, err); @@ -361,6 +345,8 @@ size -= err; buf += err; } + + blocknr += blocks; unmap_kiobuf(iobuf); diff -u --recursive --new-file v2.5.0/linux/drivers/char/sbc60xxwdt.c linux/drivers/char/sbc60xxwdt.c --- v2.5.0/linux/drivers/char/sbc60xxwdt.c Thu Sep 13 15:21:32 2001 +++ linux/drivers/char/sbc60xxwdt.c Fri Nov 30 08:26:04 2001 @@ -214,7 +214,6 @@ static int fop_close(struct inode * inode, struct file * file) { - lock_kernel(); if(MINOR(inode->i_rdev) == WATCHDOG_MINOR) { if(wdt_expect_close) @@ -225,7 +224,6 @@ } } wdt_is_open = 0; - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v2.5.0/linux/drivers/char/serial.c Fri Nov 9 14:12:55 2001 +++ linux/drivers/char/serial.c Sun Nov 25 09:43:42 2001 @@ -122,7 +122,7 @@ #define ENABLE_SERIAL_ACPI #endif -#if defined(CONFIG_ISAPNP)|| (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE)) +#ifdef __ISAPNP__ #ifndef ENABLE_SERIAL_PNP #define ENABLE_SERIAL_PNP #endif diff -u --recursive --new-file v2.5.0/linux/drivers/char/shwdt.c linux/drivers/char/shwdt.c --- v2.5.0/linux/drivers/char/shwdt.c Mon Oct 15 13:36:48 2001 +++ linux/drivers/char/shwdt.c Tue Dec 11 10:10:18 2001 @@ -10,7 +10,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ - #include #include #include @@ -177,7 +176,7 @@ * sh_wdt_read - Read from Device * * @file: file handle of device - * @char: buffer to write to + * @buf: buffer to write to * @count: length of buffer * @ppos: offset * @@ -193,7 +192,7 @@ * sh_wdt_write - Write to Device * * @file: file handle of device - * @char: buffer to write + * @buf: buffer to write * @count: length of buffer * @ppos: offset * @@ -269,7 +268,7 @@ static int sh_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { - if (code == SYS_DOWN || SYS_HALT) { + if (code == SYS_DOWN || code == SYS_HALT) { sh_wdt_stop(); } diff -u --recursive --new-file v2.5.0/linux/drivers/char/softdog.c linux/drivers/char/softdog.c --- v2.5.0/linux/drivers/char/softdog.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/char/softdog.c Fri Nov 30 08:26:04 2001 @@ -100,12 +100,10 @@ * Shut off the timer. * Lock it in if it's a module and we defined ...NOWAYOUT */ - lock_kernel(); #ifndef CONFIG_WATCHDOG_NOWAYOUT del_timer(&watchdog_ticktock); #endif timer_alive=0; - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/sonypi.c linux/drivers/char/sonypi.c --- v2.5.0/linux/drivers/char/sonypi.c Mon Oct 15 08:38:31 2001 +++ linux/drivers/char/sonypi.c Thu Nov 29 07:53:34 2001 @@ -617,8 +617,11 @@ goto out3; } +#if !defined(CONFIG_ACPI) + /* Enable ACPI mode to get Fn key events */ if (fnkeyinit) outb(0xf0, 0xb2); +#endif if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) sonypi_type2_srs(); @@ -666,6 +669,11 @@ sonypi_type2_dis(); else sonypi_type1_dis(); +#if !defined(CONFIG_ACPI) + /* disable ACPI mode */ + if (fnkeyinit) + outb(0xf1, 0xb2); +#endif free_irq(sonypi_device.irq, sonypi_irq); release_region(sonypi_device.ioport1, sonypi_device.region_size); misc_deregister(&sonypi_misc_device); diff -u --recursive --new-file v2.5.0/linux/drivers/char/sonypi.h linux/drivers/char/sonypi.h --- v2.5.0/linux/drivers/char/sonypi.h Mon Oct 15 08:38:31 2001 +++ linux/drivers/char/sonypi.h Thu Nov 29 07:53:34 2001 @@ -35,7 +35,7 @@ #ifdef __KERNEL__ #define SONYPI_DRIVER_MAJORVERSION 1 -#define SONYPI_DRIVER_MINORVERSION 7 +#define SONYPI_DRIVER_MINORVERSION 8 #include #include diff -u --recursive --new-file v2.5.0/linux/drivers/char/sysrq.c linux/drivers/char/sysrq.c --- v2.5.0/linux/drivers/char/sysrq.c Tue Oct 2 09:20:37 2001 +++ linux/drivers/char/sysrq.c Mon Dec 10 13:52:53 2001 @@ -336,7 +336,7 @@ /* Key Operations table and lock */ -spinlock_t sysrq_key_table_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t sysrq_key_table_lock = SPIN_LOCK_UNLOCKED; #define SYSRQ_KEY_TABLE_LENGTH 36 static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = { /* 0 */ &sysrq_loglevel_op, diff -u --recursive --new-file v2.5.0/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c --- v2.5.0/linux/drivers/char/tpqic02.c Fri Sep 14 14:40:00 2001 +++ linux/drivers/char/tpqic02.c Fri Nov 30 08:26:04 2001 @@ -2395,7 +2395,6 @@ { kdev_t dev = inode->i_rdev; - lock_kernel(); if (TP_DIAGS(dev)) { printk("qic02_tape_release: dev=%s\n", kdevname(dev)); } @@ -2419,7 +2418,6 @@ (void) do_qic_cmd(QCMD_REWIND, TIM_R); } } - unlock_kernel(); return 0; } /* qic02_tape_release */ diff -u --recursive --new-file v2.5.0/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v2.5.0/linux/drivers/char/tty_io.c Fri Nov 2 17:26:17 2001 +++ linux/drivers/char/tty_io.c Thu Nov 29 20:48:58 2001 @@ -102,10 +102,6 @@ #include -#ifdef CONFIG_VT -extern void con_init_devfs (void); -#endif - #define CONSOLE_DEV MKDEV(TTY_MAJOR,0) #define TTY_DEV MKDEV(TTYAUX_MAJOR,0) #define SYSCONS_DEV MKDEV(TTYAUX_MAJOR,1) @@ -2246,6 +2242,8 @@ static struct tty_driver dev_ptmx_driver; #endif #ifdef CONFIG_VT +extern void con_init_devfs (void); +extern void console_map_init(void); static struct tty_driver dev_console_driver; #endif @@ -2317,7 +2315,9 @@ if (tty_register_driver(&dev_console_driver)) panic("Couldn't register /dev/tty0 driver\n"); + vcs_init(); kbd_init(); + console_map_init(); #endif #ifdef CONFIG_ESPSERIAL /* init ESP before rs, so rs doesn't see the port */ @@ -2363,9 +2363,6 @@ #ifdef CONFIG_MOXA_INTELLIO moxa_init(); #endif -#ifdef CONFIG_VT - vcs_init(); -#endif #ifdef CONFIG_TN3270 tub3270_init(); #endif diff -u --recursive --new-file v2.5.0/linux/drivers/char/w83877f_wdt.c linux/drivers/char/w83877f_wdt.c --- v2.5.0/linux/drivers/char/w83877f_wdt.c Thu Sep 13 15:21:32 2001 +++ linux/drivers/char/w83877f_wdt.c Fri Nov 30 08:26:04 2001 @@ -214,7 +214,6 @@ static int fop_close(struct inode * inode, struct file * file) { - lock_kernel(); if(MINOR(inode->i_rdev) == WATCHDOG_MINOR) { if(wdt_expect_close) @@ -225,7 +224,6 @@ } } wdt_is_open = 0; - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/wdt.c linux/drivers/char/wdt.c --- v2.5.0/linux/drivers/char/wdt.c Fri Sep 7 09:28:38 2001 +++ linux/drivers/char/wdt.c Fri Nov 30 08:26:04 2001 @@ -50,7 +50,7 @@ #include #include -static int wdt_is_open; +static unsigned long wdt_is_open; /* * You must set these - there is no sane way to probe for this board. @@ -337,13 +337,12 @@ switch(MINOR(inode->i_rdev)) { case WATCHDOG_MINOR: - if(wdt_is_open) + if(test_and_set_bit(0, &wdt_is_open)) return -EBUSY; /* * Activate */ - wdt_is_open=1; inb_p(WDT_DC); /* Disable */ wdt_ctr_mode(0,3); wdt_ctr_mode(1,2); @@ -374,16 +373,14 @@ static int wdt_release(struct inode *inode, struct file *file) { - lock_kernel(); if(MINOR(inode->i_rdev)==WATCHDOG_MINOR) { #ifndef CONFIG_WATCHDOG_NOWAYOUT inb_p(WDT_DC); /* Disable counters */ wdt_ctr_load(2,0); /* 0 length reset pulses now */ #endif - wdt_is_open=0; + clear_bit(0, &wdt_is_open); } - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/char/wdt285.c linux/drivers/char/wdt285.c --- v2.5.0/linux/drivers/char/wdt285.c Fri Sep 7 09:28:38 2001 +++ linux/drivers/char/wdt285.c Fri Nov 30 08:26:04 2001 @@ -94,10 +94,8 @@ static int watchdog_release(struct inode *inode, struct file *file) { #ifdef ONLY_TESTING - lock_kernel(); free_irq(IRQ_TIMER4, NULL); timer_alive = 0; - unlock_kernel(); #else /* * It's irreversible! diff -u --recursive --new-file v2.5.0/linux/drivers/char/wdt977.c linux/drivers/char/wdt977.c --- v2.5.0/linux/drivers/char/wdt977.c Fri Sep 7 09:28:38 2001 +++ linux/drivers/char/wdt977.c Fri Nov 30 08:26:04 2001 @@ -92,7 +92,6 @@ * Lock it in if it's a module and we defined ...NOWAYOUT */ #ifndef CONFIG_WATCHDOG_NOWAYOUT - lock_kernel(); // unlock the SuperIO chip outb(0x87,0x370); @@ -124,7 +123,6 @@ outb(0xAA,0x370); timer_alive=0; - unlock_kernel(); printk(KERN_INFO "Watchdog: shutdown.\n"); #endif diff -u --recursive --new-file v2.5.0/linux/drivers/char/wdt_pci.c linux/drivers/char/wdt_pci.c --- v2.5.0/linux/drivers/char/wdt_pci.c Fri Sep 7 09:28:38 2001 +++ linux/drivers/char/wdt_pci.c Fri Nov 30 08:26:04 2001 @@ -71,7 +71,7 @@ #define PCI_DEVICE_ID_WDG_CSM 0x22c0 #endif -static int wdt_is_open; +static unsigned long wdt_is_open; /* * You must set these - there is no sane way to probe for this board. @@ -353,16 +353,16 @@ switch(MINOR(inode->i_rdev)) { case WATCHDOG_MINOR: - if(wdt_is_open) + if( test_and_set_bit(0,&wdt_is_open) ) + { return -EBUSY; + } #ifdef CONFIG_WATCHDOG_NOWAYOUT MOD_INC_USE_COUNT; #endif /* * Activate */ - - wdt_is_open=1; inb_p(WDT_DC); /* Disable */ @@ -412,13 +412,11 @@ { if(MINOR(inode->i_rdev)==WATCHDOG_MINOR) { - lock_kernel(); #ifndef CONFIG_WATCHDOG_NOWAYOUT inb_p(WDT_DC); /* Disable counters */ wdtpci_ctr_load(2,0); /* 0 length reset pulses now */ #endif - wdt_is_open=0; - unlock_kernel(); + clear_bit(0, &wdt_is_open ); } return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/fc4/fc.c linux/drivers/fc4/fc.c --- v2.5.0/linux/drivers/fc4/fc.c Fri Sep 14 14:04:08 2001 +++ linux/drivers/fc4/fc.c Sun Dec 16 12:20:20 2001 @@ -767,8 +767,12 @@ static void fcp_scsi_done (Scsi_Cmnd *SCpnt) { + unsigned long flags; + + spin_lock_irqsave(&SCpnt->host->host_lock, flags); if (FCP_CMND(SCpnt)->done) FCP_CMND(SCpnt)->done(SCpnt); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); } static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare) @@ -913,8 +917,12 @@ */ if (++fc->abort_count < (fc->can_queue >> 1)) { + unsigned long flags; + SCpnt->result = DID_ABORT; + spin_lock_irqsave(&SCpnt->host->host_lock, flags); fcmd->done(SCpnt); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); printk("FC: soft abort\n"); return SUCCESS; } else { diff -u --recursive --new-file v2.5.0/linux/drivers/fc4/soc.c linux/drivers/fc4/soc.c --- v2.5.0/linux/drivers/fc4/soc.c Thu Oct 11 09:14:32 2001 +++ linux/drivers/fc4/soc.c Sun Dec 16 12:20:20 2001 @@ -341,14 +341,14 @@ unsigned long flags; register struct soc *s = (struct soc *)dev_id; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&s->lock, flags); cmd = sbus_readl(s->regs + CMD); for (; (cmd = SOC_INTR (s, cmd)); cmd = sbus_readl(s->regs + CMD)) { if (cmd & SOC_CMD_RSP_Q1) soc_unsolicited (s); if (cmd & SOC_CMD_RSP_Q0) soc_solicited (s); if (cmd & SOC_CMD_REQ_QALL) soc_request (s, cmd); } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&s->lock, flags); } #define TOKEN(proto, port, token) (((proto)<<12)|(token)|(port)) @@ -559,6 +559,7 @@ if (s == NULL) return; memset (s, 0, sizeof(struct soc)); + spin_lock_init(&s->lock); s->soc_no = no; SOD(("socs %08lx soc_intr %08lx soc_hw_enque %08x\n", diff -u --recursive --new-file v2.5.0/linux/drivers/fc4/soc.h linux/drivers/fc4/soc.h --- v2.5.0/linux/drivers/fc4/soc.h Tue Jan 4 11:17:47 2000 +++ linux/drivers/fc4/soc.h Sun Dec 16 12:20:20 2001 @@ -265,6 +265,7 @@ } soc_cq; struct soc { + spinlock_t lock; soc_port port[2]; /* Every SOC has one or two FC ports */ soc_cq req[2]; /* Request CQs */ soc_cq rsp[2]; /* Response CQs */ diff -u --recursive --new-file v2.5.0/linux/drivers/fc4/socal.c linux/drivers/fc4/socal.c --- v2.5.0/linux/drivers/fc4/socal.c Thu Oct 11 09:14:32 2001 +++ linux/drivers/fc4/socal.c Sun Dec 16 12:20:20 2001 @@ -411,7 +411,7 @@ unsigned long flags; register struct socal *s = (struct socal *)dev_id; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&s->lock, flags); cmd = sbus_readl(s->regs + CMD); for (; (cmd = SOCAL_INTR (s, cmd)); cmd = sbus_readl(s->regs + CMD)) { #ifdef SOCALDEBUG @@ -428,7 +428,7 @@ if (cmd & SOCAL_CMD_REQ_QALL) socal_request (s, cmd); } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&s->lock, flags); } #define TOKEN(proto, port, token) (((proto)<<12)|(token)|(port)) @@ -667,6 +667,7 @@ s = kmalloc (sizeof (struct socal), GFP_KERNEL); if (!s) return; memset (s, 0, sizeof(struct socal)); + spin_lock_init(&s->lock); s->socal_no = no; SOD(("socals %08lx socal_intr %08lx socal_hw_enque %08lx\n", diff -u --recursive --new-file v2.5.0/linux/drivers/fc4/socal.h linux/drivers/fc4/socal.h --- v2.5.0/linux/drivers/fc4/socal.h Mon Dec 20 22:06:42 1999 +++ linux/drivers/fc4/socal.h Sun Dec 16 12:20:20 2001 @@ -290,6 +290,7 @@ } socal_cq; struct socal { + spinlock_t lock; socal_port port[2]; /* Every SOCAL has one or two FC ports */ socal_cq req[4]; /* Request CQs */ socal_cq rsp[4]; /* Response CQs */ diff -u --recursive --new-file v2.5.0/linux/drivers/i2c/i2c-dev.c linux/drivers/i2c/i2c-dev.c --- v2.5.0/linux/drivers/i2c/i2c-dev.c Thu Oct 11 08:05:47 2001 +++ linux/drivers/i2c/i2c-dev.c Fri Nov 30 08:26:04 2001 @@ -423,14 +423,9 @@ #endif #if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) MOD_DEC_USE_COUNT; -#else /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */ - lock_kernel(); #endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */ if (i2cdev_adaps[minor]->dec_use) i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]); -#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) - unlock_kernel(); -#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */ return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/ide/aec62xx.c linux/drivers/ide/aec62xx.c --- v2.5.0/linux/drivers/ide/aec62xx.c Tue Jun 20 07:52:36 2000 +++ linux/drivers/ide/aec62xx.c Tue Nov 27 09:23:27 2001 @@ -557,6 +557,7 @@ #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) hwif->dmaproc = &aec62xx_dmaproc; + hwif->highmem = 1; #else /* !CONFIG_BLK_DEV_IDEDMA */ hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; diff -u --recursive --new-file v2.5.0/linux/drivers/ide/amd74xx.c linux/drivers/ide/amd74xx.c --- v2.5.0/linux/drivers/ide/amd74xx.c Mon Aug 13 14:56:19 2001 +++ linux/drivers/ide/amd74xx.c Tue Nov 27 09:23:27 2001 @@ -75,7 +75,8 @@ { unsigned int class_rev; - if (dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) + if ((dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) || + (dev->device == PCI_DEVICE_ID_AMD_VIPER_7441)) return 0; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); @@ -122,8 +123,8 @@ pci_read_config_byte(dev, 0x4c, &pio_timing); #ifdef DEBUG - printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ", - drive->name, ultra_timing, dma_pio_timing, pio_timing); + printk("%s:%d: Speed 0x%02x UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n", + drive->name, drive->dn, speed, ultra_timing, dma_pio_timing, pio_timing); #endif ultra_timing &= ~0xC7; @@ -131,22 +132,19 @@ pio_timing &= ~(0x03 << drive->dn); #ifdef DEBUG - printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ", - ultra_timing, dma_pio_timing, pio_timing); + printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n", + drive->name, ultra_timing, dma_pio_timing, pio_timing); #endif switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA + case XFER_UDMA_7: + case XFER_UDMA_6: + speed = XFER_UDMA_5; case XFER_UDMA_5: -#undef __CAN_MODE_5 -#ifdef __CAN_MODE_5 ultra_timing |= 0x46; dma_pio_timing |= 0x20; break; -#else - printk("%s: setting to mode 4, driver problems in mode 5.\n", drive->name); - speed = XFER_UDMA_4; -#endif /* __CAN_MODE_5 */ case XFER_UDMA_4: ultra_timing |= 0x45; dma_pio_timing |= 0x20; @@ -222,8 +220,8 @@ pci_write_config_byte(dev, 0x4c, pio_timing); #ifdef DEBUG - printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n", - ultra_timing, dma_pio_timing, pio_timing); + printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n", + drive->name, ultra_timing, dma_pio_timing, pio_timing); #endif #ifdef CONFIG_BLK_DEV_IDEDMA @@ -303,11 +301,12 @@ struct pci_dev *dev = hwif->pci_dev; struct hd_driveid *id = drive->id; byte udma_66 = eighty_ninty_three(drive); - byte udma_100 = (dev->device==PCI_DEVICE_ID_AMD_VIPER_7411) ? 1 : 0; + byte udma_100 = ((dev->device==PCI_DEVICE_ID_AMD_VIPER_7411)|| + (dev->device==PCI_DEVICE_ID_AMD_VIPER_7441)) ? 1 : 0; byte speed = 0x00; int rval; - if ((id->dma_ultra & 0x0020) && (udma_66)&& (udma_100)) { + if ((id->dma_ultra & 0x0020) && (udma_66) && (udma_100)) { speed = XFER_UDMA_5; } else if ((id->dma_ultra & 0x0010) && (udma_66)) { speed = XFER_UDMA_4; @@ -331,7 +330,7 @@ (void) amd74xx_tune_chipset(drive, speed); - rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : ide_dma_off_quietly); @@ -352,7 +351,7 @@ } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { - if (id->dma_ultra & 0x002F) { + if (id->dma_ultra & 0x003F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive); if ((id->field_valid & 2) && diff -u --recursive --new-file v2.5.0/linux/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c --- v2.5.0/linux/drivers/ide/cmd64x.c Thu Jul 27 16:40:57 2000 +++ linux/drivers/ide/cmd64x.c Tue Nov 27 09:23:27 2001 @@ -795,5 +795,7 @@ default: break; } + + hwif->highmem = 1; #endif /* CONFIG_BLK_DEV_IDEDMA */ } diff -u --recursive --new-file v2.5.0/linux/drivers/ide/cs5530.c linux/drivers/ide/cs5530.c --- v2.5.0/linux/drivers/ide/cs5530.c Tue Jan 2 16:58:45 2001 +++ linux/drivers/ide/cs5530.c Tue Nov 27 09:23:27 2001 @@ -352,9 +352,10 @@ unsigned int basereg, d0_timings; #ifdef CONFIG_BLK_DEV_IDEDMA - hwif->dmaproc = &cs5530_dmaproc; + hwif->dmaproc = &cs5530_dmaproc; + hwif->highmem = 1; #else - hwif->autodma = 0; + hwif->autodma = 0; #endif /* CONFIG_BLK_DEV_IDEDMA */ hwif->tuneproc = &cs5530_tuneproc; diff -u --recursive --new-file v2.5.0/linux/drivers/ide/cy82c693.c linux/drivers/ide/cy82c693.c --- v2.5.0/linux/drivers/ide/cy82c693.c Sat May 19 17:43:06 2001 +++ linux/drivers/ide/cy82c693.c Tue Nov 27 09:23:27 2001 @@ -441,6 +441,7 @@ #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { + hwif->highmem = 1; hwif->dmaproc = &cy82c693_dmaproc; if (!noautodma) hwif->autodma = 1; diff -u --recursive --new-file v2.5.0/linux/drivers/ide/hd.c linux/drivers/ide/hd.c --- v2.5.0/linux/drivers/ide/hd.c Mon Oct 15 13:27:42 2001 +++ linux/drivers/ide/hd.c Sun Dec 16 15:37:16 2001 @@ -62,6 +62,8 @@ #define HD_IRQ IRQ_HARDDISK #endif +static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED; + static int revalidate_hddisk(kdev_t, int); #define HD_DELAY 0 @@ -106,8 +108,7 @@ static struct hd_struct hd[MAX_HD<<6]; static int hd_sizes[MAX_HD<<6]; static int hd_blocksizes[MAX_HD<<6]; -static int hd_hardsectsizes[MAX_HD<<6]; -static int hd_maxsect[MAX_HD<<6]; + static struct timer_list device_timer; @@ -465,7 +466,7 @@ i = --CURRENT->nr_sectors; --CURRENT->current_nr_sectors; CURRENT->buffer += 512; - if (!i || (CURRENT->bh && !SUBSECTOR(i))) + if (!i || (CURRENT->bio && !SUBSECTOR(i))) end_request(1); if (i > 0) { SET_INTR(&write_intr); @@ -560,19 +561,18 @@ dev = MINOR(CURRENT->rq_dev); block = CURRENT->sector; nsect = CURRENT->nr_sectors; - if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects || ((block+nsect) > hd[dev].nr_sects)) { -#ifdef DEBUG - if (dev >= (NR_HD<<6)) + if (dev >= (NR_HD<<6) || (dev & 0x3f) || + block >= hd[dev].nr_sects || ((block+nsect) > hd[dev].nr_sects)) { + if (dev >= (NR_HD<<6) || (dev & 0x3f)) printk("hd: bad minor number: device=%s\n", kdevname(CURRENT->rq_dev)); else printk("hd%c: bad access: block=%d, count=%d\n", (MINOR(CURRENT->rq_dev)>>6)+'a', block, nsect); -#endif end_request(0); goto repeat; } - block += hd[dev].start_sect; + dev >>= 6; if (special_op[dev]) { if (do_special_op(dev)) @@ -588,24 +588,29 @@ dev+'a', (CURRENT->cmd == READ)?"read":"writ", cyl, head, sec, nsect, (unsigned long) CURRENT->buffer); #endif - if (CURRENT->cmd == READ) { - hd_out(dev,nsect,sec,head,cyl,WIN_READ,&read_intr); - if (reset) - goto repeat; - return; - } - if (CURRENT->cmd == WRITE) { - hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr); - if (reset) - goto repeat; - if (wait_DRQ()) { - bad_rw_intr(); - goto repeat; + if(CURRENT->flags & REQ_CMD) { + switch (rq_data_dir(CURRENT)) { + case READ: + hd_out(dev,nsect,sec,head,cyl,WIN_READ,&read_intr); + if (reset) + goto repeat; + break; + case WRITE: + hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr); + if (reset) + goto repeat; + if (wait_DRQ()) { + bad_rw_intr(); + goto repeat; + } + outsw(HD_DATA,CURRENT->buffer,256); + break; + default: + printk("unknown hd-command\n"); + end_request(0); + break; } - outsw(HD_DATA,CURRENT->buffer,256); - return; } - panic("unknown hd-command"); } static void do_hd_request (request_queue_t * q) @@ -634,22 +639,17 @@ g.heads = hd_info[dev].head; g.sectors = hd_info[dev].sect; g.cylinders = hd_info[dev].cyl; - g.start = hd[MINOR(inode->i_rdev)].start_sect; + g.start = get_start_sect(inode->i_rdev); return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; } - case BLKGETSIZE: /* Return device size */ - return put_user(hd[MINOR(inode->i_rdev)].nr_sects, - (unsigned long *) arg); - case BLKGETSIZE64: - return put_user((u64)hd[MINOR(inode->i_rdev)].nr_sects << 9, - (u64 *) arg); - case BLKRRPART: /* Re-read partition tables */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; return revalidate_hddisk(inode->i_rdev, 1); + case BLKGETSIZE: + case BLKGETSIZE64: case BLKROSET: case BLKROGET: case BLKRASET: @@ -730,14 +730,11 @@ { int drive; - for(drive=0; drive < (MAX_HD << 6); drive++) { + for(drive=0; drive < (MAX_HD << 6); drive++) hd_blocksizes[drive] = 1024; - hd_hardsectsizes[drive] = 512; - hd_maxsect[drive]=255; - } + blksize_size[MAJOR_NR] = hd_blocksizes; - hardsect_size[MAJOR_NR] = hd_hardsectsizes; - max_sectors[MAJOR_NR] = hd_maxsect; + blk_queue_hardsect_size(QUEUE, 512); #ifdef __i386__ if (!NR_HD) { @@ -839,7 +836,8 @@ printk("hd: unable to get major %d for hard disk\n",MAJOR_NR); return -1; } - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST, &hd_lock); + blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), 255); read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */ add_gendisk(&hd_gendisk); init_timer(&device_timer); @@ -868,9 +866,7 @@ { int target; struct gendisk * gdev; - int max_p; - int start; - int i; + int res; long flags; target = DEVICE_NR(dev); @@ -885,25 +881,20 @@ DEVICE_BUSY = 1; restore_flags(flags); - max_p = gdev->max_p; - start = target << gdev->minor_shift; - - for (i=max_p - 1; i >=0 ; i--) { - int minor = start + i; - invalidate_device(MKDEV(MAJOR_NR, minor), 1); - gdev->part[minor].start_sect = 0; - gdev->part[minor].nr_sects = 0; - } + res = wipe_partitions(dev); + if (res) + goto leave; #ifdef MAYBE_REINIT MAYBE_REINIT; #endif - grok_partitions(gdev, target, 1<<6, CAPACITY); + grok_partitions(dev, CAPACITY); +leave: DEVICE_BUSY = 0; wake_up(&busy_wait); - return 0; + return res; } static int parse_hd_setup (char *line) { diff -u --recursive --new-file v2.5.0/linux/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c --- v2.5.0/linux/drivers/ide/hpt34x.c Sat May 19 17:43:06 2001 +++ linux/drivers/ide/hpt34x.c Tue Nov 27 09:23:27 2001 @@ -425,6 +425,7 @@ hwif->autodma = 0; hwif->dmaproc = &hpt34x_dmaproc; + hwif->highmem = 1; } else { hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; diff -u --recursive --new-file v2.5.0/linux/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c --- v2.5.0/linux/drivers/ide/hpt366.c Tue Aug 14 20:01:07 2001 +++ linux/drivers/ide/hpt366.c Tue Nov 27 09:23:27 2001 @@ -730,6 +730,7 @@ hwif->autodma = 1; else hwif->autodma = 0; + hwif->highmem = 1; } else { hwif->autodma = 0; hwif->drives[0].autotune = 1; diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c --- v2.5.0/linux/drivers/ide/ide-cd.c Wed Oct 24 23:53:51 2001 +++ linux/drivers/ide/ide-cd.c Sat Dec 8 20:02:47 2001 @@ -533,8 +533,8 @@ /* stuff the sense request in front of our current request */ rq = &info->request_sense_request; ide_init_drive_cmd(rq); - rq->cmd = REQUEST_SENSE_COMMAND; - rq->buffer = (char *) pc; + rq->flags = REQ_SENSE; + rq->special = (char *) pc; rq->waiting = wait; (void) ide_do_drive_cmd(drive, rq, ide_preempt); } @@ -544,17 +544,17 @@ { struct request *rq = HWGROUP(drive)->rq; - if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate) { - struct packet_command *pc = (struct packet_command *) rq->buffer; + if ((rq->flags & REQ_SENSE) && uptodate) { + struct packet_command *pc = (struct packet_command *) rq->special; cdrom_analyze_sense_data(drive, (struct packet_command *) pc->sense, (struct request_sense *) (pc->buffer - pc->c[4])); } - if (rq->cmd == READ || rq->cmd == WRITE) - if (!rq->current_nr_sectors) - uptodate = 1; - ide_end_request (uptodate, HWGROUP(drive)); + if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors) + uptodate = 1; + + ide_end_request(uptodate, HWGROUP(drive)); } @@ -584,21 +584,20 @@ return 1; } - if (rq->cmd == REQUEST_SENSE_COMMAND) { + if (rq->flags & REQ_SENSE) { /* We got an error trying to get sense info from the drive (probably while trying to recover from a former error). Just give up. */ - pc = (struct packet_command *) rq->buffer; + pc = (struct packet_command *) rq->special; pc->stat = 1; cdrom_end_request (1, drive); *startstop = ide_error (drive, "request sense failure", stat); return 1; - - } else if (rq->cmd == PACKET_COMMAND) { + } else if (rq->flags & REQ_PC) { /* All other functions, except for READ. */ struct completion *wait = NULL; - pc = (struct packet_command *) rq->buffer; + pc = (struct packet_command *) rq->special; /* Check for tray open. */ if (sense_key == NOT_READY) { @@ -632,7 +631,7 @@ if ((stat & ERR_STAT) != 0) cdrom_queue_request_sense(drive, wait, pc->sense, pc); - } else { + } else if (rq->flags & REQ_CMD) { /* Handle errors from READ and WRITE requests. */ if (sense_key == NOT_READY) { @@ -671,7 +670,8 @@ queue a request sense command. */ if ((stat & ERR_STAT) != 0) cdrom_queue_request_sense(drive, NULL, NULL, NULL); - } + } else + blk_dump_rq_flags(rq, "ide-cd bad flags"); /* Retry, or handle the next request. */ *startstop = ide_stopped; @@ -681,7 +681,6 @@ static int cdrom_timer_expiry(ide_drive_t *drive) { struct request *rq = HWGROUP(drive)->rq; - struct packet_command *pc = (struct packet_command *) rq->buffer; unsigned long wait = 0; /* @@ -690,7 +689,7 @@ * this, but not all commands/drives support that. Let * ide_timer_expiry keep polling us for these. */ - switch (pc->c[0]) { + switch (rq->cmd[0]) { case GPCMD_BLANK: case GPCMD_FORMAT_UNIT: case GPCMD_RESERVE_RZONE_TRACK: @@ -700,6 +699,7 @@ wait = 0; break; } + return wait; } @@ -891,7 +891,7 @@ int stat; int ireason, len, sectors_to_transfer, nskip; struct cdrom_info *info = drive->driver_data; - int i, dma = info->dma, dma_error = 0; + int dma = info->dma, dma_error = 0; ide_startstop_t startstop; struct request *rq = HWGROUP(drive)->rq; @@ -908,10 +908,7 @@ if (dma) { if (!dma_error) { - for (i = rq->nr_sectors; i > 0;) { - i -= rq->current_nr_sectors; - ide_end_request(1, HWGROUP(drive)); - } + __ide_end_request(HWGROUP(drive), 1, rq->nr_sectors); return ide_stopped; } else return ide_error (drive, "dma error", stat); @@ -926,7 +923,7 @@ /* If we're not done filling the current buffer, complain. Otherwise, complete the command normally. */ if (rq->current_nr_sectors > 0) { - printk ("%s: cdrom_read_intr: data underrun (%ld blocks)\n", + printk ("%s: cdrom_read_intr: data underrun (%u blocks)\n", drive->name, rq->current_nr_sectors); cdrom_end_request (0, drive); } else @@ -959,8 +956,7 @@ /* First, figure out if we need to bit-bucket any of the leading sectors. */ - nskip = MIN ((int)(rq->current_nr_sectors - (rq->bh->b_size >> SECTOR_BITS)), - sectors_to_transfer); + nskip = MIN(rq->current_nr_sectors - bio_sectors(rq->bio), sectors_to_transfer); while (nskip > 0) { /* We need to throw away a sector. */ @@ -1058,7 +1054,7 @@ represent the number of sectors to skip at the start of a transfer will fail. I think that this will never happen, but let's be paranoid and check. */ - if (rq->current_nr_sectors < (rq->bh->b_size >> SECTOR_BITS) && + if (rq->current_nr_sectors < bio_sectors(rq->bio) && (rq->sector % SECTORS_PER_FRAME) != 0) { printk ("%s: cdrom_read_from_buffer: buffer botch (%ld)\n", drive->name, rq->sector); @@ -1097,9 +1093,9 @@ nskip = (sector % SECTORS_PER_FRAME); if (nskip > 0) { /* Sanity check... */ - if (rq->current_nr_sectors != (rq->bh->b_size >> SECTOR_BITS) && + if (rq->current_nr_sectors != bio_sectors(rq->bio) && (rq->sector % CD_FRAMESIZE != 0)) { - printk ("%s: cdrom_start_read_continuation: buffer botch (%lu)\n", + printk ("%s: cdrom_start_read_continuation: buffer botch (%u)\n", drive->name, rq->current_nr_sectors); cdrom_end_request (0, drive); return ide_stopped; @@ -1120,11 +1116,7 @@ (65534 / CD_FRAMESIZE) : 65535); /* Set up the command */ - memset (&pc.c, 0, sizeof (pc.c)); - pc.c[0] = GPCMD_READ_10; - pc.c[7] = (nframes >> 8); - pc.c[8] = (nframes & 0xff); - put_unaligned(cpu_to_be32(frame), (unsigned int *) &pc.c[2]); + memcpy(pc.c, rq->cmd, sizeof(pc.c)); pc.timeout = WAIT_CMD; /* Send the command to the drive and return. */ @@ -1174,7 +1166,7 @@ sector -= nskip; frame = sector / SECTORS_PER_FRAME; - memset (&pc.c, 0, sizeof (pc.c)); + memset(rq->cmd, 0, sizeof(rq->cmd)); pc.c[0] = GPCMD_SEEK; put_unaligned(cpu_to_be32(frame), (unsigned int *) &pc.c[2]); @@ -1192,68 +1184,23 @@ return cdrom_start_packet_command (drive, 0, cdrom_start_seek_continuation); } -static inline int cdrom_merge_requests(struct request *rq, struct request *nxt) -{ - int ret = 1; - - /* - * partitions not really working, but better check anyway... - */ - if (rq->cmd == nxt->cmd && rq->rq_dev == nxt->rq_dev) { - rq->nr_sectors += nxt->nr_sectors; - rq->hard_nr_sectors += nxt->nr_sectors; - rq->bhtail->b_reqnext = nxt->bh; - rq->bhtail = nxt->bhtail; - list_del(&nxt->queue); - blkdev_release_request(nxt); - ret = 0; - } - - return ret; -} - /* - * the current request will always be the first one on the list + * Fix up a possibly partially-processed request so that we can + * start it over entirely -- remember to call prep_rq_fn again since we + * may have changed the layout */ -static void cdrom_attempt_remerge(ide_drive_t *drive, struct request *rq) -{ - struct list_head *entry; - struct request *nxt; - unsigned long flags; - - spin_lock_irqsave(&io_request_lock, flags); - - while (1) { - entry = rq->queue.next; - if (entry == &drive->queue.queue_head) - break; - - nxt = blkdev_entry_to_request(entry); - if (rq->sector + rq->nr_sectors != nxt->sector) - break; - else if (rq->nr_sectors + nxt->nr_sectors > SECTORS_MAX) - break; - - if (cdrom_merge_requests(rq, nxt)) - break; - } - - spin_unlock_irqrestore(&io_request_lock, flags); -} - -/* Fix up a possibly partially-processed request so that we can - start it over entirely, or even put it back on the request queue. */ static void restore_request (struct request *rq) { - if (rq->buffer != rq->bh->b_data) { - int n = (rq->buffer - rq->bh->b_data) / SECTOR_SIZE; - rq->buffer = rq->bh->b_data; + if (rq->buffer != bio_data(rq->bio)) { + int n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE; + rq->buffer = bio_data(rq->bio); rq->nr_sectors += n; rq->sector -= n; } - rq->current_nr_sectors = rq->bh->b_size >> SECTOR_BITS; + rq->hard_cur_sectors = rq->current_nr_sectors = bio_sectors(rq->bio); rq->hard_nr_sectors = rq->nr_sectors; rq->hard_sector = rq->sector; + rq->q->prep_rq_fn(rq->q, rq); } /* @@ -1263,25 +1210,14 @@ { struct cdrom_info *info = drive->driver_data; struct request *rq = HWGROUP(drive)->rq; - int minor = MINOR (rq->rq_dev); - - /* If the request is relative to a partition, fix it up to refer to the - absolute address. */ - if (minor & PARTN_MASK) { - rq->sector = block; - minor &= ~PARTN_MASK; - rq->rq_dev = MKDEV(MAJOR(rq->rq_dev), minor); - } - /* We may be retrying this request after an error. Fix up - any weirdness which might be present in the request packet. */ restore_request(rq); /* Satisfy whatever we can of this request from our cached sector. */ if (cdrom_read_from_buffer(drive)) return ide_stopped; - cdrom_attempt_remerge(drive, rq); + blk_attempt_remerge(&drive->queue, rq); /* Clear the local sector buffer. */ info->nsectors_buffered = 0; @@ -1311,7 +1247,7 @@ { int ireason, len, stat, thislen; struct request *rq = HWGROUP(drive)->rq; - struct packet_command *pc = (struct packet_command *)rq->buffer; + struct packet_command *pc = (struct packet_command *) rq->special; ide_startstop_t startstop; /* Check for errors. */ @@ -1407,7 +1343,7 @@ static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive) { struct request *rq = HWGROUP(drive)->rq; - struct packet_command *pc = (struct packet_command *)rq->buffer; + struct packet_command *pc = (struct packet_command *) rq->special; if (!pc->timeout) pc->timeout = WAIT_CMD; @@ -1421,7 +1357,7 @@ { int len; struct request *rq = HWGROUP(drive)->rq; - struct packet_command *pc = (struct packet_command *)rq->buffer; + struct packet_command *pc = (struct packet_command *) rq->special; struct cdrom_info *info = drive->driver_data; info->dma = 0; @@ -1460,8 +1396,8 @@ /* Start of retry loop. */ do { ide_init_drive_cmd (&req); - req.cmd = PACKET_COMMAND; - req.buffer = (char *)pc; + req.flags = REQ_PC; + req.special = (char *) pc; if (ide_do_drive_cmd (drive, &req, ide_wait)) { printk("%s: do_drive_cmd returned stat=%02x,err=%02x\n", drive->name, req.buffer[0], req.buffer[1]); @@ -1532,7 +1468,7 @@ { int stat, ireason, len, sectors_to_transfer, uptodate; struct cdrom_info *info = drive->driver_data; - int i, dma_error = 0, dma = info->dma; + int dma_error = 0, dma = info->dma; ide_startstop_t startstop; struct request *rq = HWGROUP(drive)->rq; @@ -1559,10 +1495,7 @@ return ide_error(drive, "dma error", stat); rq = HWGROUP(drive)->rq; - for (i = rq->nr_sectors; i > 0;) { - i -= rq->current_nr_sectors; - ide_end_request(1, HWGROUP(drive)); - } + __ide_end_request(HWGROUP(drive), 1, rq->nr_sectors); return ide_stopped; } @@ -1577,7 +1510,7 @@ */ uptodate = 1; if (rq->current_nr_sectors > 0) { - printk("%s: write_intr: data underrun (%ld blocks)\n", + printk("%s: write_intr: data underrun (%u blocks)\n", drive->name, rq->current_nr_sectors); uptodate = 0; } @@ -1639,18 +1572,10 @@ nframes = rq->nr_sectors >> 2; frame = rq->sector >> 2; - memset(&pc.c, 0, sizeof(pc.c)); - /* - * we might as well use WRITE_12, but none of the device I have - * support the streaming feature anyway, so who cares. - */ - pc.c[0] = GPCMD_WRITE_10; + memcpy(pc.c, rq->cmd, sizeof(pc.c)); #if 0 /* the immediate bit */ pc.c[1] = 1 << 3; #endif - pc.c[7] = (nframes >> 8) & 0xff; - pc.c[8] = nframes & 0xff; - put_unaligned(cpu_to_be32(frame), (unsigned int *)&pc.c[2]); pc.timeout = 2 * WAIT_CMD; return cdrom_transfer_packet_command(drive, &pc, cdrom_write_intr); @@ -1674,7 +1599,7 @@ * remerge requests, often the plugging will not have had time * to do this properly */ - cdrom_attempt_remerge(drive, rq); + blk_attempt_remerge(&drive->queue, rq); info->nsectors_buffered = 0; @@ -1687,6 +1612,28 @@ return cdrom_start_packet_command(drive, 32768, cdrom_start_write_cont); } +/* + * just wrap this around cdrom_do_packet_command + */ +static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) +{ + struct packet_command pc; + ide_startstop_t startstop; + + memset(&pc, 0, sizeof(pc)); + memcpy(pc.c, rq->cmd, sizeof(pc.c)); + pc.quiet = 1; + pc.timeout = 60 * HZ; + rq->special = (char *) &pc; + + startstop = cdrom_do_packet_command(drive); + if (pc.stat) + rq->errors++; + + return startstop; +} + + /**************************************************************************** * cdrom driver request routine. */ @@ -1696,50 +1643,45 @@ ide_startstop_t action; struct cdrom_info *info = drive->driver_data; - switch (rq->cmd) { - case WRITE: - case READ: { - if (CDROM_CONFIG_FLAGS(drive)->seeking) { - unsigned long elpased = jiffies - info->start_seek; - int stat = GET_STAT(); - - if ((stat & SEEK_STAT) != SEEK_STAT) { - if (elpased < IDECD_SEEK_TIMEOUT) { - ide_stall_queue(drive, IDECD_SEEK_TIMER); - return ide_stopped; - } - printk ("%s: DSC timeout\n", drive->name); + if (rq->flags & REQ_CMD) { + if (CDROM_CONFIG_FLAGS(drive)->seeking) { + unsigned long elpased = jiffies - info->start_seek; + int stat = GET_STAT(); + + if ((stat & SEEK_STAT) != SEEK_STAT) { + if (elpased < IDECD_SEEK_TIMEOUT) { + ide_stall_queue(drive, IDECD_SEEK_TIMER); + return ide_stopped; } - CDROM_CONFIG_FLAGS(drive)->seeking = 0; + printk ("%s: DSC timeout\n", drive->name); } - if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) - action = cdrom_start_seek (drive, block); - else { - if (rq->cmd == READ) - action = cdrom_start_read(drive, block); - else - action = cdrom_start_write(drive, rq); - } - info->last_block = block; - return action; - } - - case PACKET_COMMAND: - case REQUEST_SENSE_COMMAND: { - return cdrom_do_packet_command(drive); - } - - case RESET_DRIVE_COMMAND: { - cdrom_end_request(1, drive); - return ide_do_reset(drive); + CDROM_CONFIG_FLAGS(drive)->seeking = 0; } - - default: { - printk("ide-cd: bad cmd %d\n", rq->cmd); - cdrom_end_request(0, drive); - return ide_stopped; + if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) + action = cdrom_start_seek (drive, block); + else { + if (rq_data_dir(rq) == READ) + action = cdrom_start_read(drive, block); + else + action = cdrom_start_write(drive, rq); } + info->last_block = block; + return action; + } else if (rq->flags & (REQ_PC | REQ_SENSE)) { + return cdrom_do_packet_command(drive); + } else if (rq->flags & REQ_SPECIAL) { + /* + * right now this can only be a reset... + */ + cdrom_end_request(1, drive); + return ide_do_reset(drive); + } else if (rq->flags & REQ_BLOCK_PC) { + return cdrom_do_block_pc(drive, rq); } + + blk_dump_rq_flags(rq, "ide-cd bad flags"); + cdrom_end_request(0, drive); + return ide_stopped; } @@ -2202,9 +2144,13 @@ pc.quiet = cgc->quiet; pc.timeout = cgc->timeout; pc.sense = cgc->sense; - return cgc->stat = cdrom_queue_packet_command(drive, &pc); + cgc->stat = cdrom_queue_packet_command(drive, &pc); + if (!cgc->stat) + cgc->buflen -= pc.buflen; + return cgc->stat; } + static int ide_cdrom_dev_ioctl (struct cdrom_device_info *cdi, unsigned int cmd, unsigned long arg) @@ -2338,7 +2284,7 @@ int ret; ide_init_drive_cmd (&req); - req.cmd = RESET_DRIVE_COMMAND; + req.flags = REQ_SPECIAL; ret = ide_do_drive_cmd(drive, &req, ide_wait); /* @@ -2711,7 +2657,6 @@ ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL); ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, INT_MAX, 1, 1024, &max_readahead[major][minor], NULL); - ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL); ide_add_setting(drive, "dsc_overlap", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL); } @@ -2728,6 +2673,7 @@ */ set_device_ro(MKDEV(HWIF(drive)->major, minor), 1); set_blocksize(MKDEV(HWIF(drive)->major, minor), CD_FRAMESIZE); + blk_queue_hardsect_size(&drive->queue, CD_FRAMESIZE); drive->special.all = 0; drive->ready_stat = 0; @@ -2875,7 +2821,7 @@ MOD_INC_USE_COUNT; if (info->buffer == NULL) info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL); - if ((info->buffer == NULL) || (rc = cdrom_open(ip, fp))) { + if ((info->buffer == NULL) || (rc = cdrom_open(ip, fp))) { drive->usage--; MOD_DEC_USE_COUNT; } diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide-cd.h linux/drivers/ide/ide-cd.h --- v2.5.0/linux/drivers/ide/ide-cd.h Thu Nov 22 11:46:58 2001 +++ linux/drivers/ide/ide-cd.h Sun Dec 16 15:45:39 2001 @@ -435,7 +435,7 @@ byte curlba[3]; byte nslots; - __u8 short slot_tablelen; + __u16 slot_tablelen; }; diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide-cs.c linux/drivers/ide/ide-cs.c --- v2.5.0/linux/drivers/ide/ide-cs.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/ide/ide-cs.c Sun Nov 25 09:48:08 2001 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -226,6 +227,16 @@ #define CFG_CHECK(fn, args...) \ if (CardServices(fn, args) != 0) goto next_entry +int idecs_register (int io_base, int ctl_base, int irq) +{ + hw_regs_t hw; + ide_init_hwif_ports(&hw, (ide_ioreg_t) io_base, (ide_ioreg_t) ctl_base, NULL); + hw.irq = irq; + hw.chipset = ide_pci; // this enables IRQ sharing w/ PCI irqs + return ide_register_hw(&hw, NULL); +} + + void ide_config(dev_link_t *link) { client_handle_t handle = link->handle; @@ -327,12 +338,16 @@ if (link->io.NumPorts2) release_region(link->io.BasePort2, link->io.NumPorts2); + /* disable drive interrupts during IDE probe */ + if(ctl_base) + outb(0x02, ctl_base); + /* retry registration in case device is still spinning up */ for (i = 0; i < 10; i++) { - hd = ide_register(io_base, ctl_base, link->irq.AssignedIRQ); + hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ); if (hd >= 0) break; if (link->io.NumPorts1 == 0x20) { - hd = ide_register(io_base+0x10, ctl_base+0x10, + hd = idecs_register(io_base+0x10, ctl_base+0x10, link->irq.AssignedIRQ); if (hd >= 0) { io_base += 0x10; ctl_base += 0x10; diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c --- v2.5.0/linux/drivers/ide/ide-disk.c Tue Nov 20 21:35:28 2001 +++ linux/drivers/ide/ide-disk.c Thu Dec 6 14:02:57 2001 @@ -27,6 +27,7 @@ * Version 1.09 added increment of rq->sector in ide_multwrite * added UDMA 3/4 reporting * Version 1.10 request queue changes, Ultra DMA 100 + * Version 1.11 Highmem I/O support, Jens Axboe */ #define IDEDISK_VERSION "1.10" @@ -139,7 +140,9 @@ byte stat; int i; unsigned int msect, nsect; + unsigned long flags; struct request *rq; + char *to; /* new way for dealing with premature shared PCI interrupts */ if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { @@ -150,8 +153,8 @@ ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); return ide_started; } + msect = drive->mult_count; - read_next: rq = HWGROUP(drive)->rq; if (msect) { @@ -160,14 +163,15 @@ msect -= nsect; } else nsect = 1; - idedisk_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); + to = ide_map_buffer(rq, &flags); + idedisk_input_data(drive, to, nsect * SECTOR_WORDS); #ifdef DEBUG printk("%s: read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n", drive->name, rq->sector, rq->sector+nsect-1, (unsigned long) rq->buffer+(nsect<<9), rq->nr_sectors-nsect); #endif + ide_unmap_buffer(to, &flags); rq->sector += nsect; - rq->buffer += nsect<<9; rq->errors = 0; i = (rq->nr_sectors -= nsect); if (((long)(rq->current_nr_sectors -= nsect)) <= 0) @@ -201,14 +205,16 @@ #endif if ((rq->nr_sectors == 1) ^ ((stat & DRQ_STAT) != 0)) { rq->sector++; - rq->buffer += 512; rq->errors = 0; i = --rq->nr_sectors; --rq->current_nr_sectors; if (((long)rq->current_nr_sectors) <= 0) ide_end_request(1, hwgroup); if (i > 0) { - idedisk_output_data (drive, rq->buffer, SECTOR_WORDS); + unsigned long flags; + char *to = ide_map_buffer(rq, &flags); + idedisk_output_data (drive, to, SECTOR_WORDS); + ide_unmap_buffer(to, &flags); ide_set_handler (drive, &write_intr, WAIT_CMD, NULL); return ide_started; } @@ -238,28 +244,28 @@ do { char *buffer; int nsect = rq->current_nr_sectors; - + unsigned long flags; + if (nsect > mcount) nsect = mcount; mcount -= nsect; - buffer = rq->buffer; + buffer = ide_map_buffer(rq, &flags); rq->sector += nsect; - rq->buffer += nsect << 9; rq->nr_sectors -= nsect; rq->current_nr_sectors -= nsect; /* Do we move to the next bh after this? */ if (!rq->current_nr_sectors) { - struct buffer_head *bh = rq->bh->b_reqnext; + struct bio *bio = rq->bio->bi_next; /* end early early we ran out of requests */ - if (!bh) { + if (!bio) { mcount = 0; } else { - rq->bh = bh; - rq->current_nr_sectors = bh->b_size >> 9; - rq->buffer = bh->b_data; + rq->bio = bio; + rq->current_nr_sectors = bio_sectors(bio); + rq->hard_cur_sectors = rq->current_nr_sectors; } } @@ -268,6 +274,7 @@ * re-entering us on the last transfer. */ idedisk_output_data(drive, buffer, nsect<<7); + ide_unmap_buffer(buffer, &flags); } while (mcount); return 0; @@ -279,7 +286,6 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive) { byte stat; - int i; ide_hwgroup_t *hwgroup = HWGROUP(drive); struct request *rq = &hwgroup->wrq; @@ -302,10 +308,8 @@ */ if (!rq->nr_sectors) { /* all done? */ rq = hwgroup->rq; - for (i = rq->nr_sectors; i > 0;){ - i -= rq->current_nr_sectors; - ide_end_request(1, hwgroup); - } + + __ide_end_request(hwgroup, 1, rq->nr_sectors); return ide_stopped; } } @@ -367,6 +371,8 @@ */ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) { + unsigned long flags; + if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl,IDE_CONTROL_REG); OUT_BYTE(0x00, IDE_FEATURE_REG); @@ -378,7 +384,7 @@ #endif /* CONFIG_BLK_DEV_PDC4030 */ #ifdef DEBUG printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n", - drive->name, (rq->cmd==READ)?"read":"writ", + drive->name, (rq_data_dir(rq)==READ)?"read":"writ", block, rq->nr_sectors, (unsigned long) rq->buffer); #endif OUT_BYTE(block,IDE_SECTOR_REG); @@ -397,7 +403,7 @@ OUT_BYTE(head|drive->select.all,IDE_SELECT_REG); #ifdef DEBUG printk("%s: %sing: CHS=%d/%d/%d, sectors=%ld, buffer=0x%08lx\n", - drive->name, (rq->cmd==READ)?"read":"writ", cyl, + drive->name, (rq_data_dir(rq)==READ)?"read":"writ", cyl, head, sect, rq->nr_sectors, (unsigned long) rq->buffer); #endif } @@ -407,7 +413,7 @@ return do_pdc4030_io (drive, rq); } #endif /* CONFIG_BLK_DEV_PDC4030 */ - if (rq->cmd == READ) { + if (rq_data_dir(rq) == READ) { #ifdef CONFIG_BLK_DEV_IDEDMA if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_read, drive))) return ide_started; @@ -416,7 +422,7 @@ OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG); return ide_started; } - if (rq->cmd == WRITE) { + if (rq_data_dir(rq) == WRITE) { ide_startstop_t startstop; #ifdef CONFIG_BLK_DEV_IDEDMA if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_write, drive))) @@ -444,20 +450,21 @@ hwgroup->wrq = *rq; /* scratchpad */ ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL); if (ide_multwrite(drive, drive->mult_count)) { - unsigned long flags; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&ide_lock, flags); hwgroup->handler = NULL; del_timer(&hwgroup->timer); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&ide_lock, flags); return ide_stopped; } } else { + char *buffer = ide_map_buffer(rq, &flags); ide_set_handler (drive, &write_intr, WAIT_CMD, NULL); - idedisk_output_data(drive, rq->buffer, SECTOR_WORDS); + idedisk_output_data(drive, buffer, SECTOR_WORDS); + ide_unmap_buffer(buffer, &flags); } return ide_started; } - printk(KERN_ERR "%s: bad command: %d\n", drive->name, rq->cmd); + printk(KERN_ERR "%s: bad command: %lx\n", drive->name, rq->flags); ide_end_request(0, HWGROUP(drive)); return ide_stopped; } @@ -482,7 +489,8 @@ { if (drive->removable && !drive->usage) { invalidate_bdev(inode->i_bdev, 0); - if (drive->doorlocking && ide_wait_cmd(drive, WIN_DOORUNLOCK, 0, 0, 0, NULL)) + if (drive->doorlocking && + ide_wait_cmd(drive, WIN_DOORUNLOCK, 0, 0, 0, NULL)) drive->doorlocking = 0; } MOD_DEC_USE_COUNT; @@ -495,9 +503,7 @@ static void idedisk_revalidate (ide_drive_t *drive) { - grok_partitions(HWIF(drive)->gd, drive->select.b.unit, - 1<nowerr = arg; drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&ide_lock); return 0; } @@ -691,7 +697,6 @@ ide_add_setting(drive, "nowerr", SETTING_RW, HDIO_GET_NOWERR, HDIO_SET_NOWERR, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr); ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL); ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, 4096, PAGE_SIZE, 1024, &max_readahead[major][minor], NULL); - ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL); ide_add_setting(drive, "lun", SETTING_RW, -1, -1, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL); ide_add_setting(drive, "failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL); ide_add_setting(drive, "max_failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL); diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c --- v2.5.0/linux/drivers/ide/ide-dma.c Sun Sep 9 10:43:02 2001 +++ linux/drivers/ide/ide-dma.c Sun Dec 16 12:20:20 2001 @@ -203,30 +203,10 @@ #endif /* CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */ /* - * Our Physical Region Descriptor (PRD) table should be large enough - * to handle the biggest I/O request we are likely to see. Since requests - * can have no more than 256 sectors, and since the typical blocksize is - * two or more sectors, we could get by with a limit of 128 entries here for - * the usual worst case. Most requests seem to include some contiguous blocks, - * further reducing the number of table entries required. - * - * The driver reverts to PIO mode for individual requests that exceed - * this limit (possible with 512 byte blocksizes, eg. MSDOS f/s), so handling - * 100% of all crazy scenarios here is not necessary. - * - * As it turns out though, we must allocate a full 4KB page for this, - * so the two PRD tables (ide0 & ide1) will each get half of that, - * allowing each to have about 256 entries (8 bytes each) from this. - */ -#define PRD_BYTES 8 -#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES)) - -/* * dma_intr() is the handler for disk read/write DMA interrupts */ ide_startstop_t ide_dma_intr (ide_drive_t *drive) { - int i; byte stat, dma_stat; dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive); @@ -234,11 +214,8 @@ if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) { if (!dma_stat) { struct request *rq = HWGROUP(drive)->rq; - rq = HWGROUP(drive)->rq; - for (i = rq->nr_sectors; i > 0;) { - i -= rq->current_nr_sectors; - ide_end_request(1, HWGROUP(drive)); - } + + __ide_end_request(HWGROUP(drive), 1, rq->nr_sectors); return ide_stopped; } printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n", @@ -249,35 +226,19 @@ static int ide_build_sglist (ide_hwif_t *hwif, struct request *rq) { - struct buffer_head *bh; + request_queue_t *q = &hwif->drives[DEVICE_NR(rq->rq_dev) & 1].queue; struct scatterlist *sg = hwif->sg_table; - int nents = 0; + int nents; + + nents = blk_rq_map_sg(q, rq, hwif->sg_table); + + if (rq->q && nents > rq->nr_phys_segments) + printk("ide-dma: received %d phys segments, build %d\n", rq->nr_phys_segments, nents); - if (hwif->sg_dma_active) - BUG(); - - if (rq->cmd == READ) + if (rq_data_dir(rq) == READ) hwif->sg_dma_direction = PCI_DMA_FROMDEVICE; else hwif->sg_dma_direction = PCI_DMA_TODEVICE; - bh = rq->bh; - do { - unsigned char *virt_addr = bh->b_data; - unsigned int size = bh->b_size; - - if (nents >= PRD_ENTRIES) - return 0; - - while ((bh = bh->b_reqnext) != NULL) { - if ((virt_addr + size) != (unsigned char *) bh->b_data) - break; - size += bh->b_size; - } - memset(&sg[nents], 0, sizeof(*sg)); - sg[nents].address = virt_addr; - sg[nents].length = size; - nents++; - } while (bh != NULL); return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction); } @@ -289,9 +250,10 @@ */ int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func) { - unsigned int *table = HWIF(drive)->dmatable_cpu; + ide_hwif_t *hwif = HWIF(drive); + unsigned int *table = hwif->dmatable_cpu; #ifdef CONFIG_BLK_DEV_TRM290 - unsigned int is_trm290_chipset = (HWIF(drive)->chipset == ide_trm290); + unsigned int is_trm290_chipset = (hwif->chipset == ide_trm290); #else const int is_trm290_chipset = 0; #endif @@ -299,13 +261,12 @@ int i; struct scatterlist *sg; - HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq); - + hwif->sg_nents = i = ide_build_sglist(hwif, HWGROUP(drive)->rq); if (!i) return 0; - sg = HWIF(drive)->sg_table; - while (i && sg_dma_len(sg)) { + sg = hwif->sg_table; + while (i) { u32 cur_addr; u32 cur_len; @@ -319,55 +280,53 @@ */ while (cur_len) { + u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff); + if (count++ >= PRD_ENTRIES) { - printk("%s: DMA table too small\n", drive->name); - goto use_pio_instead; - } else { - u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff); - - if (bcount > cur_len) - bcount = cur_len; - *table++ = cpu_to_le32(cur_addr); - xcount = bcount & 0xffff; - if (is_trm290_chipset) - xcount = ((xcount >> 2) - 1) << 16; - if (xcount == 0x0000) { - /* - * Most chipsets correctly interpret a length of 0x0000 as 64KB, - * but at least one (e.g. CS5530) misinterprets it as zero (!). - * So here we break the 64KB entry into two 32KB entries instead. - */ - if (count++ >= PRD_ENTRIES) { - printk("%s: DMA table too small\n", drive->name); - goto use_pio_instead; - } - *table++ = cpu_to_le32(0x8000); - *table++ = cpu_to_le32(cur_addr + 0x8000); - xcount = 0x8000; + printk("ide-dma: req %p\n", HWGROUP(drive)->rq); + printk("count %d, sg_nents %d, cur_len %d, cur_addr %u\n", count, hwif->sg_nents, cur_len, cur_addr); + BUG(); + } + + if (bcount > cur_len) + bcount = cur_len; + *table++ = cpu_to_le32(cur_addr); + xcount = bcount & 0xffff; + if (is_trm290_chipset) + xcount = ((xcount >> 2) - 1) << 16; + if (xcount == 0x0000) { + /* + * Most chipsets correctly interpret a length of + * 0x0000 as 64KB, but at least one (e.g. CS5530) + * misinterprets it as zero (!). So here we break + * the 64KB entry into two 32KB entries instead. + */ + if (count++ >= PRD_ENTRIES) { + pci_unmap_sg(hwif->pci_dev, sg, + hwif->sg_nents, + hwif->sg_dma_direction); + return 0; } - *table++ = cpu_to_le32(xcount); - cur_addr += bcount; - cur_len -= bcount; + + *table++ = cpu_to_le32(0x8000); + *table++ = cpu_to_le32(cur_addr + 0x8000); + xcount = 0x8000; } + *table++ = cpu_to_le32(xcount); + cur_addr += bcount; + cur_len -= bcount; } sg++; i--; } - if (count) { - if (!is_trm290_chipset) - *--table |= cpu_to_le32(0x80000000); - return count; - } - printk("%s: empty DMA table?\n", drive->name); -use_pio_instead: - pci_unmap_sg(HWIF(drive)->pci_dev, - HWIF(drive)->sg_table, - HWIF(drive)->sg_nents, - HWIF(drive)->sg_dma_direction); - HWIF(drive)->sg_dma_active = 0; - return 0; /* revert to PIO for this request */ + if (!count) + printk("%s: empty DMA table?\n", drive->name); + else if (!is_trm290_chipset) + *--table |= cpu_to_le32(0x80000000); + + return count; } /* Teardown mappings after DMA has completed. */ @@ -378,7 +337,6 @@ int nents = HWIF(drive)->sg_nents; pci_unmap_sg(dev, sg, nents, HWIF(drive)->sg_dma_direction); - HWIF(drive)->sg_dma_active = 0; } /* @@ -532,6 +490,20 @@ } #endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ +static void ide_toggle_bounce(ide_drive_t *drive, int on) +{ + dma64_addr_t addr = BLK_BOUNCE_HIGH; + + if (on && drive->media == ide_disk && HWIF(drive)->highmem) { + if (!PCI_DMA_BUS_IS_PHYS) + addr = BLK_BOUNCE_ANY; + else + addr = HWIF(drive)->pci_dev->dma_mask; + } + + blk_queue_bounce_limit(&drive->queue, addr); +} + /* * ide_dmaproc() initiates/aborts DMA read/write operations on a drive. * @@ -550,19 +522,20 @@ */ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) { -// ide_hwgroup_t *hwgroup = HWGROUP(drive); - ide_hwif_t *hwif = HWIF(drive); - unsigned long dma_base = hwif->dma_base; - byte unit = (drive->select.b.unit & 0x01); - unsigned int count, reading = 0; + ide_hwif_t *hwif = HWIF(drive); + unsigned long dma_base = hwif->dma_base; + byte unit = (drive->select.b.unit & 0x01); + unsigned int count, reading = 0, set_high = 1; byte dma_stat; switch (func) { case ide_dma_off: printk("%s: DMA disabled\n", drive->name); + set_high = 0; case ide_dma_off_quietly: outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); case ide_dma_on: + ide_toggle_bounce(drive, set_high); drive->using_dma = (func == ide_dma_on); if (drive->using_dma) outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c --- v2.5.0/linux/drivers/ide/ide-floppy.c Thu Oct 11 09:14:32 2001 +++ linux/drivers/ide/ide-floppy.c Fri Nov 30 08:33:50 2001 @@ -707,24 +707,24 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) { struct request *rq = pc->rq; - struct buffer_head *bh = rq->bh; + struct bio *bio = rq->bio; int count; while (bcount) { - if (pc->b_count == bh->b_size) { + if (pc->b_count == bio->bi_size) { rq->sector += rq->current_nr_sectors; rq->nr_sectors -= rq->current_nr_sectors; idefloppy_end_request (1, HWGROUP(drive)); - if ((bh = rq->bh) != NULL) + if ((bio = rq->bio) != NULL) pc->b_count = 0; } - if (bh == NULL) { - printk (KERN_ERR "%s: bh == NULL in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount); + if (bio == NULL) { + printk (KERN_ERR "%s: bio == NULL in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount); idefloppy_discard_data (drive, bcount); return; } - count = IDEFLOPPY_MIN (bh->b_size - pc->b_count, bcount); - atapi_input_bytes (drive, bh->b_data + pc->b_count, count); + count = IDEFLOPPY_MIN (bio->bi_size - pc->b_count, bcount); + atapi_input_bytes (drive, bio_data(bio) + pc->b_count, count); bcount -= count; pc->b_count += count; } } @@ -732,7 +732,7 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) { struct request *rq = pc->rq; - struct buffer_head *bh = rq->bh; + struct bio *bio = rq->bio; int count; while (bcount) { @@ -740,13 +740,13 @@ rq->sector += rq->current_nr_sectors; rq->nr_sectors -= rq->current_nr_sectors; idefloppy_end_request (1, HWGROUP(drive)); - if ((bh = rq->bh) != NULL) { - pc->b_data = bh->b_data; - pc->b_count = bh->b_size; + if ((bio = rq->bio) != NULL) { + pc->b_data = bio_data(bio); + pc->b_count = bio->bi_size; } } - if (bh == NULL) { - printk (KERN_ERR "%s: bh == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount); + if (bio == NULL) { + printk (KERN_ERR "%s: bio == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount); idefloppy_write_zeros (drive, bcount); return; } @@ -760,9 +760,9 @@ static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc) { struct request *rq = pc->rq; - struct buffer_head *bh = rq->bh; + struct bio *bio = rq->bio; - while ((bh = rq->bh) != NULL) + while ((bio = rq->bio) != NULL) idefloppy_end_request (1, HWGROUP(drive)); } #endif /* CONFIG_BLK_DEV_IDEDMA */ @@ -1210,7 +1210,7 @@ pc->callback = &idefloppy_rw_callback; pc->rq = rq; pc->b_data = rq->buffer; - pc->b_count = rq->cmd == READ ? 0 : rq->bh->b_size; + pc->b_count = rq->cmd == READ ? 0 : rq->bio->bi_size; if (rq->cmd == WRITE) set_bit (PC_WRITING, &pc->flags); pc->buffer = NULL; @@ -1778,9 +1778,7 @@ */ static void idefloppy_revalidate (ide_drive_t *drive) { - grok_partitions(HWIF(drive)->gd, drive->select.b.unit, - 1<bios_sect, NULL); ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL); ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, INT_MAX, 1, 1024, &max_readahead[major][minor], NULL); - ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL); } @@ -1930,8 +1927,7 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) { struct idefloppy_id_gcw gcw; - int major = HWIF(drive)->major, i; - int minor = drive->select.b.unit << PARTN_BITS; + int i; *((unsigned short *) &gcw) = drive->id->config; drive->driver_data = floppy; @@ -1953,34 +1949,17 @@ */ if (strcmp(drive->id->model, "IOMEGA ZIP 100 ATAPI") == 0) - { - for (i = 0; i < 1 << PARTN_BITS; i++) - max_sectors[major][minor + i] = 64; - } - /* - * Guess what? The IOMEGA Clik! drive also needs the - * above fix. It makes nasty clicking noises without - * it, so please don't remove this. - */ - if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0) - { - for (i = 0; i < 1 << PARTN_BITS; i++) - max_sectors[major][minor + i] = 64; - set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags); - } + blk_queue_max_sectors(&drive->queue, 64); /* * Guess what? The IOMEGA Clik! drive also needs the * above fix. It makes nasty clicking noises without * it, so please don't remove this. */ - if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0) - { - for (i = 0; i < 1 << PARTN_BITS; i++) - max_sectors[major][minor + i] = 64; + if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0) { + blk_queue_max_sectors(&drive->queue, 64); set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags); } - (void) idefloppy_get_capacity (drive); idefloppy_add_settings(drive); diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c --- v2.5.0/linux/drivers/ide/ide-pci.c Thu Oct 25 13:53:47 2001 +++ linux/drivers/ide/ide-pci.c Fri Nov 30 15:53:51 2001 @@ -30,14 +30,14 @@ #define DEVID_MPIIX ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX}) #define DEVID_PIIX3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1}) #define DEVID_PIIX4 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB}) -#define DEVID_PIIX4E ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1}) +#define DEVID_ICH0 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1}) #define DEVID_PIIX4E2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1}) -#define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1}) +#define DEVID_ICH ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1}) #define DEVID_PIIX4U2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1}) #define DEVID_PIIX4NX ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX}) -#define DEVID_PIIX4U3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9}) -#define DEVID_PIIX4U4 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8}) -#define DEVID_PIIX4U5 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10}) +#define DEVID_ICH2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9}) +#define DEVID_ICH2M ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8}) +#define DEVID_ICH3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10}) #define DEVID_VIA_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561}) #define DEVID_MR_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1}) #define DEVID_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1}) @@ -79,6 +79,7 @@ #define DEVID_AMD7401 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401}) #define DEVID_AMD7409 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409}) #define DEVID_AMD7411 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411}) +#define DEVID_AMD7441 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7441}) #define DEVID_PDCADMA ((ide_pci_devid_t){PCI_VENDOR_ID_PDC, PCI_DEVICE_ID_PDC_1841}) #define DEVID_SLC90E66 ((ide_pci_devid_t){PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1}) #define DEVID_OSB4 ((ide_pci_devid_t){PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE}) @@ -379,14 +380,14 @@ {DEVID_MPIIX, "MPIIX", NULL, NULL, INIT_PIIX, NULL, {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX3, "PIIX3", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, - {DEVID_PIIX4E, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_ICH0, "ICH0", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4E2, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, - {DEVID_PIIX4U, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_ICH, "ICH", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4U2, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4NX, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, - {DEVID_PIIX4U3, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, - {DEVID_PIIX4U4, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, - {DEVID_PIIX4U5, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_ICH2, "ICH2", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_ICH2M, "ICH2-M", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_ICH3, "ICH3", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_MR_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, {DEVID_VP_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, @@ -437,6 +438,7 @@ {DEVID_AMD7401, "AMD7401", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_AMD7409, "AMD7409", PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, {DEVID_AMD7411, "AMD7411", PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, + {DEVID_AMD7441, "AMD7441", PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, {DEVID_PDCADMA, "PDCADMA", PCI_PDCADMA, ATA66_PDCADMA, INIT_PDCADMA, DMA_PDCADMA, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, {DEVID_SLC90E66,"SLC90E66", PCI_SLC90E66, ATA66_SLC90E66, INIT_SLC90E66, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_OSB4, "ServerWorks OSB4", PCI_SVWKS, ATA66_SVWKS, INIT_SVWKS, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, @@ -840,7 +842,7 @@ switch(class_rev) { case 4: - case 3: printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); + case 3: printk("%s: IDE controller on PCI slot %s\n", d->name, dev->slot_name); ide_setup_pci_device(dev, d); return; default: break; @@ -869,12 +871,12 @@ break; } } - printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); + printk("%s: IDE controller on PCI slot %s\n", d->name, dev->slot_name); ide_setup_pci_device(dev, d); if (!dev2) return; d2 = d; - printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn); + printk("%s: IDE controller on PCI slot %s\n", d2->name, dev2->slot_name); ide_setup_pci_device(dev2, d2); } @@ -904,10 +906,10 @@ hpt366_device_order_fixup(dev, d); else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL)) - printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n", - d->name, dev->bus->number, dev->devfn, devid.vid, devid.did); + printk("%s: unknown IDE controller on PCI slot %s, VID=%04x, DID=%04x\n", + d->name, dev->slot_name, devid.vid, devid.did); else - printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); + printk("%s: IDE controller on PCI slot %s\n", d->name, dev->slot_name); ide_setup_pci_device(dev, d); } } diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c --- v2.5.0/linux/drivers/ide/ide-probe.c Thu Oct 11 09:14:32 2001 +++ linux/drivers/ide/ide-probe.c Sun Dec 16 12:20:20 2001 @@ -594,9 +594,25 @@ static void ide_init_queue(ide_drive_t *drive) { request_queue_t *q = &drive->queue; + int max_sectors; q->queuedata = HWGROUP(drive); - blk_init_queue(q, do_ide_request); + blk_init_queue(q, do_ide_request, &ide_lock); + blk_queue_segment_boundary(q, 0xffff); + + /* IDE can do up to 128K per request, pdc4030 needs smaller limit */ +#ifdef CONFIG_BLK_DEV_PDC4030 + max_sectors = 127; +#else + max_sectors = 255; +#endif + blk_queue_max_sectors(q, max_sectors); + + /* IDE DMA can do PRD_ENTRIES number of segments. */ + blk_queue_max_hw_segments(q, PRD_ENTRIES); + + /* This is a driver limit and could be eliminated. */ + blk_queue_max_phys_segments(q, PRD_ENTRIES); } /* @@ -670,7 +686,7 @@ hwgroup->rq = NULL; hwgroup->handler = NULL; hwgroup->drive = NULL; - hwgroup->busy = 0; + hwgroup->flags = 0; init_timer(&hwgroup->timer); hwgroup->timer.function = &ide_timer_expiry; hwgroup->timer.data = (unsigned long) hwgroup; @@ -749,7 +765,7 @@ { struct gendisk *gd; unsigned int unit, units, minors; - int *bs, *max_sect, *max_ra; + int *bs, *max_ra; extern devfs_handle_t ide_devfs_handle; /* figure out maximum drive number on the interface */ @@ -762,23 +778,15 @@ gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL); gd->part = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL); bs = kmalloc (minors*sizeof(int), GFP_KERNEL); - max_sect = kmalloc (minors*sizeof(int), GFP_KERNEL); max_ra = kmalloc (minors*sizeof(int), GFP_KERNEL); memset(gd->part, 0, minors * sizeof(struct hd_struct)); /* cdroms and msdos f/s are examples of non-1024 blocksizes */ blksize_size[hwif->major] = bs; - max_sectors[hwif->major] = max_sect; max_readahead[hwif->major] = max_ra; for (unit = 0; unit < minors; ++unit) { *bs++ = BLOCK_SIZE; -#ifdef CONFIG_BLK_DEV_PDC4030 - *max_sect++ = ((hwif->chipset == ide_pdc4030) ? 127 : 255); -#else - /* IDE can do up to 128K per request. */ - *max_sect++ = 255; -#endif *max_ra++ = MAX_READAHEAD; } @@ -870,13 +878,6 @@ read_ahead[hwif->major] = 8; /* (4kB) */ hwif->present = 1; /* success */ -#if (DEBUG_SPINLOCK > 0) -{ - static int done = 0; - if (!done++) - printk("io_request_lock is %p\n", &io_request_lock); /* FIXME */ -} -#endif return hwif->present; } diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide-proc.c linux/drivers/ide/ide-proc.c --- v2.5.0/linux/drivers/ide/ide-proc.c Fri Sep 7 09:28:38 2001 +++ linux/drivers/ide/ide-proc.c Tue Nov 27 09:23:27 2001 @@ -190,7 +190,7 @@ if (hwif->mate && hwif->mate->hwgroup) mategroup = (ide_hwgroup_t *)(hwif->mate->hwgroup); cli(); /* all CPUs; ensure all writes are done together */ - while (mygroup->busy || (mategroup && mategroup->busy)) { + while (test_bit(IDE_BUSY, &mygroup->flags) || (mategroup && test_bit(IDE_BUSY, &mategroup->flags))) { sti(); /* all CPUs */ if (0 < (signed long)(jiffies - timeout)) { printk("/proc/ide/%s/config: channel(s) busy, cannot write\n", hwif->name); diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c --- v2.5.0/linux/drivers/ide/ide-tape.c Mon Aug 13 14:56:19 2001 +++ linux/drivers/ide/ide-tape.c Mon Dec 10 14:15:19 2001 @@ -5488,7 +5488,6 @@ idetape_pc_t pc; unsigned int minor=MINOR (inode->i_rdev); - lock_kernel(); tape = drive->driver_data; #if IDETAPE_DEBUG_LOG if (tape->debug_level >= 3) @@ -5519,7 +5518,6 @@ MOD_DEC_USE_COUNT; } clear_bit (IDETAPE_BUSY, &tape->flags); - unlock_kernel(); return 0; } @@ -6182,6 +6180,7 @@ }; MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver"); +MODULE_LICENSE("GPL"); static void __exit idetape_exit (void) { diff -u --recursive --new-file v2.5.0/linux/drivers/ide/ide.c linux/drivers/ide/ide.c --- v2.5.0/linux/drivers/ide/ide.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/ide/ide.c Sun Dec 16 12:21:02 2001 @@ -113,6 +113,8 @@ * Version 6.31 Debug Share INTR's and request queue streaming * Native ATA-100 support * Prep for Cascades Project + * Version 6.32 4GB highmem support for DMA, and mapping of those for + * PIO transfer (Jens Axboe) * * Some additional driver compile-time options are in ./include/linux/ide.h * @@ -121,8 +123,8 @@ * */ -#define REVISION "Revision: 6.31" -#define VERSION "Id: ide.c 6.31 2000/06/09" +#define REVISION "Revision: 6.32" +#define VERSION "Id: ide.c 6.32 2001/05/24" #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -149,6 +151,7 @@ #include #include #include +#include #include #include @@ -171,6 +174,12 @@ static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ static int initializing; /* set while initializing built-in drivers */ +/* + * protects global structures etc, we want to split this into per-hwgroup + * instead. + */ +spinlock_t ide_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED; + #ifdef CONFIG_BLK_DEV_IDEPCI static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ #endif /* CONFIG_BLK_DEV_IDEPCI */ @@ -180,7 +189,7 @@ * ide_lock is used by the Atari code to obtain access to the IDE interrupt, * which is shared between several drivers. */ -static int ide_lock; +static int ide_intr_lock; #endif /* __mc68000__ || CONFIG_APUS */ int noautodma = 0; @@ -542,18 +551,25 @@ return 1; /* drive ready: *might* be interrupting */ } -/* - * This is our end_request replacement function. - */ -void ide_end_request (byte uptodate, ide_hwgroup_t *hwgroup) +inline int __ide_end_request(ide_hwgroup_t *hwgroup, int uptodate, int nr_secs) { + ide_drive_t *drive = hwgroup->drive; struct request *rq; unsigned long flags; - ide_drive_t *drive = hwgroup->drive; + int ret = 1; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&ide_lock, flags); rq = hwgroup->rq; + BUG_ON(!(rq->flags & REQ_STARTED)); + + /* + * small hack to eliminate locking from ide_end_request to grab + * the first segment number of sectors + */ + if (!nr_secs) + nr_secs = rq->hard_cur_sectors; + /* * decide whether to reenable DMA -- 3 is a random magic for now, * if we DMA timeout more than 3 times, just stay in PIO @@ -563,13 +579,24 @@ hwgroup->hwif->dmaproc(ide_dma_on, drive); } - if (!end_that_request_first(rq, uptodate, hwgroup->drive->name)) { + if (!end_that_request_first(rq, uptodate, nr_secs)) { add_blkdev_randomness(MAJOR(rq->rq_dev)); blkdev_dequeue_request(rq); hwgroup->rq = NULL; end_that_request_last(rq); + ret = 0; } - spin_unlock_irqrestore(&io_request_lock, flags); + + spin_unlock_irqrestore(&ide_lock, flags); + return ret; +} + +/* + * This is our end_request replacement function. + */ +int ide_end_request (byte uptodate, ide_hwgroup_t *hwgroup) +{ + return __ide_end_request(hwgroup, uptodate, 0); } /* @@ -585,7 +612,7 @@ unsigned long flags; ide_hwgroup_t *hwgroup = HWGROUP(drive); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&ide_lock, flags); if (hwgroup->handler != NULL) { printk("%s: ide_set_handler: handler not null; old=%p, new=%p\n", drive->name, hwgroup->handler, handler); @@ -594,7 +621,7 @@ hwgroup->expiry = expiry; hwgroup->timer.expires = jiffies + timeout; add_timer(&hwgroup->timer); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&ide_lock, flags); } /* @@ -844,11 +871,10 @@ unsigned long flags; struct request *rq; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&ide_lock, flags); rq = HWGROUP(drive)->rq; - spin_unlock_irqrestore(&io_request_lock, flags); - if (rq->cmd == IDE_DRIVE_CMD) { + if (rq->flags & REQ_DRIVE_CMD) { byte *args = (byte *) rq->buffer; rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); if (args) { @@ -856,7 +882,7 @@ args[1] = err; args[2] = IN_BYTE(IDE_NSECTOR_REG); } - } else if (rq->cmd == IDE_DRIVE_TASK) { + } else if (rq->flags & REQ_DRIVE_TASK) { byte *args = (byte *) rq->buffer; rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); if (args) { @@ -869,11 +895,12 @@ args[6] = IN_BYTE(IDE_SELECT_REG); } } - spin_lock_irqsave(&io_request_lock, flags); + blkdev_dequeue_request(rq); HWGROUP(drive)->rq = NULL; end_that_request_last(rq); - spin_unlock_irqrestore(&io_request_lock, flags); + + spin_unlock_irqrestore(&ide_lock, flags); } /* @@ -975,7 +1002,7 @@ if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) return ide_stopped; /* retry only "normal" I/O: */ - if (rq->cmd == IDE_DRIVE_CMD || rq->cmd == IDE_DRIVE_TASK) { + if (!(rq->flags & REQ_CMD)) { rq->errors = 1; ide_end_drive_cmd(drive, stat, err); return ide_stopped; @@ -995,7 +1022,7 @@ else if (err & TRK0_ERR) /* help it find track zero */ rq->errors |= ERROR_RECAL; } - if ((stat & DRQ_STAT) && rq->cmd != WRITE) + if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ) try_to_flush_leftover_data(drive); } if (GET_STAT() & (BUSY_STAT|DRQ_STAT)) @@ -1142,7 +1169,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq) { byte *args = rq->buffer; - if (args && rq->cmd == IDE_DRIVE_TASK) { + if (args && (rq->flags & REQ_DRIVE_TASK)) { byte sel; #ifdef DEBUG printk("%s: DRIVE_TASK_CMD data=x%02x cmd=0x%02x fr=0x%02x ns=0x%02x sc=0x%02x lcyl=0x%02x hcyl=0x%02x sel=0x%02x\n", @@ -1192,17 +1219,19 @@ /* * start_request() initiates handling of a new I/O request */ -static ide_startstop_t start_request (ide_drive_t *drive) +static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) { ide_startstop_t startstop; - unsigned long block, blockend; - struct request *rq = blkdev_entry_next_request(&drive->queue.queue_head); + unsigned long block; unsigned int minor = MINOR(rq->rq_dev), unit = minor >> PARTN_BITS; ide_hwif_t *hwif = HWIF(drive); + BUG_ON(!(rq->flags & REQ_STARTED)); + #ifdef DEBUG printk("%s: start_request: current=0x%08lx\n", hwif->name, (unsigned long) rq); #endif + /* bail early if we've exceeded max_failures */ if (drive->max_failures && (drive->failures > drive->max_failures)) { goto kill_rq; @@ -1219,16 +1248,11 @@ } #endif block = rq->sector; - blockend = block + rq->nr_sectors; - if ((rq->cmd == READ || rq->cmd == WRITE) && + /* Strange disk manager remap */ + if ((rq->flags & REQ_CMD) && (drive->media == ide_disk || drive->media == ide_floppy)) { - if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK].nr_sects)) { - printk("%s%c: bad access: block=%ld, count=%ld\n", drive->name, - (minor&PARTN_MASK)?'0'+(minor&PARTN_MASK):' ', block, rq->nr_sectors); - goto kill_rq; - } - block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0; + block += drive->sect0; } /* Yecch - this will shift the entire interval, possibly killing some innocent following sector */ @@ -1240,18 +1264,20 @@ #endif SELECT_DRIVE(hwif, drive); - if (ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) { + if (ide_wait_stat(&startstop, drive, drive->ready_stat, + BUSY_STAT|DRQ_STAT, WAIT_READY)) { printk("%s: drive not ready for command\n", drive->name); return startstop; } if (!drive->special.all) { - if (rq->cmd == IDE_DRIVE_CMD || rq->cmd == IDE_DRIVE_TASK) { + if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) return execute_drive_cmd(drive, rq); - } + if (drive->driver != NULL) { return (DRIVER(drive)->do_request(drive, rq, block)); } - printk("%s: media type %d not supported\n", drive->name, drive->media); + printk("%s: media type %d not supported\n", + drive->name, drive->media); goto kill_rq; } return do_special(drive); @@ -1267,13 +1293,15 @@ { ide_hwgroup_t *hwgroup = HWGROUP(drive); unsigned long flags; + struct request *rq; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&ide_lock, flags); hwgroup->handler = NULL; del_timer(&hwgroup->timer); - spin_unlock_irqrestore(&io_request_lock, flags); + rq = hwgroup->rq; + spin_unlock_irqrestore(&ide_lock, flags); - return start_request(drive); + return start_request(drive, rq); } /* @@ -1305,7 +1333,7 @@ || (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep))) || (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive)))) { - if( !drive->queue.plugged ) + if (!blk_queue_plugged(&drive->queue)) best = drive; } } @@ -1334,7 +1362,7 @@ /* * Issue a new request to a drive from hwgroup - * Caller must have already done spin_lock_irqsave(&io_request_lock, ..); + * Caller must have already done spin_lock_irqsave(&ide_lock, ...) * * A hwgroup is a serialized group of IDE interfaces. Usually there is * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640) @@ -1346,39 +1374,34 @@ * possibly along with many other devices. This is especially common in * PCI-based systems with off-board IDE controller cards. * - * The IDE driver uses the single global io_request_lock spinlock to protect - * access to the request queues, and to protect the hwgroup->busy flag. + * The IDE driver uses the queue spinlock to protect access to the request + * queues. * * The first thread into the driver for a particular hwgroup sets the - * hwgroup->busy flag to indicate that this hwgroup is now active, + * hwgroup->flags IDE_BUSY flag to indicate that this hwgroup is now active, * and then initiates processing of the top request from the request queue. * * Other threads attempting entry notice the busy setting, and will simply - * queue their new requests and exit immediately. Note that hwgroup->busy - * remains set even when the driver is merely awaiting the next interrupt. + * queue their new requests and exit immediately. Note that hwgroup->flags + * remains busy even when the driver is merely awaiting the next interrupt. * Thus, the meaning is "this hwgroup is busy processing a request". * * When processing of a request completes, the completing thread or IRQ-handler * will start the next request from the queue. If no more work remains, - * the driver will clear the hwgroup->busy flag and exit. - * - * The io_request_lock (spinlock) is used to protect all access to the - * hwgroup->busy flag, but is otherwise not needed for most processing in - * the driver. This makes the driver much more friendlier to shared IRQs - * than previous designs, while remaining 100% (?) SMP safe and capable. + * the driver will clear the hwgroup->flags IDE_BUSY flag and exit. */ static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq) { ide_drive_t *drive; ide_hwif_t *hwif; ide_startstop_t startstop; + struct request *rq; - ide_get_lock(&ide_lock, ide_intr, hwgroup); /* for atari only: POSSIBLY BROKEN HERE(?) */ + ide_get_lock(&ide_intr_lock, ide_intr, hwgroup);/* for atari only: POSSIBLY BROKEN HERE(?) */ __cli(); /* necessary paranoia: ensure IRQs are masked on local CPU */ - while (!hwgroup->busy) { - hwgroup->busy = 1; + while (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) { drive = choose_drive(hwgroup); if (drive == NULL) { unsigned long sleep = 0; @@ -1401,13 +1424,13 @@ if (timer_pending(&hwgroup->timer)) printk("ide_set_handler: timer already active\n"); #endif - hwgroup->sleeping = 1; /* so that ide_timer_expiry knows what to do */ + set_bit(IDE_SLEEP, &hwgroup->flags); mod_timer(&hwgroup->timer, sleep); - /* we purposely leave hwgroup->busy==1 while sleeping */ + /* we purposely leave hwgroup busy while sleeping */ } else { /* Ugly, but how can we sleep for the lock otherwise? perhaps from tq_disk? */ - ide_release_lock(&ide_lock); /* for atari only */ - hwgroup->busy = 0; + ide_release_lock(&ide_intr_lock);/* for atari only */ + clear_bit(IDE_BUSY, &hwgroup->flags); } return; /* no more work for this hwgroup (for now) */ } @@ -1421,9 +1444,14 @@ drive->sleep = 0; drive->service_start = jiffies; - if ( drive->queue.plugged ) /* paranoia */ - printk("%s: Huh? nuking plugged queue\n", drive->name); - hwgroup->rq = blkdev_entry_next_request(&drive->queue.queue_head); + if (blk_queue_plugged(&drive->queue)) + BUG(); + + /* + * just continuing an interrupted request maybe + */ + rq = hwgroup->rq = elv_next_request(&drive->queue); + /* * Some systems have trouble with IDE IRQs arriving while * the driver is still setting things up. So, here we disable @@ -1434,14 +1462,14 @@ */ if (masked_irq && hwif->irq != masked_irq) disable_irq_nosync(hwif->irq); - spin_unlock(&io_request_lock); + spin_unlock(&ide_lock); ide__sti(); /* allow other IRQs while we start this request */ - startstop = start_request(drive); - spin_lock_irq(&io_request_lock); + startstop = start_request(drive, rq); + spin_lock_irq(&ide_lock); if (masked_irq && hwif->irq != masked_irq) enable_irq(hwif->irq); if (startstop == ide_stopped) - hwgroup->busy = 0; + clear_bit(IDE_BUSY, &hwgroup->flags); } } @@ -1501,9 +1529,14 @@ HWGROUP(drive)->rq = NULL; rq->errors = 0; - rq->sector = rq->bh->b_rsector; - rq->current_nr_sectors = rq->bh->b_size >> 9; - rq->buffer = rq->bh->b_data; + rq->sector = rq->bio->bi_sector; + rq->current_nr_sectors = bio_sectors(rq->bio); + + /* + * just to make sure... + */ + if (rq->bio) + rq->buffer = NULL; } /* @@ -1519,7 +1552,11 @@ unsigned long flags; unsigned long wait; - spin_lock_irqsave(&io_request_lock, flags); + /* + * a global lock protects timers etc -- shouldn't get contention + * worth mentioning + */ + spin_lock_irqsave(&ide_lock, flags); del_timer(&hwgroup->timer); if ((handler = hwgroup->handler) == NULL) { @@ -1529,10 +1566,8 @@ * or we were "sleeping" to give other devices a chance. * Either way, we don't really want to complain about anything. */ - if (hwgroup->sleeping) { - hwgroup->sleeping = 0; - hwgroup->busy = 0; - } + if (test_and_clear_bit(IDE_SLEEP, &hwgroup->flags)) + clear_bit(IDE_BUSY, &hwgroup->flags); } else { ide_drive_t *drive = hwgroup->drive; if (!drive) { @@ -1541,17 +1576,16 @@ } else { ide_hwif_t *hwif; ide_startstop_t startstop; - if (!hwgroup->busy) { - hwgroup->busy = 1; /* paranoia */ - printk("%s: ide_timer_expiry: hwgroup->busy was 0 ??\n", drive->name); - } + /* paranoia */ + if (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) + printk("%s: ide_timer_expiry: hwgroup was not busy??\n", drive->name); if ((expiry = hwgroup->expiry) != NULL) { /* continue */ if ((wait = expiry(drive)) != 0) { /* reset timer */ hwgroup->timer.expires = jiffies + wait; add_timer(&hwgroup->timer); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&ide_lock, flags); return; } } @@ -1561,7 +1595,7 @@ * the handler() function, which means we need to globally * mask the specific IRQ: */ - spin_unlock(&io_request_lock); + spin_unlock(&ide_lock); hwif = HWIF(drive); #if DISABLE_IRQ_NOSYNC disable_irq_nosync(hwif->irq); @@ -1587,13 +1621,13 @@ set_recovery_timer(hwif); drive->service_time = jiffies - drive->service_start; enable_irq(hwif->irq); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&ide_lock); if (startstop == ide_stopped) - hwgroup->busy = 0; + clear_bit(IDE_BUSY, &hwgroup->flags); } } ide_do_request(hwgroup, 0); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&ide_lock, flags); } /* @@ -1656,13 +1690,11 @@ ide_handler_t *handler; ide_startstop_t startstop; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&ide_lock, flags); hwif = hwgroup->hwif; - if (!ide_ack_intr(hwif)) { - spin_unlock_irqrestore(&io_request_lock, flags); - return; - } + if (!ide_ack_intr(hwif)) + goto out_lock; if ((handler = hwgroup->handler) == NULL || hwgroup->poll_timeout != 0) { /* @@ -1694,16 +1726,14 @@ (void) IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); #endif /* CONFIG_BLK_DEV_IDEPCI */ } - spin_unlock_irqrestore(&io_request_lock, flags); - return; + goto out_lock; } drive = hwgroup->drive; if (!drive) { /* * This should NEVER happen, and there isn't much we could do about it here. */ - spin_unlock_irqrestore(&io_request_lock, flags); - return; + goto out_lock; } if (!drive_is_ready(drive)) { /* @@ -1712,21 +1742,19 @@ * the IRQ before their status register is up to date. Hopefully we have * enough advance overhead that the latter isn't a problem. */ - spin_unlock_irqrestore(&io_request_lock, flags); - return; - } - if (!hwgroup->busy) { - hwgroup->busy = 1; /* paranoia */ - printk("%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name); + goto out_lock; } + /* paranoia */ + if (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) + printk("%s: ide_intr: hwgroup was not busy??\n", drive->name); hwgroup->handler = NULL; del_timer(&hwgroup->timer); - spin_unlock(&io_request_lock); + spin_unlock(&ide_lock); if (drive->unmask) ide__sti(); /* local CPU only */ startstop = handler(drive); /* service this interrupt, may set handler for next interrupt */ - spin_lock_irq(&io_request_lock); + spin_lock_irq(&ide_lock); /* * Note that handler() may have set things up for another @@ -1739,13 +1767,15 @@ drive->service_time = jiffies - drive->service_start; if (startstop == ide_stopped) { if (hwgroup->handler == NULL) { /* paranoia */ - hwgroup->busy = 0; + clear_bit(IDE_BUSY, &hwgroup->flags); ide_do_request(hwgroup, hwif->irq); } else { printk("%s: ide_intr: huh? expected NULL handler on exit\n", drive->name); } } - spin_unlock_irqrestore(&io_request_lock, flags); + +out_lock: + spin_unlock_irqrestore(&ide_lock, flags); } /* @@ -1755,9 +1785,6 @@ ide_drive_t *get_info_ptr (kdev_t i_rdev) { int major = MAJOR(i_rdev); -#if 0 - int minor = MINOR(i_rdev) & PARTN_MASK; -#endif unsigned int h; for (h = 0; h < MAX_HWIFS; ++h) { @@ -1766,11 +1793,7 @@ unsigned unit = DEVICE_NR(i_rdev); if (unit < MAX_DRIVES) { ide_drive_t *drive = &hwif->drives[unit]; -#if 0 - if ((drive->present) && (drive->part[minor].nr_sects)) -#else if (drive->present) -#endif return drive; } break; @@ -1785,7 +1808,7 @@ void ide_init_drive_cmd (struct request *rq) { memset(rq, 0, sizeof(*rq)); - rq->cmd = IDE_DRIVE_CMD; + rq->flags = REQ_DRIVE_CMD; } /* @@ -1818,7 +1841,8 @@ unsigned long flags; ide_hwgroup_t *hwgroup = HWGROUP(drive); unsigned int major = HWIF(drive)->major; - struct list_head *queue_head = &drive->queue.queue_head; + request_queue_t *q = &drive->queue; + struct list_head *queue_head = &q->queue_head; DECLARE_COMPLETION(wait); #ifdef CONFIG_BLK_DEV_PDC4030 @@ -1830,8 +1854,8 @@ rq->rq_dev = MKDEV(major,(drive->select.b.unit)<waiting = &wait; - spin_lock_irqsave(&io_request_lock, flags); - if (list_empty(queue_head) || action == ide_preempt) { + spin_lock_irqsave(&ide_lock, flags); + if (blk_queue_empty(&drive->queue) || action == ide_preempt) { if (action == ide_preempt) hwgroup->rq = NULL; } else { @@ -1840,9 +1864,9 @@ } else queue_head = queue_head->next; } - list_add(&rq->queue, queue_head); + q->elevator.elevator_add_req_fn(q, rq, queue_head); ide_do_request(hwgroup, 0); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&ide_lock, flags); if (action == ide_wait) { wait_for_completion(&wait); /* wait for it to be serviced */ return rq->errors ? -EIO : 0; /* return -EIO if errors */ @@ -1851,6 +1875,16 @@ } +/* Common for ide-floppy.c and ide-disk.c */ +void ide_revalidate_drive (ide_drive_t *drive) +{ + struct gendisk *g = HWIF(drive)->gd; + int minor = (drive->select.b.unit << g->minor_shift); + kdev_t dev = MKDEV(g->major, minor); + + grok_partitions(dev, current_capacity(drive)); +} + /* * This routine is called to flush all partitions and partition tables * for a changed disk, and then re-read the new partition table. @@ -1863,40 +1897,33 @@ { ide_drive_t *drive; ide_hwgroup_t *hwgroup; - unsigned int p, major, minor; - long flags; + unsigned long flags; + int res; if ((drive = get_info_ptr(i_rdev)) == NULL) return -ENODEV; - major = MAJOR(i_rdev); - minor = drive->select.b.unit << PARTN_BITS; hwgroup = HWGROUP(drive); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&ide_lock, flags); if (drive->busy || (drive->usage > 1)) { - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&ide_lock, flags); return -EBUSY; - }; + } drive->busy = 1; MOD_INC_USE_COUNT; - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&ide_lock, flags); - for (p = 0; p < (1<part[p].nr_sects > 0) { - kdev_t devp = MKDEV(major, minor+p); - invalidate_device(devp, 1); - set_blocksize(devp, 1024); - } - drive->part[p].start_sect = 0; - drive->part[p].nr_sects = 0; - }; + res = wipe_partitions(i_rdev); + if (res) + goto leave; if (DRIVER(drive)->revalidate) DRIVER(drive)->revalidate(drive); + leave: drive->busy = 0; wake_up(&drive->wqueue); MOD_DEC_USE_COUNT; - return 0; + return res; } static void revalidate_drives (void) @@ -2169,11 +2196,10 @@ */ unregister_blkdev(hwif->major, hwif->name); kfree(blksize_size[hwif->major]); - kfree(max_sectors[hwif->major]); kfree(max_readahead[hwif->major]); blk_dev[hwif->major].data = NULL; blk_dev[hwif->major].queue = NULL; - blksize_size[hwif->major] = NULL; + blk_clear(hwif->major); gd = hwif->gd; if (gd) { del_gendisk(gd); @@ -2293,6 +2319,7 @@ memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); hwif->irq = hw->irq; hwif->noprobe = 0; + hwif->chipset = hw->chipset; if (!initializing) { ide_probe_module(); @@ -2403,7 +2430,7 @@ unsigned long flags; if ((setting->rw & SETTING_READ)) { - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&ide_lock, flags); switch(setting->data_type) { case TYPE_BYTE: val = *((u8 *) setting->data); @@ -2416,7 +2443,7 @@ val = *((u32 *) setting->data); break; } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&ide_lock, flags); } return val; } @@ -2426,11 +2453,11 @@ ide_hwgroup_t *hwgroup = HWGROUP(drive); unsigned long timeout = jiffies + (3 * HZ); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&ide_lock); - while (hwgroup->busy) { + while (test_bit(IDE_BUSY, &hwgroup->flags)) { unsigned long lflags; - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&ide_lock); __save_flags(lflags); /* local CPU only */ __sti(); /* local CPU only; needed for jiffies */ if (0 < (signed long)(jiffies - timeout)) { @@ -2439,7 +2466,7 @@ return -EBUSY; } __restore_flags(lflags); /* local CPU only */ - spin_lock_irq(&io_request_lock); + spin_lock_irq(&ide_lock); } return 0; } @@ -2480,7 +2507,7 @@ *p = val; break; } - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&ide_lock); return 0; } @@ -2560,7 +2587,7 @@ struct request rq; ide_init_drive_cmd(&rq); - rq.cmd = IDE_DRIVE_TASK; + rq.flags = REQ_DRIVE_TASK; rq.buffer = buf; return ide_do_drive_cmd(drive, &rq, ide_wait); } @@ -2633,6 +2660,7 @@ { struct hd_big_geometry *loc = (struct hd_big_geometry *) arg; if (!loc || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL; + if (put_user(drive->bios_head, (byte *) &loc->heads)) return -EFAULT; if (put_user(drive->bios_sect, (byte *) &loc->sectors)) return -EFAULT; if (put_user(drive->bios_cyl, (unsigned int *) &loc->cylinders)) return -EFAULT; @@ -2653,11 +2681,6 @@ return 0; } - case BLKGETSIZE: /* Return device size */ - return put_user(drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects, (unsigned long *) arg); - case BLKGETSIZE64: - return put_user((u64)drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects << 9, (u64 *) arg); - case BLKRRPART: /* Re-read partition tables */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; return ide_revalidate_disk(inode->i_rdev); @@ -2775,6 +2798,8 @@ } return 0; + case BLKGETSIZE: + case BLKGETSIZE64: case BLKROSET: case BLKROGET: case BLKFLSBUF: @@ -2786,6 +2811,13 @@ case BLKBSZSET: return blk_ioctl(inode->i_rdev, cmd, arg); + /* + * uniform packet command handling + */ + case CDROMEJECT: + case CDROMCLOSETRAY: + return block_ioctl(inode->i_rdev, cmd, arg); + case HDIO_GET_BUSSTATE: if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -3409,7 +3441,7 @@ #ifdef CONFIG_BLK_DEV_IDE #if defined(__mc68000__) || defined(CONFIG_APUS) if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) { - ide_get_lock(&ide_lock, NULL, NULL); /* for atari only */ + ide_get_lock(&ide_intr_lock, NULL, NULL);/* for atari only */ disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */ // disable_irq_nosync(ide_hwifs[0].irq); } @@ -3420,7 +3452,7 @@ #if defined(__mc68000__) || defined(CONFIG_APUS) if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) { enable_irq(ide_hwifs[0].irq); - ide_release_lock(&ide_lock); /* for atari only */ + ide_release_lock(&ide_intr_lock);/* for atari only */ } #endif /* __mc68000__ || CONFIG_APUS */ #endif /* CONFIG_BLK_DEV_IDE */ @@ -3654,6 +3686,7 @@ */ devfs_handle_t ide_devfs_handle; +EXPORT_SYMBOL(ide_lock); EXPORT_SYMBOL(ide_probe); EXPORT_SYMBOL(drive_is_flashcard); EXPORT_SYMBOL(ide_timer_expiry); @@ -3685,6 +3718,8 @@ EXPORT_SYMBOL(ide_do_drive_cmd); EXPORT_SYMBOL(ide_end_drive_cmd); EXPORT_SYMBOL(ide_end_request); +EXPORT_SYMBOL(__ide_end_request); +EXPORT_SYMBOL(ide_revalidate_drive); EXPORT_SYMBOL(ide_revalidate_disk); EXPORT_SYMBOL(ide_cmd); EXPORT_SYMBOL(ide_wait_cmd); diff -u --recursive --new-file v2.5.0/linux/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c --- v2.5.0/linux/drivers/ide/pdc202xx.c Wed Nov 14 11:44:03 2001 +++ linux/drivers/ide/pdc202xx.c Tue Nov 27 09:23:27 2001 @@ -893,6 +893,7 @@ #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { hwif->dmaproc = &pdc202xx_dmaproc; + hwif->highmem = 1; if (!noautodma) hwif->autodma = 1; } else { diff -u --recursive --new-file v2.5.0/linux/drivers/ide/piix.c linux/drivers/ide/piix.c --- v2.5.0/linux/drivers/ide/piix.c Thu Oct 25 13:53:47 2001 +++ linux/drivers/ide/piix.c Fri Nov 30 15:53:51 2001 @@ -88,33 +88,9 @@ u8 c0 = 0, c1 = 0; u8 reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0, reg55 = 0; - switch(bmide_dev->device) { - case PCI_DEVICE_ID_INTEL_82801BA_8: - case PCI_DEVICE_ID_INTEL_82801BA_9: - case PCI_DEVICE_ID_INTEL_82801CA_10: - p += sprintf(p, "\n Intel PIIX4 Ultra 100 Chipset.\n"); - break; - case PCI_DEVICE_ID_INTEL_82372FB_1: - case PCI_DEVICE_ID_INTEL_82801AA_1: - p += sprintf(p, "\n Intel PIIX4 Ultra 66 Chipset.\n"); - break; - case PCI_DEVICE_ID_INTEL_82451NX: - case PCI_DEVICE_ID_INTEL_82801AB_1: - case PCI_DEVICE_ID_INTEL_82443MX_1: - case PCI_DEVICE_ID_INTEL_82371AB: - p += sprintf(p, "\n Intel PIIX4 Ultra 33 Chipset.\n"); - break; - case PCI_DEVICE_ID_INTEL_82371SB_1: - p += sprintf(p, "\n Intel PIIX3 Chipset.\n"); - break; - case PCI_DEVICE_ID_INTEL_82371MX: - p += sprintf(p, "\n Intel MPIIX Chipset.\n"); - return p-buffer; /* => must be less than 4k! */ - case PCI_DEVICE_ID_INTEL_82371FB_1: - case PCI_DEVICE_ID_INTEL_82371FB_0: - default: - p += sprintf(p, "\n Intel PIIX Chipset.\n"); - break; + if (bmide_dev->device == PCI_DEVICE_ID_INTEL_82371MX) { + p += sprintf(p, "\n Intel MPIIX Chipset.\n"); + return p-buffer; /* => must be less than 4k! */ } pci_read_config_word(bmide_dev, 0x40, ®40); @@ -136,6 +112,7 @@ c0 = inb_p((unsigned short)bibma + 0x02); c1 = inb_p((unsigned short)bibma + 0x0a); + p += sprintf(p, "\n %s Chipset.\n", bmide_dev->name); p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); p += sprintf(p, " %sabled %sabled\n", (c0&0x80) ? "dis" : " en", @@ -523,6 +500,7 @@ if (!hwif->dma_base) return; + hwif->highmem = 1; #ifndef CONFIG_BLK_DEV_IDEDMA hwif->autodma = 0; #else /* CONFIG_BLK_DEV_IDEDMA */ diff -u --recursive --new-file v2.5.0/linux/drivers/ide/serverworks.c linux/drivers/ide/serverworks.c --- v2.5.0/linux/drivers/ide/serverworks.c Sun Sep 9 10:43:02 2001 +++ linux/drivers/ide/serverworks.c Tue Nov 27 09:23:27 2001 @@ -593,6 +593,7 @@ if (!noautodma) hwif->autodma = 1; hwif->dmaproc = &svwks_dmaproc; + hwif->highmem = 1; } else { hwif->autodma = 0; hwif->drives[0].autotune = 1; diff -u --recursive --new-file v2.5.0/linux/drivers/ide/sis5513.c linux/drivers/ide/sis5513.c --- v2.5.0/linux/drivers/ide/sis5513.c Fri Sep 7 09:28:38 2001 +++ linux/drivers/ide/sis5513.c Tue Nov 27 09:23:27 2001 @@ -671,6 +671,7 @@ case PCI_DEVICE_ID_SI_5591: if (!noautodma) hwif->autodma = 1; + hwif->highmem = 1; hwif->dmaproc = &sis5513_dmaproc; break; #endif /* CONFIG_BLK_DEV_IDEDMA */ diff -u --recursive --new-file v2.5.0/linux/drivers/ide/slc90e66.c linux/drivers/ide/slc90e66.c --- v2.5.0/linux/drivers/ide/slc90e66.c Sun Jul 15 16:22:23 2001 +++ linux/drivers/ide/slc90e66.c Tue Nov 27 09:23:27 2001 @@ -373,6 +373,7 @@ return; hwif->autodma = 0; + hwif->highmem = 1; #ifdef CONFIG_BLK_DEV_IDEDMA if (!noautodma) hwif->autodma = 1; diff -u --recursive --new-file v2.5.0/linux/drivers/ide/via82cxxx.c linux/drivers/ide/via82cxxx.c --- v2.5.0/linux/drivers/ide/via82cxxx.c Tue Sep 11 08:40:36 2001 +++ linux/drivers/ide/via82cxxx.c Tue Nov 27 09:23:27 2001 @@ -520,6 +520,7 @@ #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { + hwif->highmem = 1; hwif->dmaproc = &via82cxxx_dmaproc; #ifdef CONFIG_IDEDMA_AUTO if (!noautodma) diff -u --recursive --new-file v2.5.0/linux/drivers/ieee1394/raw1394.c linux/drivers/ieee1394/raw1394.c --- v2.5.0/linux/drivers/ieee1394/raw1394.c Mon Oct 1 21:24:24 2001 +++ linux/drivers/ieee1394/raw1394.c Fri Nov 30 08:26:04 2001 @@ -949,7 +949,6 @@ struct pending_request *req; int done = 0, i; - lock_kernel(); for (i = 0; i < 64; i++) { if (fi->listen_channels & (1ULL << i)) { hpsb_unlisten_channel(hl_handle, fi->host, i); @@ -990,7 +989,6 @@ kfree(fi); V22_COMPAT_MOD_DEC_USE_COUNT; - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/input/evdev.c linux/drivers/input/evdev.c --- v2.5.0/linux/drivers/input/evdev.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/input/evdev.c Fri Nov 30 08:26:04 2001 @@ -94,7 +94,6 @@ struct evdev_list *list = file->private_data; struct evdev_list **listptr; - lock_kernel(); listptr = &list->evdev->list; evdev_fasync(-1, file, 0); @@ -113,7 +112,6 @@ } kfree(list); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/input/input.c linux/drivers/input/input.c --- v2.5.0/linux/drivers/input/input.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/input/input.c Fri Nov 30 08:26:04 2001 @@ -387,9 +387,7 @@ old_fops = file->f_op; file->f_op = new_fops; - lock_kernel(); err = new_fops->open(inode, file); - unlock_kernel(); if (err) { fops_put(file->f_op); diff -u --recursive --new-file v2.5.0/linux/drivers/input/joydev.c linux/drivers/input/joydev.c --- v2.5.0/linux/drivers/input/joydev.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/input/joydev.c Fri Nov 30 08:26:04 2001 @@ -164,8 +164,7 @@ { struct joydev_list *list = file->private_data; struct joydev_list **listptr; - - lock_kernel(); + listptr = &list->joydev->list; joydev_fasync(-1, file, 0); @@ -184,7 +183,6 @@ } kfree(list); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/input/mousedev.c linux/drivers/input/mousedev.c --- v2.5.0/linux/drivers/input/mousedev.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/input/mousedev.c Fri Nov 30 08:26:04 2001 @@ -169,8 +169,7 @@ { struct mousedev_list *list = file->private_data; struct mousedev_list **listptr; - - lock_kernel(); + listptr = &list->mousedev->list; mousedev_fasync(-1, file, 0); @@ -208,7 +207,6 @@ } kfree(list); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/Config.in linux/drivers/isdn/Config.in --- v2.5.0/linux/drivers/isdn/Config.in Sun Sep 9 10:45:43 2001 +++ linux/drivers/isdn/Config.in Fri Nov 30 09:48:32 2001 @@ -81,6 +81,7 @@ dep_tristate 'Sedlbauer PCMCIA cards' CONFIG_HISAX_SEDLBAUER_CS $CONFIG_PCMCIA dep_tristate 'ELSA PCMCIA MicroLink cards' CONFIG_HISAX_ELSA_CS $CONFIG_PCMCIA dep_tristate 'ST5481 USB ISDN modem (EXPERIMENTAL)' CONFIG_HISAX_ST5481 $CONFIG_HISAX $CONFIG_USB $CONFIG_EXPERIMENTAL + dep_tristate 'Fritz!PCIv2 support (EXPERIMENTAL)' CONFIG_HISAX_FRITZ_PCIPNP $CONFIG_HISAX $CONFIG_EXPERIMENTAL fi endmenu diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c --- v2.5.0/linux/drivers/isdn/avmb1/capi.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/isdn/avmb1/capi.c Thu Dec 6 14:01:17 2001 @@ -87,10 +87,10 @@ struct capincci *nccip; unsigned int minor; - __u16 applid; - __u32 ncci; - __u16 datahandle; - __u16 msgid; + u16 applid; + u32 ncci; + u16 datahandle; + u16 msgid; struct file *file; struct tty_struct *tty; @@ -112,7 +112,7 @@ /* transmit path */ struct datahandle_queue { struct datahandle_queue *next; - __u16 datahandle; + u16 datahandle; } *ackqueue; int nack; @@ -121,7 +121,7 @@ struct capincci { struct capincci *next; - __u32 ncci; + u32 ncci; struct capidev *cdev; #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE struct capiminor *minorp; @@ -131,8 +131,8 @@ struct capidev { struct capidev *next; struct file *file; - __u16 applid; - __u16 errcode; + u16 applid; + u16 errcode; unsigned int minor; unsigned userflags; @@ -166,7 +166,7 @@ #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE /* -------- datahandles --------------------------------------------- */ -int capincci_add_ack(struct capiminor *mp, __u16 datahandle) +static int capincci_add_ack(struct capiminor *mp, u16 datahandle) { struct datahandle_queue *n, **pp; @@ -184,7 +184,7 @@ return 0; } -int capiminor_del_ack(struct capiminor *mp, __u16 datahandle) +static int capiminor_del_ack(struct capiminor *mp, u16 datahandle) { struct datahandle_queue **pp, *p; @@ -200,7 +200,7 @@ return -1; } -void capiminor_del_all_ack(struct capiminor *mp) +static void capiminor_del_all_ack(struct capiminor *mp) { struct datahandle_queue **pp, *p; @@ -216,7 +216,7 @@ /* -------- struct capiminor ---------------------------------------- */ -struct capiminor *capiminor_alloc(__u16 applid, __u32 ncci) +static struct capiminor *capiminor_alloc(u16 applid, u32 ncci) { struct capiminor *mp, **pp; unsigned int minor = 0; @@ -257,7 +257,7 @@ return mp; } -void capiminor_free(struct capiminor *mp) +static void capiminor_free(struct capiminor *mp) { struct capiminor **pp; @@ -283,7 +283,7 @@ } } -struct capiminor *capiminor_find(unsigned int minor) +static struct capiminor *capiminor_find(unsigned int minor) { struct capiminor *p; for (p = minors; p && p->minor != minor; p = p->next) @@ -294,7 +294,7 @@ /* -------- struct capincci ----------------------------------------- */ -static struct capincci *capincci_alloc(struct capidev *cdev, __u32 ncci) +static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci) { struct capincci *np, **pp; #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE @@ -331,7 +331,7 @@ return np; } -static void capincci_free(struct capidev *cdev, __u32 ncci) +static void capincci_free(struct capidev *cdev, u32 ncci) { struct capincci *np, **pp; #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE @@ -375,7 +375,7 @@ } } -struct capincci *capincci_find(struct capidev *cdev, __u32 ncci) +static struct capincci *capincci_find(struct capidev *cdev, u32 ncci) { struct capincci *p; @@ -426,7 +426,7 @@ kmem_cache_free(capidev_cachep, cdev); } -static struct capidev *capidev_find(__u16 applid) +static struct capidev *capidev_find(u16 applid) { struct capidev *p; for (p=capidev_openlist; p; p = p->next) { @@ -439,13 +439,13 @@ #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE /* -------- handle data queue --------------------------------------- */ -struct sk_buff * +static struct sk_buff * gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb) { struct sk_buff *nskb; nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_ATOMIC); if (nskb) { - __u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2); + u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2); unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN); capimsg_setu16(s, 0, CAPI_DATA_B3_RESP_LEN); capimsg_setu16(s, 2, mp->applid); @@ -458,11 +458,11 @@ return nskb; } -int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb) +static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb) { struct sk_buff *nskb; unsigned int datalen; - __u16 errcode, datahandle; + u16 errcode, datahandle; datalen = skb->len - CAPIMSG_LEN(skb->data); if (mp->tty) { @@ -538,7 +538,7 @@ return -1; } -void handle_minor_recv(struct capiminor *mp) +static void handle_minor_recv(struct capiminor *mp) { struct sk_buff *skb; while ((skb = skb_dequeue(&mp->inqueue)) != 0) { @@ -552,13 +552,13 @@ } } -int handle_minor_send(struct capiminor *mp) +static int handle_minor_send(struct capiminor *mp) { struct sk_buff *skb; - __u16 len; + u16 len; int count = 0; - __u16 errcode; - __u16 datahandle; + u16 errcode; + u16 datahandle; if (mp->tty && mp->ttyoutstop) { #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) @@ -569,7 +569,7 @@ while ((skb = skb_dequeue(&mp->outqueue)) != 0) { datahandle = mp->datahandle; - len = (__u16)skb->len; + len = (u16)skb->len; skb_push(skb, CAPI_DATA_B3_REQ_LEN); memset(skb->data, 0, CAPI_DATA_B3_REQ_LEN); capimsg_setu16(skb->data, 0, CAPI_DATA_B3_REQ_LEN); @@ -578,7 +578,7 @@ capimsg_setu8 (skb->data, 5, CAPI_REQ); capimsg_setu16(skb->data, 6, mp->msgid++); capimsg_setu32(skb->data, 8, mp->ncci); /* NCCI */ - capimsg_setu32(skb->data, 12, (__u32) skb->data); /* Data32 */ + capimsg_setu32(skb->data, 12, (u32) skb->data); /* Data32 */ capimsg_setu16(skb->data, 16, len); /* Data length */ capimsg_setu16(skb->data, 18, datahandle); capimsg_setu16(skb->data, 20, 0); /* Flags */ @@ -620,16 +620,16 @@ #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ /* -------- function called by lower level -------------------------- */ -static void capi_signal(__u16 applid, void *param) +static void capi_signal(u16 applid, void *param) { struct capidev *cdev = (struct capidev *)param; #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE struct capiminor *mp; - __u16 datahandle; + u16 datahandle; #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ struct capincci *np; struct sk_buff *skb = 0; - __u32 ncci; + u32 ncci; (void) (*capifuncs->capi_get_message) (applid, &skb); if (!skb) { @@ -758,7 +758,7 @@ struct capidev *cdev = (struct capidev *)file->private_data; struct sk_buff *skb; int retval; - __u16 mlen; + u16 mlen; if (ppos != &file->f_pos) return -ESPIPE; @@ -998,7 +998,7 @@ sizeof(ncci)); if (retval) return -EFAULT; - nccip = capincci_find(cdev, (__u32) ncci); + nccip = capincci_find(cdev, (u32) ncci); if (!nccip) return 0; #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE @@ -1023,7 +1023,7 @@ sizeof(ncci)); if (retval) return -EFAULT; - nccip = capincci_find(cdev, (__u32) ncci); + nccip = capincci_find(cdev, (u32) ncci); if (!nccip || (mp = nccip->minorp) == 0) return -ESRCH; return mp->minor; @@ -1055,7 +1055,6 @@ { struct capidev *cdev = (struct capidev *)file->private_data; - lock_kernel(); capincci_free(cdev, 0xffffffff); capidev_free(cdev); file->private_data = NULL; @@ -1064,7 +1063,6 @@ #ifdef _DEBUG_REFCOUNT printk(KERN_DEBUG "capi_release %d\n", GET_USE_COUNT(THIS_MODULE)); #endif - unlock_kernel(); return 0; } @@ -1243,13 +1241,11 @@ struct capiminor *mp = (struct capiminor *)file->private_data; if (mp) { - lock_kernel(); mp->file = 0; if (mp->nccip == 0) { capiminor_free(mp); file->private_data = NULL; } - unlock_kernel(); } #ifdef _DEBUG_REFCOUNT @@ -1272,7 +1268,7 @@ /* -------- tty_operations for capincci ----------------------------- */ -int capinc_tty_open(struct tty_struct * tty, struct file * file) +static int capinc_tty_open(struct tty_struct * tty, struct file * file) { struct capiminor *mp; @@ -1300,7 +1296,7 @@ return 0; } -void capinc_tty_close(struct tty_struct * tty, struct file * file) +static void capinc_tty_close(struct tty_struct * tty, struct file * file) { struct capiminor *mp; @@ -1325,8 +1321,8 @@ #endif } -int capinc_tty_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) +static int capinc_tty_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) { struct capiminor *mp = (struct capiminor *)tty->driver_data; struct sk_buff *skb; @@ -1377,7 +1373,7 @@ return count; } -void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch) +static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch) { struct capiminor *mp = (struct capiminor *)tty->driver_data; struct sk_buff *skb; @@ -1414,7 +1410,7 @@ } } -void capinc_tty_flush_chars(struct tty_struct *tty) +static void capinc_tty_flush_chars(struct tty_struct *tty) { struct capiminor *mp = (struct capiminor *)tty->driver_data; struct sk_buff *skb; @@ -1440,7 +1436,7 @@ (void)handle_minor_recv(mp); } -int capinc_tty_write_room(struct tty_struct *tty) +static int capinc_tty_write_room(struct tty_struct *tty) { struct capiminor *mp = (struct capiminor *)tty->driver_data; int room; @@ -1458,7 +1454,7 @@ return room; } -int capinc_tty_chars_in_buffer(struct tty_struct *tty) +static int capinc_tty_chars_in_buffer(struct tty_struct *tty) { struct capiminor *mp = (struct capiminor *)tty->driver_data; if (!mp || !mp->nccip) { @@ -1476,7 +1472,7 @@ return mp->outbytes; } -int capinc_tty_ioctl(struct tty_struct *tty, struct file * file, +static int capinc_tty_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { int error = 0; @@ -1488,14 +1484,14 @@ return error; } -void capinc_tty_set_termios(struct tty_struct *tty, struct termios * old) +static void capinc_tty_set_termios(struct tty_struct *tty, struct termios * old) { #ifdef _DEBUG_TTYFUNCS printk(KERN_DEBUG "capinc_tty_set_termios\n"); #endif } -void capinc_tty_throttle(struct tty_struct * tty) +static void capinc_tty_throttle(struct tty_struct * tty) { struct capiminor *mp = (struct capiminor *)tty->driver_data; #ifdef _DEBUG_TTYFUNCS @@ -1505,7 +1501,7 @@ mp->ttyinstop = 1; } -void capinc_tty_unthrottle(struct tty_struct * tty) +static void capinc_tty_unthrottle(struct tty_struct * tty) { struct capiminor *mp = (struct capiminor *)tty->driver_data; #ifdef _DEBUG_TTYFUNCS @@ -1517,7 +1513,7 @@ } } -void capinc_tty_stop(struct tty_struct *tty) +static void capinc_tty_stop(struct tty_struct *tty) { struct capiminor *mp = (struct capiminor *)tty->driver_data; #ifdef _DEBUG_TTYFUNCS @@ -1528,7 +1524,7 @@ } } -void capinc_tty_start(struct tty_struct *tty) +static void capinc_tty_start(struct tty_struct *tty) { struct capiminor *mp = (struct capiminor *)tty->driver_data; #ifdef _DEBUG_TTYFUNCS @@ -1540,49 +1536,43 @@ } } -void capinc_tty_hangup(struct tty_struct *tty) +static void capinc_tty_hangup(struct tty_struct *tty) { #ifdef _DEBUG_TTYFUNCS printk(KERN_DEBUG "capinc_tty_hangup\n"); #endif } -void capinc_tty_break_ctl(struct tty_struct *tty, int state) +static void capinc_tty_break_ctl(struct tty_struct *tty, int state) { #ifdef _DEBUG_TTYFUNCS printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state); #endif } -void capinc_tty_flush_buffer(struct tty_struct *tty) +static void capinc_tty_flush_buffer(struct tty_struct *tty) { #ifdef _DEBUG_TTYFUNCS printk(KERN_DEBUG "capinc_tty_flush_buffer\n"); #endif } -void capinc_tty_set_ldisc(struct tty_struct *tty) +static void capinc_tty_set_ldisc(struct tty_struct *tty) { #ifdef _DEBUG_TTYFUNCS printk(KERN_DEBUG "capinc_tty_set_ldisc\n"); #endif } -void capinc_tty_send_xchar(struct tty_struct *tty, char ch) +static void capinc_tty_send_xchar(struct tty_struct *tty, char ch) { #ifdef _DEBUG_TTYFUNCS printk(KERN_DEBUG "capinc_tty_send_xchar(%d)\n", ch); #endif } -int capinc_tty_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - return 0; -} - -int capinc_write_proc(struct file *file, const char *buffer, - unsigned long count, void *data) +static int capinc_tty_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { return 0; } @@ -1594,7 +1584,7 @@ static struct termios *capinc_tty_termios[CAPINC_NR_PORTS]; static struct termios *capinc_tty_termios_locked[CAPINC_NR_PORTS]; -int capinc_tty_init(void) +static int capinc_tty_init(void) { struct tty_driver *drv = &capinc_tty_driver; @@ -1652,7 +1642,7 @@ return 0; } -void capinc_tty_exit(void) +static void capinc_tty_exit(void) { struct tty_driver *drv = &capinc_tty_driver; int retval; @@ -1844,7 +1834,7 @@ return 0; } -static void lower_callback(unsigned int cmd, __u32 contr, void *data) +static void lower_callback(unsigned int cmd, u32 contr, void *data) { struct capi_ncciinfo *np; struct capidev *cdev; diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c --- v2.5.0/linux/drivers/isdn/divert/divert_procfs.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/isdn/divert/divert_procfs.c Thu Dec 6 14:01:17 2001 @@ -29,6 +29,7 @@ ulong if_used = 0; /* number of interface users */ static struct divert_info *divert_info_head = NULL; /* head of queue */ static struct divert_info *divert_info_tail = NULL; /* pointer to last entry */ +static spinlock_t divert_info_lock = SPIN_LOCK_UNLOCKED;/* lock for queue */ static wait_queue_head_t rd_queue; /*********************************/ @@ -50,15 +51,13 @@ return; /* no memory */ strcpy(ib->info_start, cp); /* set output string */ ib->next = NULL; - save_flags(flags); - cli(); + spin_lock_irqsave( &divert_info_lock, flags ); ib->usage_cnt = if_used; if (!divert_info_head) divert_info_head = ib; /* new head */ else divert_info_tail->next = ib; /* follows existing messages */ divert_info_tail = ib; /* new tail */ - restore_flags(flags); /* delete old entrys */ while (divert_info_head->next) { @@ -70,6 +69,7 @@ } else break; } /* divert_info_head->next */ + spin_unlock_irqrestore( &divert_info_lock, flags ); wake_up_interruptible(&(rd_queue)); } /* put_info_buffer */ @@ -135,17 +135,14 @@ { unsigned long flags; - lock_kernel(); - save_flags(flags); - cli(); - if_used++; + spin_lock_irqsave( &divert_info_lock, flags ); + if_used++; if (divert_info_head) (struct divert_info **) filep->private_data = &(divert_info_tail->next); else (struct divert_info **) filep->private_data = &divert_info_head; - restore_flags(flags); + spin_unlock_irqrestore( &divert_info_lock, flags ); /* start_divert(); */ - unlock_kernel(); return (0); } /* isdn_divert_open */ @@ -158,23 +155,20 @@ struct divert_info *inf; unsigned long flags; - lock_kernel(); - save_flags(flags); - cli(); + spin_lock_irqsave( &divert_info_lock, flags ); if_used--; inf = *((struct divert_info **) filep->private_data); while (inf) { inf->usage_cnt--; inf = inf->next; } - restore_flags(flags); if (if_used <= 0) while (divert_info_head) { inf = divert_info_head; divert_info_head = divert_info_head->next; kfree(inf); } - unlock_kernel(); + spin_unlock_irqrestore( &divert_info_lock, flags ); return (0); } /* isdn_divert_close */ @@ -267,6 +261,7 @@ #ifdef CONFIG_PROC_FS static struct file_operations isdn_fops = { + owner: THIS_MODULE, llseek: no_llseek, read: isdn_divert_read, write: isdn_divert_write, diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/eicon/common.c linux/drivers/isdn/eicon/common.c --- v2.5.0/linux/drivers/isdn/eicon/common.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/isdn/eicon/common.c Thu Dec 6 14:01:17 2001 @@ -808,7 +808,9 @@ while(i--) { - DivaDoCardDpc(card++); + if (card->state == DIA_RUNNING) + DivaDoCardDpc(card); + card++; } } diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/eicon/eicon_mod.c linux/drivers/isdn/eicon/eicon_mod.c --- v2.5.0/linux/drivers/isdn/eicon/eicon_mod.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/isdn/eicon/eicon_mod.c Thu Dec 6 14:01:17 2001 @@ -1550,7 +1550,7 @@ }; }; /* all adapter flavors checked without match, finito with: */ - return ENODEV; + return -ENODEV; }; @@ -1597,14 +1597,14 @@ membase = cards_membase; } else { if (membase != cards_membase) - return ENODEV; + return -ENODEV; }; cards_irq=irq_array[((adf_pos0 & 0xC)>>2)]; if (irq == -1) { irq = cards_irq; } else { if (irq != cards_irq) - return ENODEV; + return -ENODEV; }; cards_io= 0xC00 + ((adf_pos0>>4)*0x10); type = EICON_CTYPE_ISAPRI; @@ -1616,14 +1616,14 @@ membase = cards_membase; } else { if (membase != cards_membase) - return ENODEV; + return -ENODEV; }; cards_irq=irq_array[((adf_pos0 & 0xC)>>2)]; if (irq == -1) { irq = cards_irq; } else { if (irq != cards_irq) - return ENODEV; + return -ENODEV; }; cards_io= 0xC00 + ((adf_pos0>>4)*0x10); @@ -1637,12 +1637,12 @@ irq = cards_irq; } else { if (irq != cards_irq) - return ENODEV; + return -ENODEV; }; type = 0; break; default: - return ENODEV; + return -ENODEV; }; /* matching membase & irq */ if ( 1 == eicon_addcard(type, membase, irq, id, 0)) { @@ -1661,7 +1661,7 @@ cards->mca_slot+1); return 0 ; /* eicon_addcard added a card */ } else { - return ENODEV; + return -ENODEV; }; }; #endif /* CONFIG_MCA */ diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/hisax/Makefile linux/drivers/isdn/hisax/Makefile --- v2.5.0/linux/drivers/isdn/hisax/Makefile Sun Sep 9 10:45:43 2001 +++ linux/drivers/isdn/hisax/Makefile Fri Nov 30 09:48:32 2001 @@ -6,7 +6,7 @@ # Objects that export symbols. -export-objs := config.o fsm.o +export-objs := config.o fsm.o hisax_isac.o # Multipart objects. @@ -58,6 +58,7 @@ obj-$(CONFIG_HISAX_SEDLBAUER_CS) += sedlbauer_cs.o obj-$(CONFIG_HISAX_ELSA_CS) += elsa_cs.o obj-$(CONFIG_HISAX_ST5481) += hisax_st5481.o +obj-$(CONFIG_HISAX_FRITZ_PCIPNP) += hisax_isac.o hisax_fcpcipnp.o CERT := $(shell md5sum -c md5sums.asc >> /dev/null;echo $$?) CFLAGS_cert.o := -DCERTIFICATION=$(CERT) diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c --- v2.5.0/linux/drivers/isdn/hisax/config.c Sun Sep 30 12:26:05 2001 +++ linux/drivers/isdn/hisax/config.c Fri Nov 30 09:48:32 2001 @@ -1505,15 +1505,9 @@ nrcards, (nrcards > 1) ? "s" : ""); /* Install only, if at least one card found */ - if (!HiSax_inithardware(NULL)) { - retval = -EIO; - goto out_isdnl1; - } - + HiSax_inithardware(NULL); return 0; - out_isdnl1: - Isdnl1Free(); out_tei: TeiFree(); out_isdnl2: diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/hisax/hisax_fcpcipnp.c linux/drivers/isdn/hisax/hisax_fcpcipnp.c --- v2.5.0/linux/drivers/isdn/hisax/hisax_fcpcipnp.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/hisax_fcpcipnp.c Thu Dec 6 14:01:17 2001 @@ -0,0 +1,1001 @@ +/* + * Driver for AVM Fritz!PCI, Fritz!PCI v2, Fritz!PnP ISDN cards + * + * Author Kai Germaschewski + * Copyright 2001 by Kai Germaschewski + * 2001 by Karsten Keil + * + * based upon Karsten Keil's original avm_pci.c driver + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * Thanks to Wizard Computersysteme GmbH, Bremervoerde and + * SoHaNet Technology GmbH, Berlin + * for supporting the development of this driver + */ + + +/* TODO: + * + * o POWER PC + * o clean up debugging + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hisax_fcpcipnp.h" + +// debugging cruft +#define __debug_variable debug +#include "hisax_debug.h" + +#ifdef CONFIG_HISAX_DEBUG +static int debug = 0; +MODULE_PARM(debug, "i"); +#endif + +MODULE_AUTHOR("Kai Germaschewski /Karsten Keil "); +MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver"); + +static struct pci_device_id fcpci_ids[] __devinitdata = { + { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1 , PCI_ANY_ID, PCI_ANY_ID, + 0, 0, (unsigned long) "Fritz!Card PCI" }, + { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID, + 0, 0, (unsigned long) "Fritz!Card PCI v2" }, + { } +}; +MODULE_DEVICE_TABLE(pci, fcpci_ids); + +static struct isapnp_device_id fcpnp_ids[] __devinitdata = { + { ISAPNP_VENDOR('A', 'V', 'M'), ISAPNP_FUNCTION(0x0900), + ISAPNP_VENDOR('A', 'V', 'M'), ISAPNP_FUNCTION(0x0900), + (unsigned long) "Fritz!Card PnP" }, + { } +}; +MODULE_DEVICE_TABLE(isapnp, fcpnp_ids); + +static int protocol = 2; /* EURO-ISDN Default */ +MODULE_PARM(protocol, "i"); + +// ---------------------------------------------------------------------- + +#define AVM_INDEX 0x04 +#define AVM_DATA 0x10 + +#define AVM_IDX_HDLC_1 0x00 +#define AVM_IDX_HDLC_2 0x01 +#define AVM_IDX_ISAC_FIFO 0x02 +#define AVM_IDX_ISAC_REG_LOW 0x04 +#define AVM_IDX_ISAC_REG_HIGH 0x06 + +#define AVM_STATUS0 0x02 + +#define AVM_STATUS0_IRQ_ISAC 0x01 +#define AVM_STATUS0_IRQ_HDLC 0x02 +#define AVM_STATUS0_IRQ_TIMER 0x04 +#define AVM_STATUS0_IRQ_MASK 0x07 + +#define AVM_STATUS0_RESET 0x01 +#define AVM_STATUS0_DIS_TIMER 0x02 +#define AVM_STATUS0_RES_TIMER 0x04 +#define AVM_STATUS0_ENA_IRQ 0x08 +#define AVM_STATUS0_TESTBIT 0x10 + +#define AVM_STATUS1 0x03 +#define AVM_STATUS1_ENA_IOM 0x80 + +#define HDLC_FIFO 0x0 +#define HDLC_STATUS 0x4 +#define HDLC_CTRL 0x4 + +#define HDLC_MODE_ITF_FLG 0x01 +#define HDLC_MODE_TRANS 0x02 +#define HDLC_MODE_CCR_7 0x04 +#define HDLC_MODE_CCR_16 0x08 +#define HDLC_MODE_TESTLOOP 0x80 + +#define HDLC_INT_XPR 0x80 +#define HDLC_INT_XDU 0x40 +#define HDLC_INT_RPR 0x20 +#define HDLC_INT_MASK 0xE0 + +#define HDLC_STAT_RME 0x01 +#define HDLC_STAT_RDO 0x10 +#define HDLC_STAT_CRCVFRRAB 0x0E +#define HDLC_STAT_CRCVFR 0x06 +#define HDLC_STAT_RML_MASK 0x3f00 + +#define HDLC_CMD_XRS 0x80 +#define HDLC_CMD_XME 0x01 +#define HDLC_CMD_RRS 0x20 +#define HDLC_CMD_XML_MASK 0x3f00 + +#define AVM_HDLC_FIFO_1 0x10 +#define AVM_HDLC_FIFO_2 0x18 + +#define AVM_HDLC_STATUS_1 0x14 +#define AVM_HDLC_STATUS_2 0x1c + +#define AVM_ISACSX_INDEX 0x04 +#define AVM_ISACSX_DATA 0x08 + +// ---------------------------------------------------------------------- +// Fritz!PCI + +static unsigned char fcpci_read_isac(struct isac *isac, unsigned char offset) +{ + struct fritz_adapter *adapter = isac->priv; + unsigned char idx = (offset > 0x2f) ? + AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW; + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&adapter->hw_lock, flags); + outb(idx, adapter->io + AVM_INDEX); + val = inb(adapter->io + AVM_DATA + (offset & 0xf)); + spin_unlock_irqrestore(&adapter->hw_lock, flags); + DBG(0x1000, " port %#x, value %#x", + offset, val); + return val; +} + +static void fcpci_write_isac(struct isac *isac, unsigned char offset, + unsigned char value) +{ + struct fritz_adapter *adapter = isac->priv; + unsigned char idx = (offset > 0x2f) ? + AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW; + unsigned long flags; + + DBG(0x1000, " port %#x, value %#x", + offset, value); + spin_lock_irqsave(&adapter->hw_lock, flags); + outb(idx, adapter->io + AVM_INDEX); + outb(value, adapter->io + AVM_DATA + (offset & 0xf)); + spin_unlock_irqrestore(&adapter->hw_lock, flags); +} + +static void fcpci_read_isac_fifo(struct isac *isac, unsigned char * data, + int size) +{ + struct fritz_adapter *adapter = isac->priv; + unsigned long flags; + + spin_lock_irqsave(&adapter->hw_lock, flags); + outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX); + insb(adapter->io + AVM_DATA, data, size); + spin_unlock_irqrestore(&adapter->hw_lock, flags); +} + +static void fcpci_write_isac_fifo(struct isac *isac, unsigned char * data, + int size) +{ + struct fritz_adapter *adapter = isac->priv; + unsigned long flags; + + spin_lock_irqsave(&adapter->hw_lock, flags); + outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX); + outsb(adapter->io + AVM_DATA, data, size); + spin_unlock_irqrestore(&adapter->hw_lock, flags); +} + +static u32 fcpci_read_hdlc_status(struct fritz_adapter *adapter, int nr) +{ + u32 val; + int idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1; + unsigned long flags; + + spin_lock_irqsave(&adapter->hw_lock, flags); + outl(idx, adapter->io + AVM_INDEX); + val = inl(adapter->io + AVM_DATA + HDLC_STATUS); + spin_unlock_irqrestore(&adapter->hw_lock, flags); + return val; +} + +static void __fcpci_write_ctrl(struct fritz_bcs *bcs, int which) +{ + struct fritz_adapter *adapter = bcs->adapter; + int idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1; + + DBG(0x40, "hdlc %c wr%x ctrl %x", + 'A' + bcs->channel, which, bcs->ctrl.ctrl); + + outl(idx, adapter->io + AVM_INDEX); + outl(bcs->ctrl.ctrl, adapter->io + AVM_DATA + HDLC_CTRL); +} + +static void fcpci_write_ctrl(struct fritz_bcs *bcs, int which) +{ + struct fritz_adapter *adapter = bcs->adapter; + unsigned long flags; + + spin_lock_irqsave(&adapter->hw_lock, flags); + __fcpci_write_ctrl(bcs, which); + spin_unlock_irqrestore(&adapter->hw_lock, flags); +} + +// ---------------------------------------------------------------------- +// Fritz!PCI v2 + +static unsigned char fcpci2_read_isac(struct isac *isac, unsigned char offset) +{ + struct fritz_adapter *adapter = isac->priv; + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&adapter->hw_lock, flags); + outl(offset, adapter->io + AVM_ISACSX_INDEX); + val = inl(adapter->io + AVM_ISACSX_DATA); + spin_unlock_irqrestore(&adapter->hw_lock, flags); + DBG(0x1000, " port %#x, value %#x", + offset, val); + + return val; +} + +static void fcpci2_write_isac(struct isac *isac, unsigned char offset, + unsigned char value) +{ + struct fritz_adapter *adapter = isac->priv; + unsigned long flags; + + DBG(0x1000, " port %#x, value %#x", + offset, value); + spin_lock_irqsave(&adapter->hw_lock, flags); + outl(offset, adapter->io + AVM_ISACSX_INDEX); + outl(value, adapter->io + AVM_ISACSX_DATA); + spin_unlock_irqrestore(&adapter->hw_lock, flags); +} + +static void fcpci2_read_isac_fifo(struct isac *isac, unsigned char * data, + int size) +{ + struct fritz_adapter *adapter = isac->priv; + int i; + unsigned long flags; + + spin_lock_irqsave(&adapter->hw_lock, flags); + outl(0, adapter->io + AVM_ISACSX_INDEX); + for (i = 0; i < size; i++) + data[i] = inl(adapter->io + AVM_ISACSX_DATA); + spin_unlock_irqrestore(&adapter->hw_lock, flags); +} + +static void fcpci2_write_isac_fifo(struct isac *isac, unsigned char * data, + int size) +{ + struct fritz_adapter *adapter = isac->priv; + int i; + unsigned long flags; + + spin_lock_irqsave(&adapter->hw_lock, flags); + outl(0, adapter->io + AVM_ISACSX_INDEX); + for (i = 0; i < size; i++) + outl(data[i], adapter->io + AVM_ISACSX_DATA); + spin_unlock_irqrestore(&adapter->hw_lock, flags); +} + +static u32 fcpci2_read_hdlc_status(struct fritz_adapter *adapter, int nr) +{ + int offset = nr ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1; + + return inl(adapter->io + offset); +} + +static void fcpci2_write_ctrl(struct fritz_bcs *bcs, int which) +{ + struct fritz_adapter *adapter = bcs->adapter; + int offset = bcs->channel ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1; + + DBG(0x40, "hdlc %c wr%x ctrl %x", + 'A' + bcs->channel, which, bcs->ctrl.ctrl); + + outl(bcs->ctrl.ctrl, adapter->io + offset); +} + +// ---------------------------------------------------------------------- +// Fritz!PnP (ISAC access as for Fritz!PCI) + +static u32 fcpnp_read_hdlc_status(struct fritz_adapter *adapter, int nr) +{ + unsigned char idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1; + u32 val; + unsigned long flags; + + spin_lock_irqsave(&adapter->hw_lock, flags); + outb(idx, adapter->io + AVM_INDEX); + val = inb(adapter->io + AVM_DATA + HDLC_STATUS); + if (val & HDLC_INT_RPR) + val |= inb(adapter->io + AVM_DATA + HDLC_STATUS + 1) << 8; + spin_unlock_irqrestore(&adapter->hw_lock, flags); + return val; +} + +static void __fcpnp_write_ctrl(struct fritz_bcs *bcs, int which) +{ + struct fritz_adapter *adapter = bcs->adapter; + unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1; + + DBG(0x40, "hdlc %c wr%x ctrl %x", + 'A' + bcs->channel, which, bcs->ctrl.ctrl); + + outb(idx, adapter->io + AVM_INDEX); + if (which & 4) + outb(bcs->ctrl.sr.mode, + adapter->io + AVM_DATA + HDLC_STATUS + 2); + if (which & 2) + outb(bcs->ctrl.sr.xml, + adapter->io + AVM_DATA + HDLC_STATUS + 1); + if (which & 1) + outb(bcs->ctrl.sr.cmd, + adapter->io + AVM_DATA + HDLC_STATUS + 0); +} + +static void fcpnp_write_ctrl(struct fritz_bcs *bcs, int which) +{ + struct fritz_adapter *adapter = bcs->adapter; + unsigned long flags; + + spin_lock_irqsave(&adapter->hw_lock, flags); + __fcpnp_write_ctrl(bcs, which); + spin_unlock_irqrestore(&adapter->hw_lock, flags); +} + +// ---------------------------------------------------------------------- + +static inline void B_L1L2(struct fritz_bcs *bcs, int pr, void *arg) +{ + struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if; + + DBG(2, "pr %#x", pr); + ifc->l1l2(ifc, pr, arg); +} + +static void hdlc_fill_fifo(struct fritz_bcs *bcs) +{ + struct fritz_adapter *adapter = bcs->adapter; + struct sk_buff *skb = bcs->tx_skb; + int count; + int fifo_size = 32; + unsigned long flags; + unsigned char *p; + + DBG(0x40, "hdlc_fill_fifo"); + + if (!skb) + BUG(); + + if (skb->len == 0) + BUG(); + + bcs->ctrl.sr.cmd &= ~HDLC_CMD_XME; + if (bcs->tx_skb->len > fifo_size) { + count = fifo_size; + } else { + count = bcs->tx_skb->len; + if (bcs->mode != L1_MODE_TRANS) + bcs->ctrl.sr.cmd |= HDLC_CMD_XME; + } + DBG(0x40, "hdlc_fill_fifo %d/%d", count, bcs->tx_skb->len); + p = bcs->tx_skb->data; + skb_pull(bcs->tx_skb, count); + bcs->tx_cnt += count; + bcs->ctrl.sr.xml = ((count == fifo_size) ? 0 : count); + + switch (adapter->type) { + case AVM_FRITZ_PCI: + spin_lock_irqsave(&adapter->hw_lock, flags); + // sets the correct AVM_INDEX, too + __fcpci_write_ctrl(bcs, 3); + outsl(adapter->io + AVM_DATA + HDLC_FIFO, + p, (count + 3) / 4); + spin_unlock_irqrestore(&adapter->hw_lock, flags); + break; + case AVM_FRITZ_PCIV2: + fcpci2_write_ctrl(bcs, 3); + outsl(adapter->io + + (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1), + p, (count + 3) / 4); + break; + case AVM_FRITZ_PNP: + spin_lock_irqsave(&adapter->hw_lock, flags); + // sets the correct AVM_INDEX, too + __fcpnp_write_ctrl(bcs, 3); + outsb(adapter->io + AVM_DATA, p, count); + spin_unlock_irqrestore(&adapter->hw_lock, flags); + break; + } +} + +static inline void hdlc_empty_fifo(struct fritz_bcs *bcs, int count) +{ + struct fritz_adapter *adapter = bcs->adapter; + unsigned char *p; + unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1; + + DBG(0x10, "hdlc_empty_fifo %d", count); + if (bcs->rcvidx + count > HSCX_BUFMAX) { + DBG(0x10, "hdlc_empty_fifo: incoming packet too large"); + return; + } + p = bcs->rcvbuf + bcs->rcvidx; + bcs->rcvidx += count; + switch (adapter->type) { + case AVM_FRITZ_PCI: + spin_lock(&adapter->hw_lock); + outl(idx, adapter->io + AVM_INDEX); + insl(adapter->io + AVM_DATA + HDLC_FIFO, + p, (count + 3) / 4); + spin_unlock(&adapter->hw_lock); + break; + case AVM_FRITZ_PCIV2: + insl(adapter->io + + (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1), + p, (count + 3) / 4); + break; + case AVM_FRITZ_PNP: + spin_lock(&adapter->hw_lock); + outb(idx, adapter->io + AVM_INDEX); + insb(adapter->io + AVM_DATA, p, count); + spin_unlock(&adapter->hw_lock); + break; + } +} + +static inline void hdlc_rpr_irq(struct fritz_bcs *bcs, u32 stat) +{ + struct fritz_adapter *adapter = bcs->adapter; + struct sk_buff *skb; + int len; + + if (stat & HDLC_STAT_RDO) { + DBG(0x10, "RDO"); + bcs->ctrl.sr.xml = 0; + bcs->ctrl.sr.cmd |= HDLC_CMD_RRS; + adapter->write_ctrl(bcs, 1); + bcs->ctrl.sr.cmd &= ~HDLC_CMD_RRS; + adapter->write_ctrl(bcs, 1); + bcs->rcvidx = 0; + return; + } + + len = (stat & HDLC_STAT_RML_MASK) >> 8; + if (len == 0) + len = 32; + + hdlc_empty_fifo(bcs, len); + + if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) { + if (((stat & HDLC_STAT_CRCVFRRAB)== HDLC_STAT_CRCVFR) || + (bcs->mode == L1_MODE_TRANS)) { + skb = dev_alloc_skb(bcs->rcvidx); + if (!skb) { + printk(KERN_WARNING "HDLC: receive out of memory\n"); + } else { + memcpy(skb_put(skb, bcs->rcvidx), bcs->rcvbuf, + bcs->rcvidx); + DBG_SKB(1, skb); + B_L1L2(bcs, PH_DATA | INDICATION, skb); + } + bcs->rcvidx = 0; + } else { + DBG(0x10, "ch%d invalid frame %#x", + bcs->channel, stat); + bcs->rcvidx = 0; + } + } +} + +static inline void hdlc_xdu_irq(struct fritz_bcs *bcs) +{ + struct fritz_adapter *adapter = bcs->adapter; + + /* Here we lost an TX interrupt, so + * restart transmitting the whole frame. + */ + bcs->ctrl.sr.xml = 0; + bcs->ctrl.sr.cmd |= HDLC_CMD_XRS; + adapter->write_ctrl(bcs, 1); + bcs->ctrl.sr.cmd &= ~HDLC_CMD_XRS; + adapter->write_ctrl(bcs, 1); + + if (!bcs->tx_skb) { + DBG(0x10, "XDU without skb"); + return; + } + skb_push(bcs->tx_skb, bcs->tx_cnt); + bcs->tx_cnt = 0; +} + +static inline void hdlc_xpr_irq(struct fritz_bcs *bcs) +{ + struct sk_buff *skb; + + skb = bcs->tx_skb; + if (!skb) + return; + + if (skb->len) { + hdlc_fill_fifo(bcs); + return; + } + bcs->tx_cnt = 0; + bcs->tx_skb = NULL; + B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize); + dev_kfree_skb_irq(skb); +} + +static void hdlc_irq_one(struct fritz_bcs *bcs, u32 stat) +{ + DBG(0x10, "ch%d stat %#x", bcs->channel, stat); + if (stat & HDLC_INT_RPR) { + DBG(0x10, "RPR"); + hdlc_rpr_irq(bcs, stat); + } + if (stat & HDLC_INT_XDU) { + DBG(0x10, "XDU"); + hdlc_xdu_irq(bcs); + } + if (stat & HDLC_INT_XPR) { + DBG(0x10, "XPR"); + hdlc_xpr_irq(bcs); + } +} + +static inline void hdlc_irq(struct fritz_adapter *adapter) +{ + int nr; + u32 stat; + + for (nr = 0; nr < 2; nr++) { + stat = adapter->read_hdlc_status(adapter, nr); + DBG(0x10, "HDLC %c stat %#x", 'A' + nr, stat); + if (stat & HDLC_INT_MASK) + hdlc_irq_one(&adapter->bcs[nr], stat); + } +} + +static void modehdlc(struct fritz_bcs *bcs, int mode) +{ + struct fritz_adapter *adapter = bcs->adapter; + + DBG(0x40, "hdlc %c mode %d --> %d", + 'A' + bcs->channel, bcs->mode, mode); + + if (bcs->mode == mode) + return; + + bcs->ctrl.ctrl = 0; + bcs->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; + switch (mode) { + case L1_MODE_NULL: + bcs->ctrl.sr.mode = HDLC_MODE_TRANS; + adapter->write_ctrl(bcs, 5); + break; + case L1_MODE_TRANS: + bcs->ctrl.sr.mode = HDLC_MODE_TRANS; + adapter->write_ctrl(bcs, 5); + bcs->ctrl.sr.cmd = HDLC_CMD_XRS; + adapter->write_ctrl(bcs, 1); + bcs->ctrl.sr.cmd = 0; + break; + case L1_MODE_HDLC: + bcs->ctrl.sr.mode = HDLC_MODE_ITF_FLG; + adapter->write_ctrl(bcs, 5); + bcs->ctrl.sr.cmd = HDLC_CMD_XRS; + adapter->write_ctrl(bcs, 1); + bcs->ctrl.sr.cmd = 0; + break; + } + bcs->mode = mode; +} + +static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg) +{ + struct fritz_bcs *bcs = ifc->priv; + struct sk_buff *skb = arg; + int mode; + + DBG(0x10, "pr %#x", pr); + + switch (pr) { + case PH_DATA | REQUEST: + if (bcs->tx_skb) + BUG(); + + bcs->tx_skb = skb; + DBG_SKB(1, skb); + hdlc_fill_fifo(bcs); + break; + case PH_ACTIVATE | REQUEST: + mode = (int) arg; + DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode); + modehdlc(bcs, mode); + B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL); + break; + case PH_DEACTIVATE | REQUEST: + DBG(4,"B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1); + modehdlc(bcs, L1_MODE_NULL); + B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL); + break; + } +} + +// ---------------------------------------------------------------------- + +static void fcpci2_irq(int intno, void *dev, struct pt_regs *regs) +{ + struct fritz_adapter *adapter = dev; + unsigned char val; + + val = inb(adapter->io + AVM_STATUS0); + if (!(val & AVM_STATUS0_IRQ_MASK)) + /* hopefully a shared IRQ reqest */ + return; + DBG(2, "STATUS0 %#x", val); + if (val & AVM_STATUS0_IRQ_ISAC) + isacsx_irq(&adapter->isac); + + if (val & AVM_STATUS0_IRQ_HDLC) + hdlc_irq(adapter); +} + +static void fcpci_irq(int intno, void *dev, struct pt_regs *regs) +{ + struct fritz_adapter *adapter = dev; + unsigned char sval; + + sval = inb(adapter->io + 2); + if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) + /* possibly a shared IRQ reqest */ + return; + DBG(2, "sval %#x", sval); + if (!(sval & AVM_STATUS0_IRQ_ISAC)) + isac_irq(&adapter->isac); + + if (!(sval & AVM_STATUS0_IRQ_HDLC)) + hdlc_irq(adapter); +} + +// ---------------------------------------------------------------------- + +static inline void fcpci2_init(struct fritz_adapter *adapter) +{ + outb(AVM_STATUS0_RES_TIMER, adapter->io + AVM_STATUS0); + outb(AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0); + +} + +static inline void fcpci_init(struct fritz_adapter *adapter) +{ + outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | + AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0); + + outb(AVM_STATUS1_ENA_IOM | adapter->irq, + adapter->io + AVM_STATUS1); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(50*HZ / 1000); /* Timeout 50ms */ +} + +// ---------------------------------------------------------------------- + +static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter) +{ + u32 val = 0; + int retval; + + DBG(1,""); + + isac_init(&adapter->isac); // FIXME is this okay now + + retval = -EBUSY; + if (!request_region(adapter->io, 32, "fcpcipnp")) + goto err; + + switch (adapter->type) { + case AVM_FRITZ_PCIV2: + retval = request_irq(adapter->irq, fcpci2_irq, SA_SHIRQ, + "fcpcipnp", adapter); + break; + case AVM_FRITZ_PCI: + retval = request_irq(adapter->irq, fcpci_irq, SA_SHIRQ, + "fcpcipnp", adapter); + break; + case AVM_FRITZ_PNP: + retval = request_irq(adapter->irq, fcpci_irq, 0, + "fcpcipnp", adapter); + break; + } + if (retval) + goto err_region; + + switch (adapter->type) { + case AVM_FRITZ_PCIV2: + case AVM_FRITZ_PCI: + val = inl(adapter->io); + break; + case AVM_FRITZ_PNP: + val = inb(adapter->io); + val |= inb(adapter->io + 1) << 8; + break; + } + + DBG(1, "stat %#x Class %X Rev %d", + val, val & 0xff, (val>>8) & 0xff); + + spin_lock_init(&adapter->hw_lock); + adapter->isac.priv = adapter; + switch (adapter->type) { + case AVM_FRITZ_PCIV2: + adapter->isac.read_isac = &fcpci2_read_isac;; + adapter->isac.write_isac = &fcpci2_write_isac; + adapter->isac.read_isac_fifo = &fcpci2_read_isac_fifo; + adapter->isac.write_isac_fifo = &fcpci2_write_isac_fifo; + + adapter->read_hdlc_status = &fcpci2_read_hdlc_status; + adapter->write_ctrl = &fcpci2_write_ctrl; + break; + case AVM_FRITZ_PCI: + adapter->isac.read_isac = &fcpci_read_isac;; + adapter->isac.write_isac = &fcpci_write_isac; + adapter->isac.read_isac_fifo = &fcpci_read_isac_fifo; + adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo; + + adapter->read_hdlc_status = &fcpci_read_hdlc_status; + adapter->write_ctrl = &fcpci_write_ctrl; + break; + case AVM_FRITZ_PNP: + adapter->isac.read_isac = &fcpci_read_isac;; + adapter->isac.write_isac = &fcpci_write_isac; + adapter->isac.read_isac_fifo = &fcpci_read_isac_fifo; + adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo; + + adapter->read_hdlc_status = &fcpnp_read_hdlc_status; + adapter->write_ctrl = &fcpnp_write_ctrl; + break; + } + + // Reset + outb(0, adapter->io + AVM_STATUS0); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(50 * HZ / 1000); // 50 msec + outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(50 * HZ / 1000); // 50 msec + outb(0, adapter->io + AVM_STATUS0); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(10 * HZ / 1000); // 10 msec + + switch (adapter->type) { + case AVM_FRITZ_PCIV2: + fcpci2_init(adapter); + isacsx_setup(&adapter->isac); + break; + case AVM_FRITZ_PCI: + case AVM_FRITZ_PNP: + fcpci_init(adapter); + isac_setup(&adapter->isac); + break; + } + val = adapter->read_hdlc_status(adapter, 0); + DBG(0x20, "HDLC A STA %x", val); + val = adapter->read_hdlc_status(adapter, 1); + DBG(0x20, "HDLC B STA %x", val); + + adapter->bcs[0].mode = -1; + adapter->bcs[1].mode = -1; + modehdlc(&adapter->bcs[0], L1_MODE_NULL); + modehdlc(&adapter->bcs[1], L1_MODE_NULL); + + return 0; + + err_region: + release_region(adapter->io, 32); + err: + return retval; +} + +static void __devexit fcpcipnp_release(struct fritz_adapter *adapter) +{ + DBG(1,""); + + outb(0, adapter->io + AVM_STATUS0); + free_irq(adapter->irq, adapter); + release_region(adapter->io, 32); +} + +// ---------------------------------------------------------------------- + +static struct fritz_adapter * __devinit +new_adapter(struct pci_dev *pdev) +{ + struct fritz_adapter *adapter; + struct hisax_b_if *b_if[2]; + int i; + + adapter = kmalloc(sizeof(struct fritz_adapter), GFP_KERNEL); + if (!adapter) + return NULL; + + memset(adapter, 0, sizeof(struct fritz_adapter)); + + SET_MODULE_OWNER(&adapter->isac.hisax_d_if); + adapter->isac.hisax_d_if.ifc.priv = &adapter->isac; + adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1; + + for (i = 0; i < 2; i++) { + adapter->bcs[i].adapter = adapter; + adapter->bcs[i].channel = i; + adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i]; + adapter->bcs[i].b_if.ifc.l2l1 = fritz_b_l2l1; + } + + pci_set_drvdata(pdev, adapter); + + for (i = 0; i < 2; i++) + b_if[i] = &adapter->bcs[i].b_if; + + hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol); + + return adapter; +} + +static void delete_adapter(struct fritz_adapter *adapter) +{ + hisax_unregister(&adapter->isac.hisax_d_if); + kfree(adapter); +} + +static int __devinit fcpci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct fritz_adapter *adapter; + int retval; + + retval = -ENOMEM; + adapter = new_adapter(pdev); + if (!adapter) + goto err; + + if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2) + adapter->type = AVM_FRITZ_PCIV2; + else + adapter->type = AVM_FRITZ_PCI; + + retval = pci_enable_device(pdev); + if (retval) + goto err_free; + + adapter->io = pci_resource_start(pdev, 1); + adapter->irq = pdev->irq; + + printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at %s\n", + (char *) ent->driver_data, pdev->slot_name); + + retval = fcpcipnp_setup(adapter); + if (retval) + goto err_free; + + return 0; + + err_free: + delete_adapter(adapter); + err: + return retval; +} + +static int __devinit fcpnp_probe(struct pci_dev *pdev, + const struct isapnp_device_id *ent) +{ + struct fritz_adapter *adapter; + int retval; + + retval = -ENOMEM; + adapter = new_adapter(pdev); + if (!adapter) + goto err; + + adapter->type = AVM_FRITZ_PNP; + + pdev->prepare(pdev); + pdev->deactivate(pdev); // why? + pdev->activate(pdev); + adapter->io = pdev->resource[0].start; + adapter->irq = pdev->irq_resource[0].start; + + printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at IO %#x irq %d\n", + (char *) ent->driver_data, adapter->io, adapter->irq); + + retval = fcpcipnp_setup(adapter); + if (retval) + goto err_free; + + return 0; + + err_free: + delete_adapter(adapter); + err: + return retval; +} + +static void __devexit fcpci_remove(struct pci_dev *pdev) +{ + struct fritz_adapter *adapter = pci_get_drvdata(pdev); + + fcpcipnp_release(adapter); + pci_disable_device(pdev); + delete_adapter(adapter); +} + +static void __devexit fcpnp_remove(struct pci_dev *pdev) +{ + struct fritz_adapter *adapter = pci_get_drvdata(pdev); + + fcpcipnp_release(adapter); + pdev->deactivate(pdev); + delete_adapter(adapter); +} + +static struct pci_driver fcpci_driver = { + name: "fcpci", + probe: fcpci_probe, + remove: fcpci_remove, + id_table: fcpci_ids, +}; + +static struct isapnp_driver fcpnp_driver = { + name: "fcpnp", + probe: fcpnp_probe, + remove: fcpnp_remove, + id_table: fcpnp_ids, +}; + +static int __init hisax_fcpcipnp_init(void) +{ + int retval, pci_nr_found; + + printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1\n"); + + retval = pci_register_driver(&fcpci_driver); + if (retval < 0) + goto out; + pci_nr_found = retval; + + retval = isapnp_register_driver(&fcpnp_driver); + if (retval < 0) + goto out_unregister_pci; + +#if !defined(CONFIG_HOTPLUG) || defined(MODULE) + if (pci_nr_found + retval == 0) { + retval = -ENODEV; + goto out_unregister_isapnp; + } +#endif + return 0; + +#if !defined(CONFIG_HOTPLUG) || defined(MODULE) + out_unregister_isapnp: + isapnp_unregister_driver(&fcpnp_driver); +#endif + out_unregister_pci: + pci_unregister_driver(&fcpci_driver); + out: + return retval; +} + +static void __exit hisax_fcpcipnp_exit(void) +{ + isapnp_unregister_driver(&fcpnp_driver); + pci_unregister_driver(&fcpci_driver); +} + +module_init(hisax_fcpcipnp_init); +module_exit(hisax_fcpcipnp_exit); diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/hisax/hisax_fcpcipnp.h linux/drivers/isdn/hisax/hisax_fcpcipnp.h --- v2.5.0/linux/drivers/isdn/hisax/hisax_fcpcipnp.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/hisax_fcpcipnp.h Fri Nov 30 09:48:32 2001 @@ -0,0 +1,57 @@ +#include "hisax_if.h" +#include "hisax_isac.h" +#include + +#define HSCX_BUFMAX 4096 + +enum { + AVM_FRITZ_PCI, + AVM_FRITZ_PNP, + AVM_FRITZ_PCIV2, +}; + +struct hdlc_stat_reg { +#ifdef __BIG_ENDIAN + u_char fill __attribute__((packed)); + u_char mode __attribute__((packed)); + u_char xml __attribute__((packed)); + u_char cmd __attribute__((packed)); +#else + u_char cmd __attribute__((packed)); + u_char xml __attribute__((packed)); + u_char mode __attribute__((packed)); + u_char fill __attribute__((packed)); +#endif +}; + +struct fritz_bcs { + struct hisax_b_if b_if; + struct fritz_adapter *adapter; + int mode; + int channel; + + union { + u_int ctrl; + struct hdlc_stat_reg sr; + } ctrl; + u_int stat; + int rcvidx; + u_char rcvbuf[HSCX_BUFMAX]; /* B-Channel receive Buffer */ + + int tx_cnt; /* B-Channel transmit counter */ + struct sk_buff *tx_skb; /* B-Channel transmit Buffer */ +}; + +struct fritz_adapter { + int type; + spinlock_t hw_lock; + unsigned int io; + unsigned int irq; + struct isac isac; + + struct fritz_bcs bcs[2]; + + u32 (*read_hdlc_status) (struct fritz_adapter *adapter, int nr); + void (*write_ctrl) (struct fritz_bcs *bcs, int which); +}; + diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/hisax/hisax_isac.c linux/drivers/isdn/hisax/hisax_isac.c --- v2.5.0/linux/drivers/isdn/hisax/hisax_isac.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/hisax_isac.c Thu Dec 6 14:01:17 2001 @@ -0,0 +1,896 @@ +/* + * Driver for ISAC-S and ISAC-SX + * ISDN Subscriber Access Controller for Terminals + * + * Author Kai Germaschewski + * Copyright 2001 by Kai Germaschewski + * 2001 by Karsten Keil + * + * based upon Karsten Keil's original isac.c driver + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * Thanks to Wizard Computersysteme GmbH, Bremervoerde and + * SoHaNet Technology GmbH, Berlin + * for supporting the development of this driver + */ + +/* TODO: + * specifically handle level vs edge triggered? + */ + +#include +#include +#include +#include "hisax_isac.h" + +// debugging cruft + +#define __debug_variable debug +#include "hisax_debug.h" + +#ifdef CONFIG_HISAX_DEBUG +static int debug = 1; +MODULE_PARM(debug, "i"); + +static char *ISACVer[] = { + "2086/2186 V1.1", + "2085 B1", + "2085 B2", + "2085 V2.3" +}; +#endif + +MODULE_AUTHOR("Kai Germaschewski /Karsten Keil "); +MODULE_DESCRIPTION("ISAC/ISAC-SX driver"); + +#define DBG_WARN 0x0001 +#define DBG_IRQ 0x0002 +#define DBG_L1M 0x0004 +#define DBG_PR 0x0008 +#define DBG_RFIFO 0x0100 +#define DBG_RPACKET 0x0200 +#define DBG_XFIFO 0x1000 +#define DBG_XPACKET 0x2000 + +// we need to distinguish ISAC-S and ISAC-SX +#define TYPE_ISAC 0x00 +#define TYPE_ISACSX 0x01 + +// registers etc. +#define ISAC_MASK 0x20 +#define ISAC_ISTA 0x20 +#define ISAC_ISTA_EXI 0x01 +#define ISAC_ISTA_SIN 0x02 +#define ISAC_ISTA_CISQ 0x04 +#define ISAC_ISTA_XPR 0x10 +#define ISAC_ISTA_RSC 0x20 +#define ISAC_ISTA_RPF 0x40 +#define ISAC_ISTA_RME 0x80 + +#define ISAC_STAR 0x21 +#define ISAC_CMDR 0x21 +#define ISAC_CMDR_XRES 0x01 +#define ISAC_CMDR_XME 0x02 +#define ISAC_CMDR_XTF 0x08 +#define ISAC_CMDR_RRES 0x40 +#define ISAC_CMDR_RMC 0x80 + +#define ISAC_EXIR 0x24 +#define ISAC_EXIR_MOS 0x04 +#define ISAC_EXIR_XDU 0x40 +#define ISAC_EXIR_XMR 0x80 + +#define ISAC_ADF2 0x39 +#define ISAC_SPCR 0x30 +#define ISAC_ADF1 0x38 + +#define ISAC_CIR0 0x31 +#define ISAC_CIX0 0x31 +#define ISAC_CIR0_CIC0 0x02 +#define ISAC_CIR0_CIC1 0x01 + +#define ISAC_CIR1 0x33 +#define ISAC_CIX1 0x33 +#define ISAC_STCR 0x37 +#define ISAC_MODE 0x22 + +#define ISAC_RSTA 0x27 +#define ISAC_RSTA_RDO 0x40 +#define ISAC_RSTA_CRC 0x20 +#define ISAC_RSTA_RAB 0x10 + +#define ISAC_RBCL 0x25 +#define ISAC_RBCH 0x2A +#define ISAC_TIMR 0x23 +#define ISAC_SQXR 0x3b +#define ISAC_MOSR 0x3a +#define ISAC_MOCR 0x3a +#define ISAC_MOR0 0x32 +#define ISAC_MOX0 0x32 +#define ISAC_MOR1 0x34 +#define ISAC_MOX1 0x34 + +#define ISAC_RBCH_XAC 0x80 + +#define ISAC_CMD_TIM 0x0 +#define ISAC_CMD_RES 0x1 +#define ISAC_CMD_SSP 0x2 +#define ISAC_CMD_SCP 0x3 +#define ISAC_CMD_AR8 0x8 +#define ISAC_CMD_AR10 0x9 +#define ISAC_CMD_ARL 0xa +#define ISAC_CMD_DI 0xf + +#define ISACSX_MASK 0x60 +#define ISACSX_ISTA 0x60 +#define ISACSX_ISTA_ICD 0x01 +#define ISACSX_ISTA_CIC 0x10 + +#define ISACSX_MASKD 0x20 +#define ISACSX_ISTAD 0x20 +#define ISACSX_ISTAD_XDU 0x04 +#define ISACSX_ISTAD_XMR 0x08 +#define ISACSX_ISTAD_XPR 0x10 +#define ISACSX_ISTAD_RFO 0x20 +#define ISACSX_ISTAD_RPF 0x40 +#define ISACSX_ISTAD_RME 0x80 + +#define ISACSX_CMDRD 0x21 +#define ISACSX_CMDRD_XRES 0x01 +#define ISACSX_CMDRD_XME 0x02 +#define ISACSX_CMDRD_XTF 0x08 +#define ISACSX_CMDRD_RRES 0x40 +#define ISACSX_CMDRD_RMC 0x80 + +#define ISACSX_MODED 0x22 + +#define ISACSX_RBCLD 0x26 + +#define ISACSX_RSTAD 0x28 +#define ISACSX_RSTAD_RAB 0x10 +#define ISACSX_RSTAD_CRC 0x20 +#define ISACSX_RSTAD_RDO 0x40 +#define ISACSX_RSTAD_VFR 0x80 + +#define ISACSX_CIR0 0x2e +#define ISACSX_CIR0_CIC0 0x08 +#define ISACSX_CIX0 0x2e + +#define ISACSX_TR_CONF0 0x30 + +#define ISACSX_TR_CONF2 0x32 + +static struct Fsm l1fsm; + +enum { + ST_L1_RESET, + ST_L1_F3_PDOWN, + ST_L1_F3_PUP, + ST_L1_F3_PEND_DEACT, + ST_L1_F4, + ST_L1_F5, + ST_L1_F6, + ST_L1_F7, + ST_L1_F8, +}; + +#define L1_STATE_COUNT (ST_L1_F8+1) + +static char *strL1State[] = +{ + "ST_L1_RESET", + "ST_L1_F3_PDOWN", + "ST_L1_F3_PUP", + "ST_L1_F3_PEND_DEACT", + "ST_L1_F4", + "ST_L1_F5", + "ST_L1_F6", + "ST_L1_F7", + "ST_L1_F8", +}; + +enum { + EV_PH_DR, // 0000 + EV_PH_RES, // 0001 + EV_PH_TMA, // 0010 + EV_PH_SLD, // 0011 + EV_PH_RSY, // 0100 + EV_PH_DR6, // 0101 + EV_PH_EI, // 0110 + EV_PH_PU, // 0111 + EV_PH_AR, // 1000 + EV_PH_9, // 1001 + EV_PH_ARL, // 1010 + EV_PH_CVR, // 1011 + EV_PH_AI8, // 1100 + EV_PH_AI10, // 1101 + EV_PH_AIL, // 1110 + EV_PH_DC, // 1111 + EV_PH_ACTIVATE_REQ, + EV_PH_DEACTIVATE_REQ, + EV_TIMER3, +}; + +#define L1_EVENT_COUNT (EV_TIMER3 + 1) + +static char *strL1Event[] = +{ + "EV_PH_DR", // 0000 + "EV_PH_RES", // 0001 + "EV_PH_TMA", // 0010 + "EV_PH_SLD", // 0011 + "EV_PH_RSY", // 0100 + "EV_PH_DR6", // 0101 + "EV_PH_EI", // 0110 + "EV_PH_PU", // 0111 + "EV_PH_AR", // 1000 + "EV_PH_9", // 1001 + "EV_PH_ARL", // 1010 + "EV_PH_CVR", // 1011 + "EV_PH_AI8", // 1100 + "EV_PH_AI10", // 1101 + "EV_PH_AIL", // 1110 + "EV_PH_DC", // 1111 + "EV_PH_ACTIVATE_REQ", + "EV_PH_DEACTIVATE_REQ", + "EV_TIMER3", +}; + +static inline void D_L1L2(struct isac *isac, int pr, void *arg) +{ + struct hisax_if *ifc = (struct hisax_if *) &isac->hisax_d_if; + + DBG(DBG_PR, "pr %#x", pr); + ifc->l1l2(ifc, pr, arg); +} + +static void ph_command(struct isac *isac, unsigned int command) +{ + DBG(DBG_L1M, "ph_command %#x", command); + switch (isac->type) { + case TYPE_ISAC: + isac->write_isac(isac, ISAC_CIX0, (command << 2) | 3); + break; + case TYPE_ISACSX: + isac->write_isac(isac, ISACSX_CIX0, (command << 4) | (7 << 1)); + break; + } +} + +// ---------------------------------------------------------------------- + +static void l1_di(struct FsmInst *fi, int event, void *arg) +{ + struct isac *isac = fi->userdata; + + FsmChangeState(fi, ST_L1_RESET); + ph_command(isac, ISAC_CMD_DI); +} + +static void l1_di_deact_ind(struct FsmInst *fi, int event, void *arg) +{ + struct isac *isac = fi->userdata; + + FsmChangeState(fi, ST_L1_RESET); + D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); + ph_command(isac, ISAC_CMD_DI); +} + +static void l1_go_f3pdown(struct FsmInst *fi, int event, void *arg) +{ + FsmChangeState(fi, ST_L1_F3_PDOWN); +} + +static void l1_go_f3pend_deact_ind(struct FsmInst *fi, int event, void *arg) +{ + struct isac *isac = fi->userdata; + + FsmChangeState(fi, ST_L1_F3_PEND_DEACT); + D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); + ph_command(isac, ISAC_CMD_DI); +} + +static void l1_go_f3pend(struct FsmInst *fi, int event, void *arg) +{ + struct isac *isac = fi->userdata; + + FsmChangeState(fi, ST_L1_F3_PEND_DEACT); + ph_command(isac, ISAC_CMD_DI); +} + +static void l1_go_f4(struct FsmInst *fi, int event, void *arg) +{ + FsmChangeState(fi, ST_L1_F4); +} + +static void l1_go_f5(struct FsmInst *fi, int event, void *arg) +{ + FsmChangeState(fi, ST_L1_F5); +} + +static void l1_go_f6(struct FsmInst *fi, int event, void *arg) +{ + FsmChangeState(fi, ST_L1_F6); +} + +static void l1_go_f6_deact_ind(struct FsmInst *fi, int event, void *arg) +{ + struct isac *isac = fi->userdata; + + FsmChangeState(fi, ST_L1_F6); + D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); +} + +static void l1_go_f7_act_ind(struct FsmInst *fi, int event, void *arg) +{ + struct isac *isac = fi->userdata; + + FsmDelTimer(&isac->timer, 0); + FsmChangeState(fi, ST_L1_F7); + ph_command(isac, ISAC_CMD_AR8); + D_L1L2(isac, PH_ACTIVATE | INDICATION, NULL); +} + +static void l1_go_f8(struct FsmInst *fi, int event, void *arg) +{ + FsmChangeState(fi, ST_L1_F8); +} + +static void l1_go_f8_deact_ind(struct FsmInst *fi, int event, void *arg) +{ + struct isac *isac = fi->userdata; + + FsmChangeState(fi, ST_L1_F8); + D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); +} + +static void l1_ar8(struct FsmInst *fi, int event, void *arg) +{ + struct isac *isac = fi->userdata; + + FsmRestartTimer(&isac->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); + ph_command(isac, ISAC_CMD_AR8); +} + +static void l1_timer3(struct FsmInst *fi, int event, void *arg) +{ + struct isac *isac = fi->userdata; + + ph_command(isac, ISAC_CMD_DI); + D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); +} + +// state machines according to data sheet PSB 2186 / 3186 + +static struct FsmNode L1FnList[] __initdata = +{ + {ST_L1_RESET, EV_PH_RES, l1_di}, + {ST_L1_RESET, EV_PH_EI, l1_di}, + {ST_L1_RESET, EV_PH_DC, l1_go_f3pdown}, + {ST_L1_RESET, EV_PH_AR, l1_go_f6}, + {ST_L1_RESET, EV_PH_AI8, l1_go_f7_act_ind}, + + {ST_L1_F3_PDOWN, EV_PH_RES, l1_di}, + {ST_L1_F3_PDOWN, EV_PH_EI, l1_di}, + {ST_L1_F3_PDOWN, EV_PH_AR, l1_go_f6}, + {ST_L1_F3_PDOWN, EV_PH_RSY, l1_go_f5}, + {ST_L1_F3_PDOWN, EV_PH_PU, l1_go_f4}, + {ST_L1_F3_PDOWN, EV_PH_AI8, l1_go_f7_act_ind}, + {ST_L1_F3_PDOWN, EV_PH_ACTIVATE_REQ, l1_ar8}, + {ST_L1_F3_PDOWN, EV_TIMER3, l1_timer3}, + + {ST_L1_F3_PEND_DEACT, EV_PH_RES, l1_di}, + {ST_L1_F3_PEND_DEACT, EV_PH_EI, l1_di}, + {ST_L1_F3_PEND_DEACT, EV_PH_DC, l1_go_f3pdown}, + {ST_L1_F3_PEND_DEACT, EV_PH_RSY, l1_go_f5}, + {ST_L1_F3_PEND_DEACT, EV_PH_AR, l1_go_f6}, + {ST_L1_F3_PEND_DEACT, EV_PH_AI8, l1_go_f7_act_ind}, + + {ST_L1_F4, EV_PH_RES, l1_di}, + {ST_L1_F4, EV_PH_EI, l1_di}, + {ST_L1_F4, EV_PH_RSY, l1_go_f5}, + {ST_L1_F4, EV_PH_AI8, l1_go_f7_act_ind}, + {ST_L1_F4, EV_TIMER3, l1_timer3}, + {ST_L1_F4, EV_PH_DC, l1_go_f3pdown}, + + {ST_L1_F5, EV_PH_RES, l1_di}, + {ST_L1_F5, EV_PH_EI, l1_di}, + {ST_L1_F5, EV_PH_AR, l1_go_f6}, + {ST_L1_F5, EV_PH_AI8, l1_go_f7_act_ind}, + {ST_L1_F5, EV_TIMER3, l1_timer3}, + {ST_L1_F5, EV_PH_DR, l1_go_f3pend}, + {ST_L1_F5, EV_PH_DC, l1_go_f3pdown}, + + {ST_L1_F6, EV_PH_RES, l1_di}, + {ST_L1_F6, EV_PH_EI, l1_di}, + {ST_L1_F6, EV_PH_RSY, l1_go_f8}, + {ST_L1_F6, EV_PH_AI8, l1_go_f7_act_ind}, + {ST_L1_F6, EV_PH_DR6, l1_go_f3pend}, + {ST_L1_F6, EV_TIMER3, l1_timer3}, + {ST_L1_F6, EV_PH_DC, l1_go_f3pdown}, + + {ST_L1_F7, EV_PH_RES, l1_di_deact_ind}, + {ST_L1_F7, EV_PH_EI, l1_di_deact_ind}, + {ST_L1_F7, EV_PH_AR, l1_go_f6_deact_ind}, + {ST_L1_F7, EV_PH_RSY, l1_go_f8_deact_ind}, + {ST_L1_F7, EV_PH_DR, l1_go_f3pend_deact_ind}, + + {ST_L1_F8, EV_PH_RES, l1_di}, + {ST_L1_F8, EV_PH_EI, l1_di}, + {ST_L1_F8, EV_PH_AR, l1_go_f6}, + {ST_L1_F8, EV_PH_DR, l1_go_f3pend}, + {ST_L1_F8, EV_PH_AI8, l1_go_f7_act_ind}, + {ST_L1_F8, EV_TIMER3, l1_timer3}, + {ST_L1_F8, EV_PH_DC, l1_go_f3pdown}, +}; + +static void l1m_debug(struct FsmInst *fi, char *fmt, ...) +{ + va_list args; + char buf[256]; + + va_start(args, fmt); + vsprintf(buf, fmt, args); + DBG(DBG_L1M, "%s", buf); + va_end(args); +} + +static void isac_version(struct isac *cs) +{ + int val; + + val = cs->read_isac(cs, ISAC_RBCH); + DBG(1, "ISAC version (%x): %s", val, ISACVer[(val >> 5) & 3]); +} + +static void isac_empty_fifo(struct isac *isac, int count) +{ + // this also works for isacsx, since + // CMDR(D) register works the same + u_char *ptr; + + DBG(DBG_IRQ, "count %d", count); + + if ((isac->rcvidx + count) >= MAX_DFRAME_LEN_L1) { + DBG(DBG_WARN, "overrun %d", isac->rcvidx + count); + isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); + isac->rcvidx = 0; + return; + } + ptr = isac->rcvbuf + isac->rcvidx; + isac->rcvidx += count; + isac->read_isac_fifo(isac, ptr, count); + isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); + DBG_PACKET(DBG_RFIFO, ptr, count); +} + +static void isac_fill_fifo(struct isac *isac) +{ + // this also works for isacsx, since + // CMDR(D) register works the same + + int count; + unsigned char cmd; + u_char *ptr; + + if (!isac->tx_skb) + BUG(); + + count = isac->tx_skb->len; + if (count <= 0) + BUG(); + + DBG(DBG_IRQ, "count %d", count); + + if (count > 0x20) { + count = 0x20; + cmd = ISAC_CMDR_XTF; + } else { + cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME; + } + + ptr = isac->tx_skb->data; + skb_pull(isac->tx_skb, count); + isac->tx_cnt += count; + DBG_PACKET(DBG_XFIFO, ptr, count); + isac->write_isac_fifo(isac, ptr, count); + isac->write_isac(isac, ISAC_CMDR, cmd); +} + +static void isac_retransmit(struct isac *isac) +{ + if (!isac->tx_skb) { + DBG(DBG_WARN, "no skb"); + return; + } + skb_push(isac->tx_skb, isac->tx_cnt); + isac->tx_cnt = 0; +} + + +static inline void isac_cisq_interrupt(struct isac *isac) +{ + unsigned char val; + + val = isac->read_isac(isac, ISAC_CIR0); + DBG(DBG_IRQ, "CIR0 %#x", val); + if (val & ISAC_CIR0_CIC0) { + DBG(DBG_IRQ, "CODR0 %#x", (val >> 2) & 0xf); + FsmEvent(&isac->l1m, (val >> 2) & 0xf, NULL); + } + if (val & ISAC_CIR0_CIC1) { + val = isac->read_isac(isac, ISAC_CIR1); + DBG(DBG_WARN, "ISAC CIR1 %#x", val ); + } +} + +static inline void isac_rme_interrupt(struct isac *isac) +{ + unsigned char val; + int count; + struct sk_buff *skb; + + val = isac->read_isac(isac, ISAC_RSTA); + if ((val & (ISAC_RSTA_RDO | ISAC_RSTA_CRC | ISAC_RSTA_RAB) ) + != ISAC_RSTA_CRC) { + DBG(DBG_WARN, "RSTA %#x, dropped", val); + isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); + goto out; + } + + count = isac->read_isac(isac, ISAC_RBCL) & 0x1f; + DBG(DBG_IRQ, "RBCL %#x", count); + if (count == 0) + count = 0x20; + + isac_empty_fifo(isac, count); + count = isac->rcvidx; + if (count < 1) { + DBG(DBG_WARN, "count %d < 1", count); + goto out; + } + + skb = alloc_skb(count, GFP_ATOMIC); + if (!skb) { + DBG(DBG_WARN, "no memory, dropping\n"); + goto out; + } + memcpy(skb_put(skb, count), isac->rcvbuf, count); + DBG_SKB(DBG_RPACKET, skb); + D_L1L2(isac, PH_DATA | INDICATION, skb); + out: + isac->rcvidx = 0; +} + +static inline void isac_xpr_interrupt(struct isac *isac) +{ + if (!isac->tx_skb) + return; + + if (isac->tx_skb->len > 0) { + isac_fill_fifo(isac); + return; + } + dev_kfree_skb_irq(isac->tx_skb); + isac->tx_cnt = 0; + isac->tx_skb = NULL; + D_L1L2(isac, PH_DATA | CONFIRM, NULL); +} + +static inline void isac_exi_interrupt(struct isac *isac) +{ + unsigned char val; + + val = isac->read_isac(isac, ISAC_EXIR); + DBG(2, "EXIR %#x", val); + + if (val & ISAC_EXIR_XMR) { + DBG(DBG_WARN, "ISAC XMR"); + isac_retransmit(isac); + } + if (val & ISAC_EXIR_XDU) { + DBG(DBG_WARN, "ISAC XDU"); + isac_retransmit(isac); + } + if (val & ISAC_EXIR_MOS) { /* MOS */ + DBG(DBG_WARN, "MOS"); + val = isac->read_isac(isac, ISAC_MOSR); + DBG(2, "ISAC MOSR %#x", val); + } +} + +void isac_irq(struct isac *isac) +{ + unsigned char val; + + val = isac->read_isac(isac, ISAC_ISTA); + DBG(DBG_IRQ, "ISTA %#x", val); + + if (val & ISAC_ISTA_EXI) { + DBG(DBG_IRQ, "EXI"); + isac_exi_interrupt(isac); + } + if (val & ISAC_ISTA_XPR) { + DBG(DBG_IRQ, "XPR"); + isac_xpr_interrupt(isac); + } + if (val & ISAC_ISTA_RME) { + DBG(DBG_IRQ, "RME"); + isac_rme_interrupt(isac); + } + if (val & ISAC_ISTA_RPF) { + DBG(DBG_IRQ, "RPF"); + isac_empty_fifo(isac, 0x20); + } + if (val & ISAC_ISTA_CISQ) { + DBG(DBG_IRQ, "CISQ"); + isac_cisq_interrupt(isac); + } + if (val & ISAC_ISTA_RSC) { + DBG(DBG_WARN, "RSC"); + } + if (val & ISAC_ISTA_SIN) { + DBG(DBG_WARN, "SIN"); + } + isac->write_isac(isac, ISAC_MASK, 0xff); + isac->write_isac(isac, ISAC_MASK, 0x00); +} + +// ====================================================================== + +static inline void isacsx_cic_interrupt(struct isac *isac) +{ + unsigned char val; + + val = isac->read_isac(isac, ISACSX_CIR0); + DBG(DBG_IRQ, "CIR0 %#x", val); + if (val & ISACSX_CIR0_CIC0) { + DBG(DBG_IRQ, "CODR0 %#x", val >> 4); + FsmEvent(&isac->l1m, val >> 4, NULL); + } +} + +static inline void isacsx_rme_interrupt(struct isac *isac) +{ + int count; + struct sk_buff *skb; + unsigned char val; + + val = isac->read_isac(isac, ISACSX_RSTAD); + if ((val & (ISACSX_RSTAD_VFR | + ISACSX_RSTAD_RDO | + ISACSX_RSTAD_CRC | + ISACSX_RSTAD_RAB)) + != (ISACSX_RSTAD_VFR | ISACSX_RSTAD_CRC)) { + DBG(DBG_WARN, "RSTAD %#x, dropped", val); + isac->write_isac(isac, ISACSX_CMDRD, ISACSX_CMDRD_RMC); + goto out; + } + + count = isac->read_isac(isac, ISACSX_RBCLD) & 0x1f; + DBG(DBG_IRQ, "RBCLD %#x", count); + if (count == 0) + count = 0x20; + + isac_empty_fifo(isac, count); + // strip trailing status byte + count = isac->rcvidx - 1; + if (count < 1) { + DBG(DBG_WARN, "count %d < 1", count); + goto out; + } + + skb = dev_alloc_skb(count); + if (!skb) { + DBG(DBG_WARN, "no memory, dropping"); + goto out; + } + memcpy(skb_put(skb, count), isac->rcvbuf, count); + DBG_SKB(DBG_RPACKET, skb); + D_L1L2(isac, PH_DATA | INDICATION, skb); + out: + isac->rcvidx = 0; +} + +static inline void isacsx_xpr_interrupt(struct isac *isac) +{ + if (!isac->tx_skb) + return; + + if (isac->tx_skb->len > 0) { + isac_fill_fifo(isac); + return; + } + dev_kfree_skb_irq(isac->tx_skb); + isac->tx_skb = NULL; + isac->tx_cnt = 0; + D_L1L2(isac, PH_DATA | CONFIRM, NULL); +} + +static inline void isacsx_icd_interrupt(struct isac *isac) +{ + unsigned char val; + + val = isac->read_isac(isac, ISACSX_ISTAD); + DBG(DBG_IRQ, "ISTAD %#x", val); + if (val & ISACSX_ISTAD_XDU) { + DBG(DBG_WARN, "ISTAD XDU"); + isac_retransmit(isac); + } + if (val & ISACSX_ISTAD_XMR) { + DBG(DBG_WARN, "ISTAD XMR"); + isac_retransmit(isac); + } + if (val & ISACSX_ISTAD_XPR) { + DBG(DBG_IRQ, "ISTAD XPR"); + isacsx_xpr_interrupt(isac); + } + if (val & ISACSX_ISTAD_RFO) { + DBG(DBG_WARN, "ISTAD RFO"); + isac->write_isac(isac, ISACSX_CMDRD, ISACSX_CMDRD_RMC); + } + if (val & ISACSX_ISTAD_RME) { + DBG(DBG_IRQ, "ISTAD RME"); + isacsx_rme_interrupt(isac); + } + if (val & ISACSX_ISTAD_RPF) { + DBG(DBG_IRQ, "ISTAD RPF"); + isac_empty_fifo(isac, 0x20); + } +} + +void isacsx_irq(struct isac *isac) +{ + unsigned char val; + + val = isac->read_isac(isac, ISACSX_ISTA); + DBG(DBG_IRQ, "ISTA %#x", val); + + if (val & ISACSX_ISTA_ICD) + isacsx_icd_interrupt(isac); + if (val & ISACSX_ISTA_CIC) + isacsx_cic_interrupt(isac); +} + +void isac_init(struct isac *isac) +{ + isac->tx_skb = NULL; + isac->l1m.fsm = &l1fsm; + isac->l1m.state = ST_L1_RESET; +#ifdef CONFIG_HISAX_DEBUG + isac->l1m.debug = 1; +#else + isac->l1m.debug = 0; +#endif + isac->l1m.userdata = isac; + isac->l1m.printdebug = l1m_debug; + FsmInitTimer(&isac->l1m, &isac->timer); +} + +void isac_setup(struct isac *isac) +{ + int val, eval; + + isac->type = TYPE_ISAC; + isac_version(isac); + + ph_command(isac, ISAC_CMD_RES); + + isac->write_isac(isac, ISAC_MASK, 0xff); + isac->mocr = 0xaa; + if (test_bit(ISAC_IOM1, &isac->flags)) { + /* IOM 1 Mode */ + isac->write_isac(isac, ISAC_ADF2, 0x0); + isac->write_isac(isac, ISAC_SPCR, 0xa); + isac->write_isac(isac, ISAC_ADF1, 0x2); + isac->write_isac(isac, ISAC_STCR, 0x70); + isac->write_isac(isac, ISAC_MODE, 0xc9); + } else { + /* IOM 2 Mode */ + if (!isac->adf2) + isac->adf2 = 0x80; + isac->write_isac(isac, ISAC_ADF2, isac->adf2); + isac->write_isac(isac, ISAC_SQXR, 0x2f); + isac->write_isac(isac, ISAC_SPCR, 0x00); + isac->write_isac(isac, ISAC_STCR, 0x70); + isac->write_isac(isac, ISAC_MODE, 0xc9); + isac->write_isac(isac, ISAC_TIMR, 0x00); + isac->write_isac(isac, ISAC_ADF1, 0x00); + } + val = isac->read_isac(isac, ISAC_STAR); + DBG(2, "ISAC STAR %x", val); + val = isac->read_isac(isac, ISAC_MODE); + DBG(2, "ISAC MODE %x", val); + val = isac->read_isac(isac, ISAC_ADF2); + DBG(2, "ISAC ADF2 %x", val); + val = isac->read_isac(isac, ISAC_ISTA); + DBG(2, "ISAC ISTA %x", val); + if (val & 0x01) { + eval = isac->read_isac(isac, ISAC_EXIR); + DBG(2, "ISAC EXIR %x", eval); + } + val = isac->read_isac(isac, ISAC_CIR0); + DBG(2, "ISAC CIR0 %x", val); + FsmEvent(&isac->l1m, (val >> 2) & 0xf, NULL); + + isac->write_isac(isac, ISAC_MASK, 0x0); + // RESET Receiver and Transmitter + isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_XRES | ISAC_CMDR_RRES); +} + +void isacsx_setup(struct isac *isac) +{ + isac->type = TYPE_ISACSX; + // clear LDD + isac->write_isac(isac, ISACSX_TR_CONF0, 0x00); + // enable transmitter + isac->write_isac(isac, ISACSX_TR_CONF2, 0x00); + // transparent mode 0, RAC, stop/go + isac->write_isac(isac, ISACSX_MODED, 0xc9); + // all HDLC IRQ unmasked + isac->write_isac(isac, ISACSX_MASKD, 0x03); + // unmask ICD, CID IRQs + isac->write_isac(isac, ISACSX_MASK, + ~(ISACSX_ISTA_ICD | ISACSX_ISTA_CIC)); +} + +void isac_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg) +{ + struct isac *isac = hisax_d_if->priv; + struct sk_buff *skb = arg; + + DBG(DBG_PR, "pr %#x", pr); + + switch (pr) { + case PH_ACTIVATE | REQUEST: + FsmEvent(&isac->l1m, EV_PH_ACTIVATE_REQ, NULL); + break; + case PH_DEACTIVATE | REQUEST: + FsmEvent(&isac->l1m, EV_PH_DEACTIVATE_REQ, NULL); + break; + case PH_DATA | REQUEST: + DBG(DBG_PR, "PH_DATA REQUEST len %d", skb->len); + DBG_SKB(DBG_XPACKET, skb); + if (isac->l1m.state != ST_L1_F7) { + DBG(1, "L1 wrong state %d\n", isac->l1m.state); + dev_kfree_skb(skb); + break; + } + if (isac->tx_skb) + BUG(); + + isac->tx_skb = skb; + isac_fill_fifo(isac); + break; + } +} + +static int __init hisax_isac_init(void) +{ + printk(KERN_INFO "hisax_isac: ISAC-S/ISAC-SX ISDN driver v0.1.0\n"); + + l1fsm.state_count = L1_STATE_COUNT; + l1fsm.event_count = L1_EVENT_COUNT; + l1fsm.strState = strL1State; + l1fsm.strEvent = strL1Event; + return FsmNew(&l1fsm, L1FnList, ARRAY_SIZE(L1FnList)); +} + +static void __exit hisax_isac_exit(void) +{ + FsmFree(&l1fsm); +} + +EXPORT_SYMBOL(isac_init); +EXPORT_SYMBOL(isac_d_l2l1); + +EXPORT_SYMBOL(isacsx_setup); +EXPORT_SYMBOL(isacsx_irq); + +EXPORT_SYMBOL(isac_setup); +EXPORT_SYMBOL(isac_irq); + +module_init(hisax_isac_init); +module_exit(hisax_isac_exit); diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/hisax/hisax_isac.h linux/drivers/isdn/hisax/hisax_isac.h --- v2.5.0/linux/drivers/isdn/hisax/hisax_isac.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/hisax_isac.h Thu Dec 6 14:01:17 2001 @@ -0,0 +1,45 @@ +#ifndef __HISAX_ISAC_H__ +#define __HISAX_ISAC_H__ + +#include +#include "fsm.h" +#include "hisax_if.h" + +#define TIMER3_VALUE 7000 +#define MAX_DFRAME_LEN_L1 300 + +#define ISAC_IOM1 0 + +struct isac { + void *priv; + + u_long flags; + struct hisax_d_if hisax_d_if; + struct FsmInst l1m; + struct FsmTimer timer; + u_char mocr; + u_char adf2; + int type; + + u_char rcvbuf[MAX_DFRAME_LEN_L1]; + int rcvidx; + + struct sk_buff *tx_skb; + int tx_cnt; + + u_char (*read_isac) (struct isac *, u_char); + void (*write_isac) (struct isac *, u_char, u_char); + void (*read_isac_fifo) (struct isac *, u_char *, int); + void (*write_isac_fifo)(struct isac *, u_char *, int); +}; + +void isac_init(struct isac *isac); +void isac_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg); + +void isac_setup(struct isac *isac); +void isac_irq(struct isac *isac); + +void isacsx_setup(struct isac *isac); +void isacsx_irq(struct isac *isac); + +#endif diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/hisax/st5481_b.c linux/drivers/isdn/hisax/st5481_b.c --- v2.5.0/linux/drivers/isdn/hisax/st5481_b.c Sun Sep 30 12:26:06 2001 +++ linux/drivers/isdn/hisax/st5481_b.c Sat Dec 8 20:28:45 2001 @@ -168,7 +168,7 @@ test_and_clear_bit(buf_nr, &b_out->busy); if (urb->status < 0) { - if (urb->status != USB_ST_URB_KILLED) { + if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); if (b_out->busy == 0) { st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2 | USB_DIR_OUT, NULL, NULL); @@ -275,7 +275,7 @@ usb_b_out_complete, bcs); } -static void __devexit st5481_release_b_out(struct st5481_bcs *bcs) +static void st5481_release_b_out(struct st5481_bcs *bcs) { struct st5481_b_out *b_out = &bcs->b_out; @@ -316,7 +316,7 @@ /* * Release buffers and URBs for the B channels */ -void __devexit st5481_release_b(struct st5481_bcs *bcs) +void st5481_release_b(struct st5481_bcs *bcs) { DBG(4,""); diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/hisax/st5481_d.c linux/drivers/isdn/hisax/st5481_d.c --- v2.5.0/linux/drivers/isdn/hisax/st5481_d.c Wed Oct 24 15:34:51 2001 +++ linux/drivers/isdn/hisax/st5481_d.c Sat Dec 8 20:28:45 2001 @@ -382,7 +382,7 @@ test_and_clear_bit(buf_nr, &d_out->busy); if (urb->status < 0) { - if (urb->status != USB_ST_URB_KILLED) { + if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); if (d_out->busy == 0) { st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter); @@ -673,7 +673,7 @@ usb_d_out_complete, adapter); } -static void __devexit st5481_release_d_out(struct st5481_adapter *adapter) +static void st5481_release_d_out(struct st5481_adapter *adapter) { struct st5481_d_out *d_out = &adapter->d_out; @@ -723,7 +723,7 @@ return retval; } -void __devexit st5481_release_d(struct st5481_adapter *adapter) +void st5481_release_d(struct st5481_adapter *adapter) { DBG(2,""); diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/hisax/st5481_usb.c linux/drivers/isdn/hisax/st5481_usb.c --- v2.5.0/linux/drivers/isdn/hisax/st5481_usb.c Wed Oct 24 15:34:51 2001 +++ linux/drivers/isdn/hisax/st5481_usb.c Sat Dec 8 20:28:45 2001 @@ -130,7 +130,7 @@ struct ctrl_msg *ctrl_msg; if (urb->status < 0) { - if (urb->status != USB_ST_URB_KILLED) { + if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); } else { DBG(1,"urb killed"); @@ -184,7 +184,7 @@ int j; if (urb->status < 0) { - if (urb->status != USB_ST_URB_KILLED) { + if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); urb->actual_length = 0; } else { @@ -307,7 +307,7 @@ * Release buffers and URBs for the interrupt and control * endpoint. */ -void __devexit st5481_release_usb(struct st5481_adapter *adapter) +void st5481_release_usb(struct st5481_adapter *adapter) { struct st5481_intr *intr = &adapter->intr; struct st5481_ctrl *ctrl = &adapter->ctrl; @@ -443,7 +443,7 @@ return retval; } -void __devexit st5481_release_isocpipes(struct urb* urb[2]) +void st5481_release_isocpipes(struct urb* urb[2]) { int j; @@ -470,7 +470,7 @@ int len, count, status; if (urb->status < 0) { - if (urb->status != USB_ST_URB_KILLED) { + if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); } else { DBG(1,"urb killed"); @@ -547,7 +547,7 @@ return retval; } -void __devexit st5481_release_in(struct st5481_in *in) +void st5481_release_in(struct st5481_in *in) { DBG(2,""); diff -u --recursive --new-file v2.5.0/linux/drivers/isdn/hysdn/hysdn_procfs.c linux/drivers/isdn/hysdn/hysdn_procfs.c --- v2.5.0/linux/drivers/isdn/hysdn/hysdn_procfs.c Sun Aug 12 10:38:48 2001 +++ linux/drivers/isdn/hysdn/hysdn_procfs.c Wed Dec 31 16:00:00 1969 @@ -1,471 +0,0 @@ -/* $Id: hysdn_procfs.c,v 1.1 2000/02/10 19:45:18 werner Exp $ - - * Linux driver for HYSDN cards, /proc/net filesystem log functions. - * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH - * - * Copyright 1999 by Werner Cornelius (werner@titro.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Log: hysdn_procfs.c,v $ - * Revision 1.1 2000/02/10 19:45:18 werner - * - * Initial release - * - * - */ - -#define __NO_VERSION__ -#include -#include -#include -#include -#include -#include - -#include "hysdn_defs.h" - -static char *hysdn_procfs_revision = "$Revision: 1.1 $"; - -#define INFO_OUT_LEN 80 /* length of info line including lf */ - -/*************************************************/ -/* structure keeping ascii log for device output */ -/*************************************************/ -struct log_data { - struct log_data *next; - ulong usage_cnt; /* number of files still to work */ - void *proc_ctrl; /* pointer to own control procdata structure */ - char log_start[2]; /* log string start (final len aligned by size) */ -}; - -/**********************************************/ -/* structure holding proc entrys for one card */ -/**********************************************/ -struct procdata { - struct proc_dir_entry *log; /* log entry */ - char log_name[15]; /* log filename */ - struct log_data *log_head, *log_tail; /* head and tail for queue */ - int if_used; /* open count for interface */ - wait_queue_head_t rd_queue; -}; - -/********************************************/ -/* put an log buffer into the log queue. */ -/* This buffer will be kept until all files */ -/* opened for read got the contents. */ -/* Flushes buffers not longer in use. */ -/********************************************/ -void -put_log_buffer(hysdn_card * card, char *cp) -{ - struct log_data *ib; - struct procdata *pd = card->procfs; - int flags; - - if (!pd) - return; - if (!cp) - return; - if (!*cp) - return; - if (pd->if_used <= 0) - return; /* no open file for read */ - - if (!(ib = (struct log_data *) kmalloc(sizeof(struct log_data) + strlen(cp), GFP_ATOMIC))) - return; /* no memory */ - strcpy(ib->log_start, cp); /* set output string */ - ib->next = NULL; - ib->proc_ctrl = pd; /* point to own control structure */ - save_flags(flags); - cli(); - ib->usage_cnt = pd->if_used; - if (!pd->log_head) - pd->log_head = ib; /* new head */ - else - pd->log_tail->next = ib; /* follows existing messages */ - pd->log_tail = ib; /* new tail */ - restore_flags(flags); - - /* delete old entrys */ - while (pd->log_head->next) { - if ((pd->log_head->usage_cnt <= 0) && - (pd->log_head->next->usage_cnt <= 0)) { - ib = pd->log_head; - pd->log_head = pd->log_head->next; - kfree(ib); - } else - break; - } /* pd->log_head->next */ - wake_up_interruptible(&(pd->rd_queue)); /* announce new entry */ -} /* put_log_buffer */ - - -/**********************************/ -/* log file operations and tables */ -/**********************************/ - -/****************************************/ -/* write log file -> set log level bits */ -/****************************************/ -static ssize_t -hysdn_log_write(struct file *file, const char *buf, size_t count, loff_t * off) -{ - int retval; - hysdn_card *card = (hysdn_card *) file->private_data; - - if (&file->f_pos != off) /* fs error check */ - return (-ESPIPE); - - if ((retval = pof_boot_write(card, buf, count)) < 0) - retval = -EFAULT; /* an error occurred */ - - return (retval); -} /* hysdn_log_write */ - -/******************/ -/* read log file */ -/******************/ -static ssize_t -hysdn_log_read(struct file *file, char *buf, size_t count, loff_t * off) -{ - struct log_data *inf; - int len; - word ino; - struct procdata *pd; - hysdn_card *card; - - if (!*((struct log_data **) file->private_data)) { - if (file->f_flags & O_NONBLOCK) - return (-EAGAIN); - - /* sorry, but we need to search the card */ - ino = file->f_dentry->d_inode->i_ino & 0xFFFF; /* low-ino */ - card = card_root; - while (card) { - pd = card->procfs; - if (pd->log->low_ino == ino) - break; - card = card->next; /* search next entry */ - } - if (card) - interruptible_sleep_on(&(pd->rd_queue)); - else - return (-EAGAIN); - - } - if (!(inf = *((struct log_data **) file->private_data))) - return (0); - - inf->usage_cnt--; /* new usage count */ - (struct log_data **) file->private_data = &inf->next; /* next structure */ - if ((len = strlen(inf->log_start)) <= count) { - if (copy_to_user(buf, inf->log_start, len)) - return -EFAULT; - file->f_pos += len; - return (len); - } - return (0); -} /* hysdn_log_read */ - -/******************/ -/* open log file */ -/******************/ -static int -hysdn_log_open(struct inode *ino, struct file *filep) -{ - hysdn_card *card; - struct procdata *pd; - ulong flags; - - lock_kernel(); - card = card_root; - while (card) { - pd = card->procfs; - if (pd->log->low_ino == (ino->i_ino & 0xFFFF)) - break; - card = card->next; /* search next entry */ - } - if (!card) { - unlock_kernel(); - return (-ENODEV); /* device is unknown/invalid */ - } - filep->private_data = card; /* remember our own card */ - - if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { - /* write only access -> boot pof data */ - if (pof_boot_open(card)) { - unlock_kernel(); - return (-EPERM); /* no permission this time */ - } - } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { - - /* read access -> log/debug read */ - save_flags(flags); - cli(); - pd->if_used++; - if (pd->log_head) - (struct log_data **) filep->private_data = &(pd->log_tail->next); - else - (struct log_data **) filep->private_data = &(pd->log_head); - restore_flags(flags); - - } else { /* simultaneous read/write access forbidden ! */ - unlock_kernel(); - return (-EPERM); /* no permission this time */ - } - unlock_kernel(); - return (0); -} /* hysdn_log_open */ - -/*******************************************************************************/ -/* close a cardlog file. If the file has been opened for exclusive write it is */ -/* assumed as pof data input and the pof loader is noticed about. */ -/* Otherwise file is handled as log output. In this case the interface usage */ -/* count is decremented and all buffers are noticed of closing. If this file */ -/* was the last one to be closed, all buffers are freed. */ -/*******************************************************************************/ -static int -hysdn_log_close(struct inode *ino, struct file *filep) -{ - struct log_data *inf; - struct procdata *pd; - hysdn_card *card; - int flags, retval = 0; - - lock_kernel(); - if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { - /* write only access -> write debug completely written */ - retval = 0; /* success */ - } else { - /* read access -> log/debug read, mark one further file as closed */ - - pd = NULL; - save_flags(flags); - cli(); - inf = *((struct log_data **) filep->private_data); /* get first log entry */ - if (inf) - pd = (struct procdata *) inf->proc_ctrl; /* still entries there */ - else { - /* no info available -> search card */ - card = card_root; - while (card) { - pd = card->procfs; - if (pd->log->low_ino == (ino->i_ino & 0xFFFF)) - break; - card = card->next; /* search next entry */ - } - if (card) - pd = card->procfs; /* pointer to procfs ctrl */ - } - if (pd) - pd->if_used--; /* decrement interface usage count by one */ - - while (inf) { - inf->usage_cnt--; /* decrement usage count for buffers */ - inf = inf->next; - } - restore_flags(flags); - - if (pd) - if (pd->if_used <= 0) /* delete buffers if last file closed */ - while (pd->log_head) { - inf = pd->log_head; - pd->log_head = pd->log_head->next; - kfree(inf); - } - } /* read access */ - - unlock_kernel(); - return (retval); -} /* hysdn_log_close */ - -/*************************************************/ -/* select/poll routine to be able using select() */ -/*************************************************/ -static unsigned int -hysdn_log_poll(struct file *file, poll_table * wait) -{ - unsigned int mask = 0; - word ino; - hysdn_card *card; - struct procdata *pd; - - if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) - return (mask); /* no polling for write supported */ - - /* we need to search the card */ - ino = file->f_dentry->d_inode->i_ino & 0xFFFF; /* low-ino */ - card = card_root; - while (card) { - pd = card->procfs; - if (pd->log->low_ino == ino) - break; - card = card->next; /* search next entry */ - } - if (!card) - return (mask); /* card not found */ - - poll_wait(file, &(pd->rd_queue), wait); - - if (*((struct log_data **) file->private_data)) - mask |= POLLIN | POLLRDNORM; - - return mask; -} /* hysdn_log_poll */ - -/**************************************************/ -/* table for log filesystem functions defined above. */ -/**************************************************/ -static struct file_operations log_fops = -{ - llseek: no_llseek, - read: hysdn_log_read, - write: hysdn_log_write, - poll: hysdn_log_poll, - open: hysdn_log_open, - release: hysdn_log_close, -}; - -/*****************************************/ -/* Output info data to the cardinfo file */ -/*****************************************/ -static int -info_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data) -{ - char tmp[INFO_OUT_LEN * 11 + 2]; - int i; - char *cp; - hysdn_card *card; - - sprintf(tmp, "id bus slot type irq iobase plx-mem dp-mem boot device"); - cp = tmp; /* start of string */ - while (*cp) - cp++; - while (((cp - tmp) % (INFO_OUT_LEN + 1)) != INFO_OUT_LEN) - *cp++ = ' '; - *cp++ = '\n'; - - card = card_root; /* start of list */ - while (card) { - sprintf(cp, "%d %3d %4d %4d %3d 0x%04x 0x%08x 0x%08x", - card->myid, - card->bus, - PCI_SLOT(card->devfn), - card->brdtype, - card->irq, - card->iobase, - card->plxbase, - card->membase); - card = card->next; - while (*cp) - cp++; - while (((cp - tmp) % (INFO_OUT_LEN + 1)) != INFO_OUT_LEN) - *cp++ = ' '; - *cp++ = '\n'; - } - - i = cp - tmp; - *start = buffer; - if (offset + length > i) { - length = i - offset; - *eof = 1; - } else if (offset > i) { - length = 0; - *eof = 1; - } - cp = tmp + offset; - - if (length > 0) { - /* start_bh_atomic(); */ - memcpy(buffer, cp, length); - /* end_bh_atomic(); */ - return length; - } - return 0; -} /* info_read */ - -/*****************************/ -/* hysdn subdir in /proc/net */ -/*****************************/ -static struct proc_dir_entry *hysdn_proc_entry = NULL; -static struct proc_dir_entry *hysdn_info_entry = NULL; - -/***************************************************************************************/ -/* hysdn_procfs_init is called when the module is loaded and after the cards have been */ -/* detected. The needed proc dir and card entries are created. */ -/***************************************************************************************/ -int -hysdn_procfs_init(void) -{ - struct procdata *pd; - hysdn_card *card; - - hysdn_proc_entry = create_proc_entry(PROC_SUBDIR_NAME, S_IFDIR | S_IRUGO | S_IXUGO, proc_net); - if (!hysdn_proc_entry) { - printk(KERN_ERR "HYSDN: unable to create hysdn subdir\n"); - return (-1); - } - hysdn_info_entry = create_proc_entry("cardinfo", 0, hysdn_proc_entry); - if (hysdn_info_entry) - hysdn_info_entry->read_proc = info_read; /* read info function */ - - /* create all cardlog proc entries */ - - card = card_root; /* start with first card */ - while (card) { - if ((pd = (struct procdata *) kmalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) { - memset(pd, 0, sizeof(struct procdata)); - - sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid); - if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL) { - pd->log->proc_fops = &log_fops; /* set new operations table */ - pd->log->owner = THIS_MODULE; - } - - init_waitqueue_head(&(pd->rd_queue)); - - card->procfs = (void *) pd; /* remember procfs structure */ - } - card = card->next; /* point to next card */ - } - - printk(KERN_NOTICE "HYSDN: procfs Rev. %s initialised\n", hysdn_getrev(hysdn_procfs_revision)); - return (0); -} /* hysdn_procfs_init */ - -/***************************************************************************************/ -/* hysdn_procfs_release is called when the module is unloaded and before the cards */ -/* resources are released. The module counter is assumed to be 0 ! */ -/***************************************************************************************/ -void -hysdn_procfs_release(void) -{ - struct procdata *pd; - hysdn_card *card; - - card = card_root; /* start with first card */ - while (card) { - if ((pd = (struct procdata *) card->procfs) != NULL) { - if (pd->log) - remove_proc_entry(pd->log_name, hysdn_proc_entry); - kfree(pd); /* release memory */ - } - card = card->next; /* point to next card */ - } - - remove_proc_entry("cardinfo", hysdn_proc_entry); - remove_proc_entry(PROC_SUBDIR_NAME, proc_net); -} /* hysdn_procfs_release */ diff -u --recursive --new-file v2.5.0/linux/drivers/macintosh/adb.c linux/drivers/macintosh/adb.c --- v2.5.0/linux/drivers/macintosh/adb.c Tue Sep 18 14:23:14 2001 +++ linux/drivers/macintosh/adb.c Fri Nov 30 08:26:04 2001 @@ -672,7 +672,6 @@ struct adbdev_state *state = file->private_data; unsigned long flags; - lock_kernel(); if (state) { file->private_data = NULL; spin_lock_irqsave(&state->lock, flags); @@ -685,7 +684,6 @@ spin_unlock_irqrestore(&state->lock, flags); } } - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c --- v2.5.0/linux/drivers/macintosh/via-pmu.c Sat Sep 8 12:38:42 2001 +++ linux/drivers/macintosh/via-pmu.c Fri Nov 30 08:26:04 2001 @@ -1983,7 +1983,6 @@ struct pmu_private *pp = file->private_data; unsigned long flags; - lock_kernel(); if (pp != 0) { file->private_data = 0; spin_lock_irqsave(&all_pvt_lock, flags); @@ -1991,7 +1990,6 @@ spin_unlock_irqrestore(&all_pvt_lock, flags); kfree(pp); } - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/md/linear.c linux/drivers/md/linear.c --- v2.5.0/linux/drivers/md/linear.c Sun Sep 30 12:26:06 2001 +++ linux/drivers/md/linear.c Tue Dec 11 13:47:35 2001 @@ -119,22 +119,21 @@ return 0; } -static int linear_make_request (mddev_t *mddev, - int rw, struct buffer_head * bh) +static int linear_make_request (mddev_t *mddev, int rw, struct bio *bio) { linear_conf_t *conf = mddev_to_conf(mddev); struct linear_hash *hash; dev_info_t *tmp_dev; long block; - block = bh->b_rsector >> 1; + block = bio->bi_sector >> 1; hash = conf->hash_table + (block / conf->smallest->size); if (block >= (hash->dev0->size + hash->dev0->offset)) { if (!hash->dev1) { printk ("linear_make_request : hash->dev1==NULL for block %ld\n", block); - buffer_IO_error(bh); + bio_io_error(bio); return 0; } tmp_dev = hash->dev1; @@ -144,11 +143,11 @@ if (block >= (tmp_dev->size + tmp_dev->offset) || block < tmp_dev->offset) { printk ("linear_make_request: Block %ld out of bounds on dev %s size %ld offset %ld\n", block, kdevname(tmp_dev->dev), tmp_dev->size, tmp_dev->offset); - buffer_IO_error(bh); + bio_io_error(bio); return 0; } - bh->b_rdev = tmp_dev->dev; - bh->b_rsector = bh->b_rsector - (tmp_dev->offset << 1); + bio->bi_dev = tmp_dev->dev; + bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1); return 1; } @@ -190,7 +189,7 @@ status: linear_status, }; -static int md__init linear_init (void) +static int __init linear_init (void) { return register_md_personality (LINEAR, &linear_personality); } diff -u --recursive --new-file v2.5.0/linux/drivers/md/lvm-snap.c linux/drivers/md/lvm-snap.c --- v2.5.0/linux/drivers/md/lvm-snap.c Mon Nov 12 09:34:20 2001 +++ linux/drivers/md/lvm-snap.c Tue Nov 27 09:23:27 2001 @@ -351,7 +351,7 @@ blksize_snap = lvm_get_blksize(snap_phys_dev); max_blksize = max(blksize_org, blksize_snap); min_blksize = min(blksize_org, blksize_snap); - max_sectors = KIO_MAX_SECTORS * (min_blksize>>9); + max_sectors = LVM_MAX_SECTORS * (min_blksize>>9); if (chunk_size % (max_blksize>>9)) goto fail_blksize; @@ -363,20 +363,20 @@ iobuf->length = nr_sectors << 9; - if(!lvm_snapshot_prepare_blocks(iobuf->blocks, org_start, + if(!lvm_snapshot_prepare_blocks(lv_snap->blocks, org_start, nr_sectors, blksize_org)) goto fail_prepare; if (brw_kiovec(READ, 1, &iobuf, org_phys_dev, - iobuf->blocks, blksize_org) != (nr_sectors<<9)) + lv_snap->blocks, blksize_org) != (nr_sectors<<9)) goto fail_raw_read; - if(!lvm_snapshot_prepare_blocks(iobuf->blocks, snap_start, + if(!lvm_snapshot_prepare_blocks(lv_snap->blocks, snap_start, nr_sectors, blksize_snap)) goto fail_prepare; if (brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev, - iobuf->blocks, blksize_snap) != (nr_sectors<<9)) + lv_snap->blocks, blksize_snap) !=(nr_sectors<<9)) goto fail_raw_write; } @@ -505,7 +505,7 @@ ret = alloc_kiovec(1, &lv_snap->lv_iobuf); if (ret) goto out; - max_sectors = KIO_MAX_SECTORS << (PAGE_SHIFT-9); + max_sectors = LVM_MAX_SECTORS << (PAGE_SHIFT-9); ret = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_iobuf, max_sectors); if (ret) goto out_free_kiovec; @@ -542,8 +542,6 @@ void lvm_snapshot_release(lv_t * lv) { - int nbhs = KIO_MAX_SECTORS; - if (lv->lv_block_exception) { vfree(lv->lv_block_exception); diff -u --recursive --new-file v2.5.0/linux/drivers/md/lvm.c linux/drivers/md/lvm.c --- v2.5.0/linux/drivers/md/lvm.c Mon Nov 19 09:56:04 2001 +++ linux/drivers/md/lvm.c Thu Nov 29 07:48:43 2001 @@ -236,7 +236,7 @@ /* * External function prototypes */ -static int lvm_make_request_fn(request_queue_t*, int, struct buffer_head*); +static int lvm_make_request_fn(request_queue_t*, struct bio *); static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong); static int lvm_blk_open(struct inode *, struct file *); @@ -262,7 +262,7 @@ #ifdef LVM_HD_NAME extern void (*lvm_hd_name_ptr) (char *, int); #endif -static int lvm_map(struct buffer_head *, int); +static int lvm_map(struct bio *); static int lvm_do_lock_lvm(void); static int lvm_do_le_remap(vg_t *, void *); @@ -291,9 +291,9 @@ static void __update_hardsectsize(lv_t *lv); -static void _queue_io(struct buffer_head *bh, int rw); -static struct buffer_head *_dequeue_io(void); -static void _flush_io(struct buffer_head *bh); +static void _queue_io(struct bio *bh, int rw); +static struct bio *_dequeue_io(void); +static void _flush_io(struct bio *bh); static int _open_pv(pv_t *pv); static void _close_pv(pv_t *pv); @@ -346,7 +346,7 @@ static spinlock_t lvm_lock = SPIN_LOCK_UNLOCKED; static spinlock_t lvm_snapshot_lock = SPIN_LOCK_UNLOCKED; -static struct buffer_head *_pe_requests; +static struct bio *_pe_requests; static DECLARE_RWSEM(_pe_lock); @@ -369,7 +369,6 @@ /* gendisk structures */ static struct hd_struct lvm_hd_struct[MAX_LV]; static int lvm_blocksizes[MAX_LV]; -static int lvm_hardsectsizes[MAX_LV]; static int lvm_size[MAX_LV]; static struct gendisk lvm_gendisk = @@ -451,9 +450,7 @@ del_gendisk(&lvm_gendisk); - blk_size[MAJOR_NR] = NULL; - blksize_size[MAJOR_NR] = NULL; - hardsect_size[MAJOR_NR] = NULL; + blk_clear(MAJOR_NR); #ifdef LVM_HD_NAME /* reference from linux/drivers/block/genhd.c */ @@ -1037,25 +1034,25 @@ static int lvm_user_bmap(struct inode *inode, struct lv_bmap *user_result) { - struct buffer_head bh; + struct bio bio; unsigned long block; int err; if (get_user(block, &user_result->lv_block)) return -EFAULT; - memset(&bh,0,sizeof bh); - bh.b_blocknr = block; - bh.b_dev = bh.b_rdev = inode->i_rdev; - bh.b_size = lvm_get_blksize(bh.b_dev); - bh.b_rsector = block * (bh.b_size >> 9); - if ((err=lvm_map(&bh, READ)) < 0) { + memset(&bio,0,sizeof(bio)); + bio.bi_dev = inode->i_rdev; + bio.bi_io_vec.bv_len = lvm_get_blksize(bio.bi_dev); + bio.bi_sector = block * bio_sectors(&bio); + bio.bi_rw = READ; + if ((err=lvm_map(&bio)) < 0) { printk("lvm map failed: %d\n", err); return -EINVAL; } - return put_user(kdev_t_to_nr(bh.b_rdev), &user_result->lv_dev) || - put_user(bh.b_rsector/(bh.b_size>>9), &user_result->lv_block) ? + return put_user(kdev_t_to_nr(bio.bi_dev), &user_result->lv_dev) || + put_user(bio.bi_sector/bio_sectors(&bio), &user_result->lv_block) ? -EFAULT : 0; } @@ -1104,7 +1101,7 @@ (sector < (pe_lock_req.data.pv_offset + pe_size))); } -static inline int _defer_extent(struct buffer_head *bh, int rw, +static inline int _defer_extent(struct bio *bh, int rw, kdev_t pv, ulong sector, uint32_t pe_size) { if (pe_lock_req.lock == LOCK_PE) { @@ -1122,17 +1119,18 @@ return 0; } -static int lvm_map(struct buffer_head *bh, int rw) +static int lvm_map(struct bio *bh) { - int minor = MINOR(bh->b_rdev); + int minor = MINOR(bh->bi_dev); ulong index; ulong pe_start; - ulong size = bh->b_size >> 9; - ulong rsector_org = bh->b_rsector; + ulong size = bio_sectors(bh); + ulong rsector_org = bh->bi_sector; ulong rsector_map; kdev_t rdev_map; vg_t *vg_this = vg[VG_BLK(minor)]; lv_t *lv = vg_this->lv[LV_BLK(minor)]; + int rw = bio_data_dir(bh); down_read(&lv->lv_lock); @@ -1153,7 +1151,7 @@ P_MAP("%s - lvm_map minor: %d *rdev: %s *rsector: %lu size:%lu\n", lvm_name, minor, - kdevname(bh->b_rdev), + kdevname(bh->bi_dev), rsector_org, size); if (rsector_org + size > lv->lv_size) { @@ -1248,13 +1246,13 @@ } out: - bh->b_rdev = rdev_map; - bh->b_rsector = rsector_map; + bh->bi_dev = rdev_map; + bh->bi_sector = rsector_map; up_read(&lv->lv_lock); return 1; bad: - buffer_IO_error(bh); + bio_io_error(bh); up_read(&lv->lv_lock); return -1; } /* lvm_map() */ @@ -1287,10 +1285,9 @@ /* * make request function */ -static int lvm_make_request_fn(request_queue_t *q, - int rw, - struct buffer_head *bh) { - return (lvm_map(bh, rw) <= 0) ? 0 : 1; +static int lvm_make_request_fn(request_queue_t *q, struct bio *bio) +{ + return (lvm_map(bio) <= 0) ? 0 : 1; } @@ -1331,7 +1328,7 @@ static int lvm_do_pe_lock_unlock(vg_t *vg_ptr, void *arg) { pe_lock_req_t new_lock; - struct buffer_head *bh; + struct bio *bh; uint p; if (vg_ptr == NULL) return -ENXIO; @@ -1820,8 +1817,6 @@ max_hardsectsize = hardsectsize; } } - - lvm_hardsectsizes[MINOR(lv->lv_dev)] = max_hardsectsize; } /* @@ -2665,7 +2660,6 @@ blk_size[MAJOR_NR] = lvm_size; blksize_size[MAJOR_NR] = lvm_blocksizes; - hardsect_size[MAJOR_NR] = lvm_hardsectsizes; return; } /* lvm_gen_init() */ @@ -2673,16 +2667,16 @@ /* Must have down_write(_pe_lock) when we enqueue buffers */ -static void _queue_io(struct buffer_head *bh, int rw) { - if (bh->b_reqnext) BUG(); - bh->b_reqnext = _pe_requests; +static void _queue_io(struct bio *bh, int rw) { + if (bh->bi_next) BUG(); + bh->bi_next = _pe_requests; _pe_requests = bh; } /* Must have down_write(_pe_lock) when we dequeue buffers */ -static struct buffer_head *_dequeue_io(void) +static struct bio *_dequeue_io(void) { - struct buffer_head *bh = _pe_requests; + struct bio *bh = _pe_requests; _pe_requests = NULL; return bh; } @@ -2697,13 +2691,14 @@ * If, for some reason, the same PE is locked again before all of these writes * have finished, then these buffers will just be re-queued (i.e. no danger). */ -static void _flush_io(struct buffer_head *bh) +static void _flush_io(struct bio *bh) { while (bh) { - struct buffer_head *next = bh->b_reqnext; - bh->b_reqnext = NULL; + struct bio *next = bh->bi_next; + bh->bi_next = NULL; /* resubmit this buffer head */ - generic_make_request(WRITE, bh); + bh->bi_rw = WRITE; /* needed? */ + generic_make_request(bh); bh = next; } } diff -u --recursive --new-file v2.5.0/linux/drivers/md/md.c linux/drivers/md/md.c --- v2.5.0/linux/drivers/md/md.c Thu Oct 25 13:58:34 2001 +++ linux/drivers/md/md.c Tue Dec 11 13:47:35 2001 @@ -105,7 +105,6 @@ */ struct hd_struct md_hd_struct[MAX_MD_DEVS]; static int md_blocksizes[MAX_MD_DEVS]; -static int md_hardsect_sizes[MAX_MD_DEVS]; static int md_maxreadahead[MAX_MD_DEVS]; static mdk_thread_t *md_recovery_thread; @@ -131,7 +130,7 @@ /* * Enables to iterate over all existing md arrays */ -static MD_LIST_HEAD(all_mddevs); +static LIST_HEAD(all_mddevs); /* * The mapping between kdev and mddev is not necessary a simple @@ -172,14 +171,14 @@ mddev_map[minor].data = NULL; } -static int md_make_request(request_queue_t *q, int rw, struct buffer_head * bh) +static int md_make_request (request_queue_t *q, struct bio *bio) { - mddev_t *mddev = kdev_to_mddev(bh->b_rdev); + mddev_t *mddev = kdev_to_mddev(bio->bi_dev); if (mddev && mddev->pers) - return mddev->pers->make_request(mddev, rw, bh); + return mddev->pers->make_request(mddev, bio_rw(bio), bio); else { - buffer_IO_error(bh); + bio_io_error(bio); return 0; } } @@ -202,8 +201,8 @@ init_MUTEX(&mddev->reconfig_sem); init_MUTEX(&mddev->recovery_sem); init_MUTEX(&mddev->resync_sem); - MD_INIT_LIST_HEAD(&mddev->disks); - MD_INIT_LIST_HEAD(&mddev->all_mddevs); + INIT_LIST_HEAD(&mddev->disks); + INIT_LIST_HEAD(&mddev->all_mddevs); atomic_set(&mddev->active, 0); /* @@ -212,7 +211,7 @@ * if necessary. */ add_mddev_mapping(mddev, dev, 0); - md_list_add(&mddev->all_mddevs, &all_mddevs); + list_add(&mddev->all_mddevs, &all_mddevs); MOD_INC_USE_COUNT; @@ -222,7 +221,7 @@ mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) { mdk_rdev_t * rdev; - struct md_list_head *tmp; + struct list_head *tmp; ITERATE_RDEV(mddev,rdev,tmp) { if (rdev->desc_nr == nr) @@ -233,7 +232,7 @@ mdk_rdev_t * find_rdev(mddev_t * mddev, kdev_t dev) { - struct md_list_head *tmp; + struct list_head *tmp; mdk_rdev_t *rdev; ITERATE_RDEV(mddev,rdev,tmp) { @@ -243,17 +242,17 @@ return NULL; } -static MD_LIST_HEAD(device_names); +static LIST_HEAD(device_names); char * partition_name(kdev_t dev) { struct gendisk *hd; static char nomem [] = ""; dev_name_t *dname; - struct md_list_head *tmp = device_names.next; + struct list_head *tmp = device_names.next; while (tmp != &device_names) { - dname = md_list_entry(tmp, dev_name_t, list); + dname = list_entry(tmp, dev_name_t, list); if (dname->dev == dev) return dname->name; tmp = tmp->next; @@ -276,8 +275,8 @@ } dname->dev = dev; - MD_INIT_LIST_HEAD(&dname->list); - md_list_add(&dname->list, &device_names); + INIT_LIST_HEAD(&dname->list); + list_add(&dname->list, &device_names); return dname->name; } @@ -312,7 +311,7 @@ { unsigned int mask; mdk_rdev_t * rdev; - struct md_list_head *tmp; + struct list_head *tmp; if (!mddev->sb) { MD_BUG(); @@ -342,7 +341,7 @@ { int i, c; mdk_rdev_t *rdev; - struct md_list_head *tmp; + struct list_head *tmp; /* * First, all devices must be fully functional @@ -436,7 +435,7 @@ mddev->sb = (mdp_super_t *) __get_free_page (GFP_KERNEL); if (!mddev->sb) return -ENOMEM; - md_clear_page(mddev->sb); + clear_page(mddev->sb); return 0; } @@ -450,7 +449,7 @@ printk(OUT_OF_MEM); return -EINVAL; } - md_clear_page(rdev->sb); + clear_page(rdev->sb); return 0; } @@ -565,7 +564,7 @@ static mdk_rdev_t * match_dev_unit(mddev_t *mddev, kdev_t dev) { - struct md_list_head *tmp; + struct list_head *tmp; mdk_rdev_t *rdev; ITERATE_RDEV(mddev,rdev,tmp) @@ -577,7 +576,7 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2) { - struct md_list_head *tmp; + struct list_head *tmp; mdk_rdev_t *rdev; ITERATE_RDEV(mddev1,rdev,tmp) @@ -587,8 +586,8 @@ return 0; } -static MD_LIST_HEAD(all_raid_disks); -static MD_LIST_HEAD(pending_raid_disks); +static LIST_HEAD(all_raid_disks); +static LIST_HEAD(pending_raid_disks); static void bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) { @@ -606,7 +605,7 @@ mdidx(mddev), partition_name(rdev->dev), partition_name(same_pdev->dev)); - md_list_add(&rdev->same_set, &mddev->disks); + list_add(&rdev->same_set, &mddev->disks); rdev->mddev = mddev; mddev->nb_dev++; printk(KERN_INFO "md: bind<%s,%d>\n", partition_name(rdev->dev), mddev->nb_dev); @@ -618,8 +617,8 @@ MD_BUG(); return; } - md_list_del(&rdev->same_set); - MD_INIT_LIST_HEAD(&rdev->same_set); + list_del(&rdev->same_set); + INIT_LIST_HEAD(&rdev->same_set); rdev->mddev->nb_dev--; printk(KERN_INFO "md: unbind<%s,%d>\n", partition_name(rdev->dev), rdev->mddev->nb_dev); @@ -665,13 +664,13 @@ MD_BUG(); unlock_rdev(rdev); free_disk_sb(rdev); - md_list_del(&rdev->all); - MD_INIT_LIST_HEAD(&rdev->all); + list_del(&rdev->all); + INIT_LIST_HEAD(&rdev->all); if (rdev->pending.next != &rdev->pending) { printk(KERN_INFO "md: (%s was pending)\n", partition_name(rdev->dev)); - md_list_del(&rdev->pending); - MD_INIT_LIST_HEAD(&rdev->pending); + list_del(&rdev->pending); + INIT_LIST_HEAD(&rdev->pending); } #ifndef MODULE md_autodetect_dev(rdev->dev); @@ -689,7 +688,7 @@ static void export_array(mddev_t *mddev) { - struct md_list_head *tmp; + struct list_head *tmp; mdk_rdev_t *rdev; mdp_super_t *sb = mddev->sb; @@ -724,14 +723,14 @@ * Make sure nobody else is using this mddev * (careful, we rely on the global kernel lock here) */ - while (md_atomic_read(&mddev->resync_sem.count) != 1) + while (atomic_read(&mddev->resync_sem.count) != 1) schedule(); - while (md_atomic_read(&mddev->recovery_sem.count) != 1) + while (atomic_read(&mddev->recovery_sem.count) != 1) schedule(); del_mddev_mapping(mddev, MKDEV(MD_MAJOR, mdidx(mddev))); - md_list_del(&mddev->all_mddevs); - MD_INIT_LIST_HEAD(&mddev->all_mddevs); + list_del(&mddev->all_mddevs); + INIT_LIST_HEAD(&mddev->all_mddevs); kfree(mddev); MOD_DEC_USE_COUNT; } @@ -794,7 +793,7 @@ void md_print_devices(void) { - struct md_list_head *tmp, *tmp2; + struct list_head *tmp, *tmp2; mdk_rdev_t *rdev; mddev_t *mddev; @@ -872,12 +871,12 @@ static mdk_rdev_t * find_rdev_all(kdev_t dev) { - struct md_list_head *tmp; + struct list_head *tmp; mdk_rdev_t *rdev; tmp = all_raid_disks.next; while (tmp != &all_raid_disks) { - rdev = md_list_entry(tmp, mdk_rdev_t, all); + rdev = list_entry(tmp, mdk_rdev_t, all); if (rdev->dev == dev) return rdev; tmp = tmp->next; @@ -981,7 +980,7 @@ { mdk_rdev_t *rdev; mdp_super_t *sb; - struct md_list_head *tmp; + struct list_head *tmp; ITERATE_RDEV(mddev,rdev,tmp) { if (rdev->faulty || rdev->alias_device) @@ -997,15 +996,15 @@ int md_update_sb(mddev_t * mddev) { int err, count = 100; - struct md_list_head *tmp; + struct list_head *tmp; mdk_rdev_t *rdev; repeat: mddev->sb->utime = CURRENT_TIME; - if ((++mddev->sb->events_lo)==0) + if (!(++mddev->sb->events_lo)) ++mddev->sb->events_hi; - if ((mddev->sb->events_lo|mddev->sb->events_hi)==0) { + if (!(mddev->sb->events_lo | mddev->sb->events_hi)) { /* * oops, this 64-bit counter should never wrap. * Either we are in around ~1 trillion A.C., assuming @@ -1129,8 +1128,8 @@ rdev->desc_nr = -1; } } - md_list_add(&rdev->all, &all_raid_disks); - MD_INIT_LIST_HEAD(&rdev->pending); + list_add(&rdev->all, &all_raid_disks); + INIT_LIST_HEAD(&rdev->pending); if (rdev->faulty && rdev->sb) free_disk_sb(rdev); @@ -1168,7 +1167,7 @@ static int analyze_sbs(mddev_t * mddev) { int out_of_date = 0, i, first; - struct md_list_head *tmp, *tmp2; + struct list_head *tmp, *tmp2; mdk_rdev_t *rdev, *rdev2, *freshest; mdp_super_t *sb; @@ -1226,7 +1225,7 @@ */ if (calc_sb_csum(rdev->sb) != rdev->sb->sb_csum) { if (rdev->sb->events_lo || rdev->sb->events_hi) - if ((rdev->sb->events_lo--)==0) + if (!(rdev->sb->events_lo--)) rdev->sb->events_hi--; } @@ -1514,7 +1513,7 @@ int data_disks = 0, persistent; unsigned int readahead; mdp_super_t *sb = mddev->sb; - struct md_list_head *tmp; + struct list_head *tmp; mdk_rdev_t *rdev; /* @@ -1573,7 +1572,7 @@ md_size[mdidx(mddev)] = sb->size * data_disks; readahead = MD_READAHEAD; - if ((sb->level == 0) || (sb->level == 4) || (sb->level == 5)) { + if (!sb->level || (sb->level == 4) || (sb->level == 5)) { readahead = (mddev->sb->chunk_size>>PAGE_SHIFT) * 4 * data_disks; if (readahead < data_disks * (MAX_SECTORS>>(PAGE_SHIFT-9))*2) readahead = data_disks * (MAX_SECTORS>>(PAGE_SHIFT-9))*2; @@ -1609,7 +1608,7 @@ { int pnum, err; int chunk_size; - struct md_list_head *tmp; + struct list_head *tmp; mdk_rdev_t *rdev; @@ -1701,19 +1700,14 @@ * device. * Also find largest hardsector size */ - md_hardsect_sizes[mdidx(mddev)] = 512; ITERATE_RDEV(mddev,rdev,tmp) { if (rdev->faulty) continue; invalidate_device(rdev->dev, 1); - if (get_hardsect_size(rdev->dev) - > md_hardsect_sizes[mdidx(mddev)]) - md_hardsect_sizes[mdidx(mddev)] = - get_hardsect_size(rdev->dev); - } - md_blocksizes[mdidx(mddev)] = 1024; - if (md_blocksizes[mdidx(mddev)] < md_hardsect_sizes[mdidx(mddev)]) - md_blocksizes[mdidx(mddev)] = md_hardsect_sizes[mdidx(mddev)]; + md_blocksizes[mdidx(mddev)] = 1024; + if (get_hardsect_size(rdev->dev) > md_blocksizes[mdidx(mddev)]) + md_blocksizes[mdidx(mddev)] = get_hardsect_size(rdev->dev); + } mddev->pers = pers[pnum]; err = mddev->pers->run(mddev); @@ -1879,7 +1873,7 @@ static void autorun_array(mddev_t *mddev) { mdk_rdev_t *rdev; - struct md_list_head *tmp; + struct list_head *tmp; int err; if (mddev->disks.prev == &mddev->disks) { @@ -1919,8 +1913,8 @@ */ static void autorun_devices(kdev_t countdev) { - struct md_list_head candidates; - struct md_list_head *tmp; + struct list_head candidates; + struct list_head *tmp; mdk_rdev_t *rdev0, *rdev; mddev_t *mddev; kdev_t md_kdev; @@ -1928,11 +1922,11 @@ printk(KERN_INFO "md: autorun ...\n"); while (pending_raid_disks.next != &pending_raid_disks) { - rdev0 = md_list_entry(pending_raid_disks.next, + rdev0 = list_entry(pending_raid_disks.next, mdk_rdev_t, pending); printk(KERN_INFO "md: considering %s ...\n", partition_name(rdev0->dev)); - MD_INIT_LIST_HEAD(&candidates); + INIT_LIST_HEAD(&candidates); ITERATE_RDEV_PENDING(rdev,tmp) { if (uuid_equal(rdev0, rdev)) { if (!sb_equal(rdev0->sb, rdev->sb)) { @@ -1942,8 +1936,8 @@ continue; } printk(KERN_INFO "md: adding %s ...\n", partition_name(rdev->dev)); - md_list_del(&rdev->pending); - md_list_add(&rdev->pending, &candidates); + list_del(&rdev->pending); + list_add(&rdev->pending, &candidates); } } /* @@ -1970,8 +1964,8 @@ printk(KERN_INFO "md: created md%d\n", mdidx(mddev)); ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp) { bind_rdev_to_array(rdev, mddev); - md_list_del(&rdev->pending); - MD_INIT_LIST_HEAD(&rdev->pending); + list_del(&rdev->pending); + INIT_LIST_HEAD(&rdev->pending); } autorun_array(mddev); } @@ -2031,7 +2025,7 @@ partition_name(startdev)); goto abort; } - md_list_add(&start_rdev->pending, &pending_raid_disks); + list_add(&start_rdev->pending, &pending_raid_disks); sb = start_rdev->sb; @@ -2064,7 +2058,7 @@ MD_BUG(); goto abort; } - md_list_add(&rdev->pending, &pending_raid_disks); + list_add(&rdev->pending, &pending_raid_disks); } /* @@ -2097,7 +2091,7 @@ ver.minor = MD_MINOR_VERSION; ver.patchlevel = MD_PATCHLEVEL_VERSION; - if (md_copy_to_user(arg, &ver, sizeof(ver))) + if (copy_to_user(arg, &ver, sizeof(ver))) return -EFAULT; return 0; @@ -2134,7 +2128,7 @@ SET_FROM_SB(layout); SET_FROM_SB(chunk_size); - if (md_copy_to_user(arg, &info, sizeof(info))) + if (copy_to_user(arg, &info, sizeof(info))) return -EFAULT; return 0; @@ -2150,7 +2144,7 @@ if (!mddev->sb) return -EINVAL; - if (md_copy_from_user(&info, arg, sizeof(info))) + if (copy_from_user(&info, arg, sizeof(info))) return -EFAULT; nr = info.number; @@ -2162,7 +2156,7 @@ SET_FROM_SB(raid_disk); SET_FROM_SB(state); - if (md_copy_to_user(arg, &info, sizeof(info))) + if (copy_to_user(arg, &info, sizeof(info))) return -EFAULT; return 0; @@ -2197,7 +2191,7 @@ return -EINVAL; } if (mddev->nb_dev) { - mdk_rdev_t *rdev0 = md_list_entry(mddev->disks.next, + mdk_rdev_t *rdev0 = list_entry(mddev->disks.next, mdk_rdev_t, same_set); if (!uuid_equal(rdev0, rdev)) { printk(KERN_WARNING "md: %s has different UUID to %s\n", @@ -2229,7 +2223,7 @@ SET_SB(raid_disk); SET_SB(state); - if ((info->state & (1<state & (1<i_rdev; @@ -2610,12 +2604,12 @@ MD_BUG(); goto abort; } - err = md_put_user(md_hd_struct[minor].nr_sects, + err = put_user(md_hd_struct[minor].nr_sects, (unsigned long *) arg); goto done; case BLKGETSIZE64: /* Return device size */ - err = md_put_user((u64)md_hd_struct[minor].nr_sects << 9, + err = put_user((u64)md_hd_struct[minor].nr_sects << 9, (u64 *) arg); goto done; @@ -2624,7 +2618,7 @@ case BLKFLSBUF: case BLKBSZGET: case BLKBSZSET: - err = blk_ioctl (dev, cmd, arg); + err = blk_ioctl(dev, cmd, arg); goto abort; default:; @@ -2676,7 +2670,7 @@ } if (arg) { mdu_array_info_t info; - if (md_copy_from_user(&info, (void*)arg, sizeof(info))) { + if (copy_from_user(&info, (void*)arg, sizeof(info))) { err = -EFAULT; goto abort_unlock; } @@ -2759,17 +2753,17 @@ err = -EINVAL; goto abort_unlock; } - err = md_put_user (2, (char *) &loc->heads); + err = put_user (2, (char *) &loc->heads); if (err) goto abort_unlock; - err = md_put_user (4, (char *) &loc->sectors); + err = put_user (4, (char *) &loc->sectors); if (err) goto abort_unlock; - err = md_put_user (md_hd_struct[mdidx(mddev)].nr_sects/8, + err = put_user (md_hd_struct[mdidx(mddev)].nr_sects/8, (short *) &loc->cylinders); if (err) goto abort_unlock; - err = md_put_user (md_hd_struct[minor].start_sect, + err = put_user (get_start_sect(dev), (long *) &loc->start); goto done_unlock; } @@ -2793,7 +2787,7 @@ case ADD_NEW_DISK: { mdu_disk_info_t info; - if (md_copy_from_user(&info, (void*)arg, sizeof(info))) + if (copy_from_user(&info, (void*)arg, sizeof(info))) err = -EFAULT; else err = add_new_disk(mddev, &info); @@ -2834,7 +2828,7 @@ { /* The data is never used.... mdu_param_t param; - err = md_copy_from_user(¶m, (mdu_param_t *)arg, + err = copy_from_user(¶m, (mdu_param_t *)arg, sizeof(param)); if (err) goto abort_unlock; @@ -2893,7 +2887,7 @@ return 0; } -static struct block_device_operations md_fops= +static struct block_device_operations md_fops = { owner: THIS_MODULE, open: md_open, @@ -2902,11 +2896,18 @@ }; +static inline void flush_curr_signals(void) +{ + spin_lock(¤t->sigmask_lock); + flush_signals(current); + spin_unlock(¤t->sigmask_lock); +} + int md_thread(void * arg) { mdk_thread_t *thread = arg; - md_lock_kernel(); + lock_kernel(); /* * Detach thread @@ -2915,8 +2916,9 @@ daemonize(); sprintf(current->comm, thread->name); - md_init_signals(); - md_flush_signals(); + current->exit_signal = SIGCHLD; + siginitsetinv(¤t->blocked, sigmask(SIGKILL)); + flush_curr_signals(); thread->tsk = current; /* @@ -2932,7 +2934,7 @@ */ current->policy = SCHED_OTHER; current->nice = -20; - md_unlock_kernel(); + unlock_kernel(); complete(thread->event); while (thread->run) { @@ -2955,8 +2957,8 @@ run(thread->data); run_task_queue(&tq_disk); } - if (md_signal_pending(current)) - md_flush_signals(); + if (signal_pending(current)) + flush_curr_signals(); } complete(thread->event); return 0; @@ -2982,7 +2984,7 @@ return NULL; memset(thread, 0, sizeof(mdk_thread_t)); - md_init_waitqueue_head(&thread->wqueue); + init_waitqueue_head(&thread->wqueue); init_completion(&event); thread->event = &event; @@ -3070,7 +3072,7 @@ { int sz = 0, i = 0; mdk_rdev_t *rdev; - struct md_list_head *tmp; + struct list_head *tmp; sz += sprintf(page + sz, "unused devices: "); @@ -3156,7 +3158,7 @@ int count, int *eof, void *data) { int sz = 0, j, size; - struct md_list_head *tmp, *tmp2; + struct list_head *tmp, *tmp2; mdk_rdev_t *rdev; mddev_t *mddev; @@ -3213,7 +3215,7 @@ if (mddev->curr_resync) { sz += status_resync (page+sz, mddev); } else { - if (md_atomic_read(&mddev->resync_sem.count) != 1) + if (atomic_read(&mddev->resync_sem.count) != 1) sz += sprintf(page + sz, " resync=DELAYED"); } sz += sprintf(page + sz, "\n"); @@ -3257,7 +3259,7 @@ mdp_super_t *sb = mddev->sb; mdp_disk_t *disk; mdk_rdev_t *rdev; - struct md_list_head *tmp; + struct list_head *tmp; ITERATE_RDEV(mddev,rdev,tmp) { if (rdev->faulty) @@ -3294,7 +3296,7 @@ static int is_mddev_idle(mddev_t *mddev) { mdk_rdev_t * rdev; - struct md_list_head *tmp; + struct list_head *tmp; int idle; unsigned long curr_events; @@ -3317,7 +3319,7 @@ return idle; } -MD_DECLARE_WAIT_QUEUE_HEAD(resync_wait); +DECLARE_WAIT_QUEUE_HEAD(resync_wait); void md_done_sync(mddev_t *mddev, int blocks, int ok) { @@ -3339,7 +3341,7 @@ unsigned long mark[SYNC_MARKS]; unsigned long mark_cnt[SYNC_MARKS]; int last_mark,m; - struct md_list_head *tmp; + struct list_head *tmp; unsigned long last_check; @@ -3362,8 +3364,8 @@ } if (serialize) { interruptible_sleep_on(&resync_wait); - if (md_signal_pending(current)) { - md_flush_signals(); + if (signal_pending(current)) { + flush_curr_signals(); err = -EINTR; goto out; } @@ -3371,8 +3373,7 @@ } mddev->curr_resync = 1; - - max_sectors = mddev->sb->size<<1; + max_sectors = mddev->sb->size << 1; printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev)); printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed: %d KB/sec/disc.\n", @@ -3409,7 +3410,6 @@ int sectors; sectors = mddev->pers->sync_request(mddev, j); - if (sectors < 0) { err = sectors; goto out; @@ -3438,13 +3438,13 @@ } - if (md_signal_pending(current)) { + if (signal_pending(current)) { /* * got a signal, exit. */ mddev->curr_resync = 0; printk(KERN_INFO "md: md_do_sync() got signal ... exiting\n"); - md_flush_signals(); + flush_curr_signals(); err = -EINTR; goto out; } @@ -3457,7 +3457,7 @@ * about not overloading the IO subsystem. (things like an * e2fsck being done on the RAID array should execute fast) */ - if (md_need_resched(current)) + if (current->need_resched) schedule(); currspeed = (j-mddev->resync_mark_cnt)/2/((jiffies-mddev->resync_mark)/HZ +1) +1; @@ -3468,7 +3468,7 @@ if ((currspeed > sysctl_speed_limit_max) || !is_mddev_idle(mddev)) { current->state = TASK_INTERRUPTIBLE; - md_schedule_timeout(HZ/4); + schedule_timeout(HZ/4); goto repeat; } } else @@ -3480,7 +3480,7 @@ * this also signals 'finished resyncing' to md_stop */ out: - wait_event(mddev->recovery_wait, atomic_read(&mddev->recovery_active)==0); + wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active)); up(&mddev->resync_sem); out_nolock: mddev->curr_resync = 0; @@ -3503,7 +3503,7 @@ mddev_t *mddev; mdp_super_t *sb; mdp_disk_t *spare; - struct md_list_head *tmp; + struct list_head *tmp; printk(KERN_INFO "md: recovery thread got woken up ...\n"); restart: @@ -3587,13 +3587,13 @@ int md_notify_reboot(struct notifier_block *this, unsigned long code, void *x) { - struct md_list_head *tmp; + struct list_head *tmp; mddev_t *mddev; - if ((code == MD_SYS_DOWN) || (code == MD_SYS_HALT) - || (code == MD_SYS_POWER_OFF)) { + if ((code == SYS_DOWN) || (code == SYS_HALT) || (code == SYS_POWER_OFF)) { printk(KERN_INFO "md: stopping all md devices.\n"); + return NOTIFY_DONE; ITERATE_MDDEV(mddev,tmp) do_md_stop (mddev, 1); @@ -3603,7 +3603,7 @@ * right place to handle this issue is the given * driver, we do want to have a safe RAID driver ... */ - md_mdelay(1000*1); + mdelay(1000*1); } return NOTIFY_DONE; } @@ -3621,13 +3621,11 @@ for(i = 0; i < MAX_MD_DEVS; i++) { md_blocksizes[i] = 1024; md_size[i] = 0; - md_hardsect_sizes[i] = 512; md_maxreadahead[i] = MD_READAHEAD; } blksize_size[MAJOR_NR] = md_blocksizes; blk_size[MAJOR_NR] = md_size; max_readahead[MAJOR_NR] = md_maxreadahead; - hardsect_size[MAJOR_NR] = md_hardsect_sizes; dprintk("md: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t)); @@ -3636,7 +3634,7 @@ #endif } -int md__init md_init(void) +int __init md_init(void) { static char * name = "mdrecoveryd"; int minor; @@ -3670,9 +3668,10 @@ md_recovery_thread = md_register_thread(md_do_recovery, NULL, name); if (!md_recovery_thread) - printk(KERN_ALERT "md: bug: couldn't allocate md_recovery_thread\n"); + printk(KERN_ALERT + "md: bug: couldn't allocate md_recovery_thread\n"); - md_register_reboot_notifier(&md_notifier); + register_reboot_notifier(&md_notifier); raid_table_header = register_sysctl_table(raid_root_table, 1); md_geninit(); @@ -3694,7 +3693,7 @@ struct { int set; int noautodetect; -} raid_setup_args md__initdata; +} raid_setup_args __initdata; /* * Searches all registered partitions for autorun RAID arrays @@ -3737,7 +3736,7 @@ MD_BUG(); continue; } - md_list_add(&rdev->pending, &pending_raid_disks); + list_add(&rdev->pending, &pending_raid_disks); } dev_cnt = 0; @@ -3749,7 +3748,7 @@ int pers[MAX_MD_DEVS]; int chunk[MAX_MD_DEVS]; char *device_names[MAX_MD_DEVS]; -} md_setup_args md__initdata; +} md_setup_args __initdata; /* * Parse the command-line parameters given our kernel, but do not @@ -3771,7 +3770,7 @@ * Shifted name_to_kdev_t() and related operations to md_set_drive() * for later execution. Rewrote section to make devfs compatible. */ -static int md__init md_setup(char *str) +static int __init md_setup(char *str) { int minor, level, factor, fault; char *pername = ""; @@ -3790,7 +3789,7 @@ } switch (get_option(&str, &level)) { /* RAID Personality */ case 2: /* could be 0 or -1.. */ - if (level == 0 || level == -1) { + if (!level || level == -1) { if (get_option(&str, &factor) != 2 || /* Chunk Size */ get_option(&str, &fault) != 2) { printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); @@ -3832,8 +3831,8 @@ return 1; } -extern kdev_t name_to_kdev_t(char *line) md__init; -void md__init md_setup_drive(void) +extern kdev_t name_to_kdev_t(char *line) __init; +void __init md_setup_drive(void) { int minor, i; kdev_t dev; @@ -3845,7 +3844,8 @@ char *devname; mdu_disk_info_t dinfo; - if ((devname = md_setup_args.device_names[minor]) == 0) continue; + if (!(devname = md_setup_args.device_names[minor])) + continue; for (i = 0; i < MD_SB_DISKS && devname != 0; i++) { @@ -3864,7 +3864,7 @@ devfs_get_maj_min(handle, &major, &minor); dev = MKDEV(major, minor); } - if (dev == 0) { + if (!dev) { printk(KERN_WARNING "md: Unknown device name: %s\n", devname); break; } @@ -3876,7 +3876,7 @@ } devices[i] = 0; - if (md_setup_args.device_set[minor] == 0) + if (!md_setup_args.device_set[minor]) continue; if (mddev_map[minor].mddev) { @@ -3940,7 +3940,7 @@ } } -static int md__init raid_setup(char *str) +static int __init raid_setup(char *str) { int len, pos; @@ -3954,7 +3954,7 @@ wlen = (comma-str)-pos; else wlen = (len-1)-pos; - if (strncmp(str, "noautodetect", wlen) == 0) + if (!strncmp(str, "noautodetect", wlen)) raid_setup_args.noautodetect = 1; pos += wlen+1; } @@ -3962,7 +3962,7 @@ return 1; } -int md__init md_run_setup(void) +int __init md_run_setup(void) { if (raid_setup_args.noautodetect) printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n"); @@ -4008,35 +4008,30 @@ #endif del_gendisk(&md_gendisk); - blk_dev[MAJOR_NR].queue = NULL; - blksize_size[MAJOR_NR] = NULL; - blk_size[MAJOR_NR] = NULL; - max_readahead[MAJOR_NR] = NULL; - hardsect_size[MAJOR_NR] = NULL; - + blk_clear(MAJOR_NR); + free_device_names(); - } #endif -MD_EXPORT_SYMBOL(md_size); -MD_EXPORT_SYMBOL(register_md_personality); -MD_EXPORT_SYMBOL(unregister_md_personality); -MD_EXPORT_SYMBOL(partition_name); -MD_EXPORT_SYMBOL(md_error); -MD_EXPORT_SYMBOL(md_do_sync); -MD_EXPORT_SYMBOL(md_sync_acct); -MD_EXPORT_SYMBOL(md_done_sync); -MD_EXPORT_SYMBOL(md_recover_arrays); -MD_EXPORT_SYMBOL(md_register_thread); -MD_EXPORT_SYMBOL(md_unregister_thread); -MD_EXPORT_SYMBOL(md_update_sb); -MD_EXPORT_SYMBOL(md_wakeup_thread); -MD_EXPORT_SYMBOL(md_print_devices); -MD_EXPORT_SYMBOL(find_rdev_nr); -MD_EXPORT_SYMBOL(md_interrupt_thread); -MD_EXPORT_SYMBOL(mddev_map); -MD_EXPORT_SYMBOL(md_check_ordering); -MD_EXPORT_SYMBOL(get_spare); +EXPORT_SYMBOL(md_size); +EXPORT_SYMBOL(register_md_personality); +EXPORT_SYMBOL(unregister_md_personality); +EXPORT_SYMBOL(partition_name); +EXPORT_SYMBOL(md_error); +EXPORT_SYMBOL(md_do_sync); +EXPORT_SYMBOL(md_sync_acct); +EXPORT_SYMBOL(md_done_sync); +EXPORT_SYMBOL(md_recover_arrays); +EXPORT_SYMBOL(md_register_thread); +EXPORT_SYMBOL(md_unregister_thread); +EXPORT_SYMBOL(md_update_sb); +EXPORT_SYMBOL(md_wakeup_thread); +EXPORT_SYMBOL(md_print_devices); +EXPORT_SYMBOL(find_rdev_nr); +EXPORT_SYMBOL(md_interrupt_thread); +EXPORT_SYMBOL(mddev_map); +EXPORT_SYMBOL(md_check_ordering); +EXPORT_SYMBOL(get_spare); diff -u --recursive --new-file v2.5.0/linux/drivers/md/raid0.c linux/drivers/md/raid0.c --- v2.5.0/linux/drivers/md/raid0.c Sun Sep 30 12:26:06 2001 +++ linux/drivers/md/raid0.c Tue Dec 11 13:47:35 2001 @@ -223,8 +223,7 @@ * Of course, those facts may not be valid anymore (and surely won't...) * Hey guys, there's some work out there ;-) */ -static int raid0_make_request (mddev_t *mddev, - int rw, struct buffer_head * bh) +static int raid0_make_request (mddev_t *mddev, int rw, struct bio *bio) { unsigned int sect_in_chunk, chunksize_bits, chunk_size; raid0_conf_t *conf = mddev_to_conf(mddev); @@ -235,11 +234,11 @@ chunk_size = mddev->param.chunk_size >> 10; chunksize_bits = ffz(~chunk_size); - block = bh->b_rsector >> 1; + block = bio->bi_sector >> 1; hash = conf->hash_table + block / conf->smallest->size; /* Sanity check */ - if (chunk_size < (block % chunk_size) + (bh->b_size >> 10)) + if (chunk_size < (block % chunk_size) + (bio->bi_size >> 10)) goto bad_map; if (!hash) @@ -255,7 +254,7 @@ } else zone = hash->zone0; - sect_in_chunk = bh->b_rsector & ((chunk_size<<1) -1); + sect_in_chunk = bio->bi_sector & ((chunk_size<<1) -1); chunk = (block - zone->zone_offset) / (zone->nb_dev << chunksize_bits); tmp_dev = zone->dev[(block >> chunksize_bits) % zone->nb_dev]; rsect = (((chunk << chunksize_bits) + zone->dev_offset)<<1) @@ -265,8 +264,8 @@ * The new BH_Lock semantics in ll_rw_blk.c guarantee that this * is the only IO operation happening on this bh. */ - bh->b_rdev = tmp_dev->dev; - bh->b_rsector = rsect; + bio->bi_dev = tmp_dev->dev; + bio->bi_sector = rsect; /* * Let the main block layer submit the IO and resolve recursion: @@ -274,7 +273,7 @@ return 1; bad_map: - printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %ld %d\n", chunk_size, bh->b_rsector, bh->b_size >> 10); + printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %ld %d\n", chunk_size, bio->bi_sector, bio->bi_size >> 10); goto outerr; bad_hash: printk("raid0_make_request bug: hash==NULL for block %ld\n", block); @@ -285,7 +284,7 @@ bad_zone1: printk ("raid0_make_request bug: hash->zone1==NULL for block %ld\n", block); outerr: - buffer_IO_error(bh); + bio_io_error(bio); return 0; } @@ -335,7 +334,7 @@ status: raid0_status, }; -static int md__init raid0_init (void) +static int __init raid0_init (void) { return register_md_personality (RAID0, &raid0_personality); } diff -u --recursive --new-file v2.5.0/linux/drivers/md/raid1.c linux/drivers/md/raid1.c --- v2.5.0/linux/drivers/md/raid1.c Wed Oct 17 14:21:00 2001 +++ linux/drivers/md/raid1.c Tue Dec 11 13:47:35 2001 @@ -1,7 +1,7 @@ /* * raid1.c : Multiple Devices driver for Linux * - * Copyright (C) 1999, 2000 Ingo Molnar, Red Hat + * Copyright (C) 1999, 2000, 2001 Ingo Molnar, Red Hat * * Copyright (C) 1996, 1997, 1998 Ingo Molnar, Miguel de Icaza, Gadi Oxman * @@ -22,330 +22,208 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include #include -#include #define MAJOR_NR MD_MAJOR #define MD_DRIVER #define MD_PERSONALITY #define MAX_WORK_PER_DISK 128 - -#define NR_RESERVED_BUFS 32 - - /* - * The following can be used to debug the driver + * Number of guaranteed r1bios in case of extreme VM load: */ -#define RAID1_DEBUG 0 - -#if RAID1_DEBUG -#define PRINTK(x...) printk(x) -#define inline -#define __inline__ -#else -#define PRINTK(x...) do { } while (0) -#endif - +#define NR_RAID1_BIOS 256 static mdk_personality_t raid1_personality; -static md_spinlock_t retry_list_lock = MD_SPIN_LOCK_UNLOCKED; -struct raid1_bh *raid1_retry_list = NULL, **raid1_retry_tail; +static spinlock_t retry_list_lock = SPIN_LOCK_UNLOCKED; +static LIST_HEAD(retry_list_head); -static struct buffer_head *raid1_alloc_bh(raid1_conf_t *conf, int cnt) +static inline void check_all_w_bios_empty(r1bio_t *r1_bio) { - /* return a linked list of "cnt" struct buffer_heads. - * don't take any off the free list unless we know we can - * get all we need, otherwise we could deadlock - */ - struct buffer_head *bh=NULL; - - while(cnt) { - struct buffer_head *t; - md_spin_lock_irq(&conf->device_lock); - if (!conf->freebh_blocked && conf->freebh_cnt >= cnt) - while (cnt) { - t = conf->freebh; - conf->freebh = t->b_next; - t->b_next = bh; - bh = t; - t->b_state = 0; - conf->freebh_cnt--; - cnt--; - } - md_spin_unlock_irq(&conf->device_lock); - if (cnt == 0) - break; - t = kmem_cache_alloc(bh_cachep, SLAB_NOIO); - if (t) { - t->b_next = bh; - bh = t; - cnt--; - } else { - PRINTK("raid1: waiting for %d bh\n", cnt); - conf->freebh_blocked = 1; - wait_disk_event(conf->wait_buffer, - !conf->freebh_blocked || - conf->freebh_cnt > conf->raid_disks * NR_RESERVED_BUFS/2); - conf->freebh_blocked = 0; - } - } - return bh; + int i; + + return; + for (i = 0; i < MD_SB_DISKS; i++) + if (r1_bio->write_bios[i]) + BUG(); } -static inline void raid1_free_bh(raid1_conf_t *conf, struct buffer_head *bh) +static inline void check_all_bios_empty(r1bio_t *r1_bio) { - unsigned long flags; - spin_lock_irqsave(&conf->device_lock, flags); - while (bh) { - struct buffer_head *t = bh; - bh=bh->b_next; - if (t->b_pprev == NULL) - kmem_cache_free(bh_cachep, t); - else { - t->b_next= conf->freebh; - conf->freebh = t; - conf->freebh_cnt++; - } - } - spin_unlock_irqrestore(&conf->device_lock, flags); - wake_up(&conf->wait_buffer); + return; + if (r1_bio->read_bio) + BUG(); + check_all_w_bios_empty(r1_bio); } -static int raid1_grow_bh(raid1_conf_t *conf, int cnt) +static void * r1bio_pool_alloc(int gfp_flags, void *data) { - /* allocate cnt buffer_heads, possibly less if kmalloc fails */ - int i = 0; + r1bio_t *r1_bio; - while (i < cnt) { - struct buffer_head *bh; - bh = kmem_cache_alloc(bh_cachep, SLAB_KERNEL); - if (!bh) break; + r1_bio = kmalloc(sizeof(r1bio_t), gfp_flags); + if (r1_bio) + memset(r1_bio, 0, sizeof(*r1_bio)); - md_spin_lock_irq(&conf->device_lock); - bh->b_pprev = &conf->freebh; - bh->b_next = conf->freebh; - conf->freebh = bh; - conf->freebh_cnt++; - md_spin_unlock_irq(&conf->device_lock); - - i++; - } - return i; + return r1_bio; } -static void raid1_shrink_bh(raid1_conf_t *conf) +static void r1bio_pool_free(void *r1_bio, void *data) { - /* discard all buffer_heads */ - - md_spin_lock_irq(&conf->device_lock); - while (conf->freebh) { - struct buffer_head *bh = conf->freebh; - conf->freebh = bh->b_next; - kmem_cache_free(bh_cachep, bh); - conf->freebh_cnt--; - } - md_spin_unlock_irq(&conf->device_lock); + check_all_bios_empty(r1_bio); + kfree(r1_bio); } - -static struct raid1_bh *raid1_alloc_r1bh(raid1_conf_t *conf) +#define RESYNC_BLOCK_SIZE (64*1024) +#define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE) +#define RESYNC_WINDOW (2048*1024) + +static void * r1buf_pool_alloc(int gfp_flags, void *data) { - struct raid1_bh *r1_bh = NULL; + conf_t *conf = data; + struct page *page; + r1bio_t *r1_bio; + struct bio *bio; + int i, j; - do { - md_spin_lock_irq(&conf->device_lock); - if (!conf->freer1_blocked && conf->freer1) { - r1_bh = conf->freer1; - conf->freer1 = r1_bh->next_r1; - conf->freer1_cnt--; - r1_bh->next_r1 = NULL; - r1_bh->state = (1 << R1BH_PreAlloc); - r1_bh->bh_req.b_state = 0; - } - md_spin_unlock_irq(&conf->device_lock); - if (r1_bh) - return r1_bh; - r1_bh = (struct raid1_bh *) kmalloc(sizeof(struct raid1_bh), GFP_NOIO); - if (r1_bh) { - memset(r1_bh, 0, sizeof(*r1_bh)); - return r1_bh; - } - conf->freer1_blocked = 1; - wait_disk_event(conf->wait_buffer, - !conf->freer1_blocked || - conf->freer1_cnt > NR_RESERVED_BUFS/2 - ); - conf->freer1_blocked = 0; - } while (1); -} - -static inline void raid1_free_r1bh(struct raid1_bh *r1_bh) -{ - struct buffer_head *bh = r1_bh->mirror_bh_list; - raid1_conf_t *conf = mddev_to_conf(r1_bh->mddev); - - r1_bh->mirror_bh_list = NULL; - - if (test_bit(R1BH_PreAlloc, &r1_bh->state)) { - unsigned long flags; - spin_lock_irqsave(&conf->device_lock, flags); - r1_bh->next_r1 = conf->freer1; - conf->freer1 = r1_bh; - conf->freer1_cnt++; - spin_unlock_irqrestore(&conf->device_lock, flags); - /* don't need to wakeup wait_buffer because - * raid1_free_bh below will do that - */ - } else { - kfree(r1_bh); - } - raid1_free_bh(conf, bh); -} + r1_bio = mempool_alloc(conf->r1bio_pool, gfp_flags); + check_all_bios_empty(r1_bio); -static int raid1_grow_r1bh (raid1_conf_t *conf, int cnt) -{ - int i = 0; + bio = bio_alloc(gfp_flags, RESYNC_PAGES); + if (!bio) + goto out_free_r1_bio; - while (i < cnt) { - struct raid1_bh *r1_bh; - r1_bh = (struct raid1_bh*)kmalloc(sizeof(*r1_bh), GFP_KERNEL); - if (!r1_bh) - break; - memset(r1_bh, 0, sizeof(*r1_bh)); - set_bit(R1BH_PreAlloc, &r1_bh->state); - r1_bh->mddev = conf->mddev; + for (i = 0; i < RESYNC_PAGES; i++) { + page = alloc_page(gfp_flags); + if (unlikely(!page)) + goto out_free_pages; - raid1_free_r1bh(r1_bh); - i++; + bio->bi_io_vec[i].bv_page = page; + bio->bi_io_vec[i].bv_len = PAGE_SIZE; + bio->bi_io_vec[i].bv_offset = 0; } - return i; -} -static void raid1_shrink_r1bh(raid1_conf_t *conf) -{ - md_spin_lock_irq(&conf->device_lock); - while (conf->freer1) { - struct raid1_bh *r1_bh = conf->freer1; - conf->freer1 = r1_bh->next_r1; - conf->freer1_cnt--; - kfree(r1_bh); - } - md_spin_unlock_irq(&conf->device_lock); -} + /* + * Allocate a single data page for this iovec. + */ + bio->bi_vcnt = RESYNC_PAGES; + bio->bi_idx = 0; + bio->bi_size = RESYNC_BLOCK_SIZE; + bio->bi_end_io = NULL; + atomic_set(&bio->bi_cnt, 1); + r1_bio->master_bio = bio; + return r1_bio; -static inline void raid1_free_buf(struct raid1_bh *r1_bh) -{ - unsigned long flags; - struct buffer_head *bh = r1_bh->mirror_bh_list; - raid1_conf_t *conf = mddev_to_conf(r1_bh->mddev); - r1_bh->mirror_bh_list = NULL; - - spin_lock_irqsave(&conf->device_lock, flags); - r1_bh->next_r1 = conf->freebuf; - conf->freebuf = r1_bh; - spin_unlock_irqrestore(&conf->device_lock, flags); - raid1_free_bh(conf, bh); +out_free_pages: + for (j = 0; j < i; j++) + __free_page(bio->bi_io_vec[j].bv_page); + bio_put(bio); +out_free_r1_bio: + mempool_free(r1_bio, conf->r1bio_pool); + return NULL; } -static struct raid1_bh *raid1_alloc_buf(raid1_conf_t *conf) +static void r1buf_pool_free(void *__r1_bio, void *data) { - struct raid1_bh *r1_bh; - - md_spin_lock_irq(&conf->device_lock); - wait_event_lock_irq(conf->wait_buffer, conf->freebuf, conf->device_lock); - r1_bh = conf->freebuf; - conf->freebuf = r1_bh->next_r1; - r1_bh->next_r1= NULL; - md_spin_unlock_irq(&conf->device_lock); + int i; + conf_t *conf = data; + r1bio_t *r1bio = __r1_bio; + struct bio *bio = r1bio->master_bio; - return r1_bh; + check_all_bios_empty(r1bio); + if (atomic_read(&bio->bi_cnt) != 1) + BUG(); + for (i = 0; i < RESYNC_PAGES; i++) { + __free_page(bio->bi_io_vec[i].bv_page); + bio->bi_io_vec[i].bv_page = NULL; + } + if (atomic_read(&bio->bi_cnt) != 1) + BUG(); + bio_put(bio); + mempool_free(r1bio, conf->r1bio_pool); } -static int raid1_grow_buffers (raid1_conf_t *conf, int cnt) +static void put_all_bios(conf_t *conf, r1bio_t *r1_bio) { - int i = 0; - - md_spin_lock_irq(&conf->device_lock); - while (i < cnt) { - struct raid1_bh *r1_bh; - struct page *page; - - page = alloc_page(GFP_KERNEL); - if (!page) - break; + int i; - r1_bh = (struct raid1_bh *) kmalloc(sizeof(*r1_bh), GFP_KERNEL); - if (!r1_bh) { - __free_page(page); - break; + if (r1_bio->read_bio) { + if (atomic_read(&r1_bio->read_bio->bi_cnt) != 1) + BUG(); + bio_put(r1_bio->read_bio); + r1_bio->read_bio = NULL; + } + for (i = 0; i < MD_SB_DISKS; i++) { + struct bio **bio = r1_bio->write_bios + i; + if (*bio) { + if (atomic_read(&(*bio)->bi_cnt) != 1) + BUG(); + bio_put(*bio); } - memset(r1_bh, 0, sizeof(*r1_bh)); - r1_bh->bh_req.b_page = page; - r1_bh->bh_req.b_data = page_address(page); - r1_bh->next_r1 = conf->freebuf; - conf->freebuf = r1_bh; - i++; + *bio = NULL; } - md_spin_unlock_irq(&conf->device_lock); - return i; + check_all_bios_empty(r1_bio); } -static void raid1_shrink_buffers (raid1_conf_t *conf) +static inline void free_r1bio(r1bio_t *r1_bio) { - md_spin_lock_irq(&conf->device_lock); - while (conf->freebuf) { - struct raid1_bh *r1_bh = conf->freebuf; - conf->freebuf = r1_bh->next_r1; - __free_page(r1_bh->bh_req.b_page); - kfree(r1_bh); - } - md_spin_unlock_irq(&conf->device_lock); + conf_t *conf = mddev_to_conf(r1_bio->mddev); + + put_all_bios(conf, r1_bio); + mempool_free(r1_bio, conf->r1bio_pool); } -static int raid1_map (mddev_t *mddev, kdev_t *rdev) +static inline void put_buf(r1bio_t *r1_bio) { - raid1_conf_t *conf = mddev_to_conf(mddev); + conf_t *conf = mddev_to_conf(r1_bio->mddev); + struct bio *bio = r1_bio->master_bio; + + /* + * undo any possible partial request fixup magic: + */ + if (bio->bi_size != RESYNC_BLOCK_SIZE) + bio->bi_io_vec[bio->bi_vcnt-1].bv_len = PAGE_SIZE; + put_all_bios(conf, r1_bio); + mempool_free(r1_bio, conf->r1buf_pool); +} + +static int map(mddev_t *mddev, kdev_t *rdev) +{ + conf_t *conf = mddev_to_conf(mddev); int i, disks = MD_SB_DISKS; /* - * Later we do read balancing on the read side + * Later we do read balancing on the read side * now we use the first available disk. */ for (i = 0; i < disks; i++) { if (conf->mirrors[i].operational) { *rdev = conf->mirrors[i].dev; - return (0); + return 0; } } printk (KERN_ERR "raid1_map(): huh, no more operational devices?\n"); - return (-1); + return -1; } -static void raid1_reschedule_retry (struct raid1_bh *r1_bh) +static void reschedule_retry(r1bio_t *r1_bio) { unsigned long flags; - mddev_t *mddev = r1_bh->mddev; - raid1_conf_t *conf = mddev_to_conf(mddev); + mddev_t *mddev = r1_bio->mddev; + conf_t *conf = mddev_to_conf(mddev); + + spin_lock_irqsave(&retry_list_lock, flags); + list_add(&r1_bio->retry_list, &retry_list_head); + spin_unlock_irqrestore(&retry_list_lock, flags); - md_spin_lock_irqsave(&retry_list_lock, flags); - if (raid1_retry_list == NULL) - raid1_retry_tail = &raid1_retry_list; - *raid1_retry_tail = r1_bh; - raid1_retry_tail = &r1_bh->next_r1; - r1_bh->next_r1 = NULL; - md_spin_unlock_irqrestore(&retry_list_lock, flags); md_wakeup_thread(conf->thread); } -static void inline io_request_done(unsigned long sector, raid1_conf_t *conf, int phase) +static void inline raid_request_done(unsigned long sector, conf_t *conf, int phase) { unsigned long flags; spin_lock_irqsave(&conf->segment_lock, flags); @@ -359,9 +237,10 @@ spin_unlock_irqrestore(&conf->segment_lock, flags); } -static void inline sync_request_done (unsigned long sector, raid1_conf_t *conf) +static void inline sync_request_done(sector_t sector, conf_t *conf) { unsigned long flags; + spin_lock_irqsave(&conf->segment_lock, flags); if (sector >= conf->start_ready) --conf->cnt_ready; @@ -375,73 +254,80 @@ } /* - * raid1_end_bh_io() is called when we have finished servicing a mirrored + * raid_end_bio_io() is called when we have finished servicing a mirrored * operation and are ready to return a success/failure code to the buffer * cache layer. */ -static void raid1_end_bh_io (struct raid1_bh *r1_bh, int uptodate) +static int raid_end_bio_io(r1bio_t *r1_bio, int uptodate, int nr_sectors) { - struct buffer_head *bh = r1_bh->master_bh; + struct bio *bio = r1_bio->master_bio; + + raid_request_done(bio->bi_sector, mddev_to_conf(r1_bio->mddev), + test_bit(R1BIO_SyncPhase, &r1_bio->state)); - io_request_done(bh->b_rsector, mddev_to_conf(r1_bh->mddev), - test_bit(R1BH_SyncPhase, &r1_bh->state)); + bio_endio(bio, uptodate, nr_sectors); + free_r1bio(r1_bio); - bh->b_end_io(bh, uptodate); - raid1_free_r1bh(r1_bh); + return 0; } -void raid1_end_request (struct buffer_head *bh, int uptodate) + +static int end_request(struct bio *bio, int nr_sectors) { - struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private); + int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); + r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); /* * this branch is our 'one mirror IO has finished' event handler: */ if (!uptodate) - md_error (r1_bh->mddev, bh->b_dev); + md_error(r1_bio->mddev, bio->bi_dev); else /* - * Set R1BH_Uptodate in our master buffer_head, so that + * Set R1BIO_Uptodate in our master bio, so that * we will return a good error code for to the higher * levels even if IO on some other mirrored buffer fails. * - * The 'master' represents the complex operation to + * The 'master' represents the complex operation to * user-side. So if something waits for IO, then it will - * wait for the 'master' buffer_head. + * wait for the 'master' bio. */ - set_bit (R1BH_Uptodate, &r1_bh->state); + set_bit(R1BIO_Uptodate, &r1_bio->state); /* - * We split up the read and write side, imho they are + * We split up the read and write side, imho they are * conceptually different. */ - if ( (r1_bh->cmd == READ) || (r1_bh->cmd == READA) ) { + if ((r1_bio->cmd == READ) || (r1_bio->cmd == READA)) { + if (!r1_bio->read_bio) + BUG(); /* - * we have only one buffer_head on the read side + * we have only one bio on the read side */ - if (uptodate) { - raid1_end_bh_io(r1_bh, uptodate); - return; + raid_end_bio_io(r1_bio, uptodate, nr_sectors); + return 0; } /* * oops, read error: */ - printk(KERN_ERR "raid1: %s: rescheduling block %lu\n", - partition_name(bh->b_dev), bh->b_blocknr); - raid1_reschedule_retry(r1_bh); - return; + printk(KERN_ERR "raid1: %s: rescheduling sector %lu\n", + partition_name(bio->bi_dev), r1_bio->sector); + reschedule_retry(r1_bio); + return 0; } + if (r1_bio->read_bio) + BUG(); /* * WRITE: * - * Let's see if all mirrored write operations have finished + * Let's see if all mirrored write operations have finished * already. */ - - if (atomic_dec_and_test(&r1_bh->remaining)) - raid1_end_bh_io(r1_bh, test_bit(R1BH_Uptodate, &r1_bh->state)); + if (atomic_dec_and_test(&r1_bio->remaining)) + raid_end_bio_io(r1_bio, uptodate, nr_sectors); + return 0; } /* @@ -456,22 +342,20 @@ * reads should be somehow balanced. */ -static int raid1_read_balance (raid1_conf_t *conf, struct buffer_head *bh) +static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio) { - int new_disk = conf->last_used; - const int sectors = bh->b_size >> 9; - const unsigned long this_sector = bh->b_rsector; - int disk = new_disk; - unsigned long new_distance; - unsigned long current_distance; - + const int sectors = bio->bi_size >> 9; + const unsigned long this_sector = r1_bio->sector; + unsigned long new_distance, current_distance; + int new_disk = conf->last_used, disk = new_disk; + /* * Check if it is sane at all to balance */ - + if (conf->resync_mirrors) goto rb_out; - + /* make sure that disk is operational */ while( !conf->mirrors[new_disk].operational) { @@ -483,7 +367,7 @@ * Nothing much to do, lets not change anything * and hope for the best... */ - + new_disk = conf->last_used; goto rb_out; @@ -491,53 +375,51 @@ } disk = new_disk; /* now disk == new_disk == starting point for search */ - + /* * Don't touch anything for sequential reads. */ - if (this_sector == conf->mirrors[new_disk].head_position) goto rb_out; - + /* * If reads have been done only on a single disk * for a time, lets give another disk a change. * This is for kicking those idling disks so that * they would find work near some hotspot. */ - if (conf->sect_count >= conf->mirrors[new_disk].sect_limit) { conf->sect_count = 0; do { - if (new_disk<=0) + if (new_disk <= 0) new_disk = conf->raid_disks; new_disk--; if (new_disk == disk) break; } while ((conf->mirrors[new_disk].write_only) || - (!conf->mirrors[new_disk].operational)); + (!conf->mirrors[new_disk].operational)); goto rb_out; } - + current_distance = abs(this_sector - conf->mirrors[disk].head_position); - + /* Find the disk which is closest */ - + do { if (disk <= 0) disk = conf->raid_disks; disk--; - + if ((conf->mirrors[disk].write_only) || (!conf->mirrors[disk].operational)) continue; - + new_distance = abs(this_sector - conf->mirrors[disk].head_position); - + if (new_distance < current_distance) { conf->sect_count = 0; current_distance = new_distance; @@ -554,69 +436,73 @@ return new_disk; } -static int raid1_make_request (mddev_t *mddev, int rw, - struct buffer_head * bh) -{ - raid1_conf_t *conf = mddev_to_conf(mddev); - struct buffer_head *bh_req, *bhl; - struct raid1_bh * r1_bh; - int disks = MD_SB_DISKS; - int i, sum_bhs = 0; - struct mirror_info *mirror; - - if (!buffer_locked(bh)) - BUG(); - /* - * make_request() can abort the operation when READA is being - * used and no empty request is available. - * - * Currently, just replace the command with READ/WRITE. + * Wait if the reconstruction state machine puts up a bar for + * new requests in this sector range: */ - if (rw == READA) - rw = READ; - - r1_bh = raid1_alloc_r1bh (conf); - +static inline void new_request(conf_t *conf, r1bio_t *r1_bio) +{ spin_lock_irq(&conf->segment_lock); wait_event_lock_irq(conf->wait_done, - bh->b_rsector < conf->start_active || - bh->b_rsector >= conf->start_future, + r1_bio->sector < conf->start_active || + r1_bio->sector >= conf->start_future, conf->segment_lock); - if (bh->b_rsector < conf->start_active) + if (r1_bio->sector < conf->start_active) conf->cnt_done++; else { conf->cnt_future++; if (conf->phase) - set_bit(R1BH_SyncPhase, &r1_bh->state); + set_bit(R1BIO_SyncPhase, &r1_bio->state); } spin_unlock_irq(&conf->segment_lock); - +} + +static int make_request(mddev_t *mddev, int rw, struct bio * bio) +{ + conf_t *conf = mddev_to_conf(mddev); + mirror_info_t *mirror; + r1bio_t *r1_bio; + struct bio *read_bio; + int i, sum_bios = 0, disks = MD_SB_DISKS; + /* - * i think the read and write branch should be separated completely, - * since we want to do read balancing on the read side for example. - * Alternative implementations? :) --mingo + * make_request() can abort the operation when READA is being + * used and no empty request is available. + * + * Currently, just replace the command with READ. */ + if (rw == READA) + rw = READ; + + r1_bio = mempool_alloc(conf->r1bio_pool, GFP_NOIO); + check_all_bios_empty(r1_bio); - r1_bh->master_bh = bh; - r1_bh->mddev = mddev; - r1_bh->cmd = rw; + r1_bio->master_bio = bio; + + r1_bio->mddev = mddev; + r1_bio->sector = bio->bi_sector; + r1_bio->cmd = rw; + + new_request(conf, r1_bio); if (rw == READ) { /* * read balancing logic: */ - mirror = conf->mirrors + raid1_read_balance(conf, bh); + mirror = conf->mirrors + read_balance(conf, bio, r1_bio); + + read_bio = bio_clone(bio, GFP_NOIO); + if (r1_bio->read_bio) + BUG(); + r1_bio->read_bio = read_bio; + + read_bio->bi_sector = r1_bio->sector; + read_bio->bi_dev = mirror->dev; + read_bio->bi_end_io = end_request; + read_bio->bi_rw = rw; + read_bio->bi_private = r1_bio; - bh_req = &r1_bh->bh_req; - memcpy(bh_req, bh, sizeof(*bh)); - bh_req->b_blocknr = bh->b_rsector; - bh_req->b_dev = mirror->dev; - bh_req->b_rdev = mirror->dev; - /* bh_req->b_rsector = bh->n_rsector; */ - bh_req->b_end_io = raid1_end_request; - bh_req->b_private = r1_bh; - generic_make_request (rw, bh_req); + generic_make_request(read_bio); return 0; } @@ -624,62 +510,35 @@ * WRITE: */ - bhl = raid1_alloc_bh(conf, conf->raid_disks); + check_all_w_bios_empty(r1_bio); + for (i = 0; i < disks; i++) { - struct buffer_head *mbh; - if (!conf->mirrors[i].operational) + struct bio *mbio; + if (!conf->mirrors[i].operational) continue; - - /* - * We should use a private pool (size depending on NR_REQUEST), - * to avoid writes filling up the memory with bhs - * - * Such pools are much faster than kmalloc anyways (so we waste - * almost nothing by not using the master bh when writing and - * win alot of cleanness) but for now we are cool enough. --mingo - * - * It's safe to sleep here, buffer heads cannot be used in a shared - * manner in the write branch. Look how we lock the buffer at the - * beginning of this function to grok the difference ;) - */ - mbh = bhl; - if (mbh == NULL) { - MD_BUG(); - break; - } - bhl = mbh->b_next; - mbh->b_next = NULL; - mbh->b_this_page = (struct buffer_head *)1; - - /* - * prepare mirrored mbh (fields ordered for max mem throughput): - */ - mbh->b_blocknr = bh->b_rsector; - mbh->b_dev = conf->mirrors[i].dev; - mbh->b_rdev = conf->mirrors[i].dev; - mbh->b_rsector = bh->b_rsector; - mbh->b_state = (1<b_count, 1); - mbh->b_size = bh->b_size; - mbh->b_page = bh->b_page; - mbh->b_data = bh->b_data; - mbh->b_list = BUF_LOCKED; - mbh->b_end_io = raid1_end_request; - mbh->b_private = r1_bh; - - mbh->b_next = r1_bh->mirror_bh_list; - r1_bh->mirror_bh_list = mbh; - sum_bhs++; - } - if (bhl) raid1_free_bh(conf,bhl); - if (!sum_bhs) { - /* Gag - all mirrors non-operational.. */ - raid1_end_bh_io(r1_bh, 0); + + mbio = bio_clone(bio, GFP_NOIO); + if (r1_bio->write_bios[i]) + BUG(); + r1_bio->write_bios[i] = mbio; + + mbio->bi_sector = r1_bio->sector; + mbio->bi_dev = conf->mirrors[i].dev; + mbio->bi_end_io = end_request; + mbio->bi_rw = rw; + mbio->bi_private = r1_bio; + + sum_bios++; + } + if (!sum_bios) { + /* + * If all mirrors are non-operational + * then return an IO error: + */ + raid_end_bio_io(r1_bio, 0, 0); return 0; } - md_atomic_set(&r1_bh->remaining, sum_bhs); + atomic_set(&r1_bio->remaining, sum_bios); /* * We have to be a bit careful about the semaphore above, thats @@ -688,28 +547,30 @@ * safer solution. Imagine, end_request decreasing the semaphore * before we could have set it up ... We could play tricks with * the semaphore (presetting it and correcting at the end if - * sum_bhs is not 'n' but we have to do end_request by hand if + * sum_bios is not 'n' but we have to do end_request by hand if * all requests finish until we had a chance to set up the * semaphore correctly ... lots of races). */ - bh = r1_bh->mirror_bh_list; - while(bh) { - struct buffer_head *bh2 = bh; - bh = bh->b_next; - generic_make_request(rw, bh2); + for (i = 0; i < disks; i++) { + struct bio *mbio; + mbio = r1_bio->write_bios[i]; + if (!mbio) + continue; + + generic_make_request(mbio); } - return (0); + return 0; } -static int raid1_status (char *page, mddev_t *mddev) +static int status(char *page, mddev_t *mddev) { - raid1_conf_t *conf = mddev_to_conf(mddev); + conf_t *conf = mddev_to_conf(mddev); int sz = 0, i; - - sz += sprintf (page+sz, " [%d/%d] [", conf->raid_disks, - conf->working_disks); + + sz += sprintf(page+sz, " [%d/%d] [", conf->raid_disks, + conf->working_disks); for (i = 0; i < conf->raid_disks; i++) - sz += sprintf (page+sz, "%s", + sz += sprintf(page+sz, "%s", conf->mirrors[i].operational ? "U" : "_"); sz += sprintf (page+sz, "]"); return sz; @@ -731,10 +592,10 @@ #define ALREADY_SYNCING KERN_INFO \ "raid1: syncing already in progress.\n" -static void mark_disk_bad (mddev_t *mddev, int failed) +static void mark_disk_bad(mddev_t *mddev, int failed) { - raid1_conf_t *conf = mddev_to_conf(mddev); - struct mirror_info *mirror = conf->mirrors+failed; + conf_t *conf = mddev_to_conf(mddev); + mirror_info_t *mirror = conf->mirrors+failed; mdp_super_t *sb = mddev->sb; mirror->operational = 0; @@ -749,37 +610,36 @@ md_wakeup_thread(conf->thread); if (!mirror->write_only) conf->working_disks--; - printk (DISK_FAILED, partition_name (mirror->dev), - conf->working_disks); + printk(DISK_FAILED, partition_name(mirror->dev), + conf->working_disks); } -static int raid1_error (mddev_t *mddev, kdev_t dev) +static int error(mddev_t *mddev, kdev_t dev) { - raid1_conf_t *conf = mddev_to_conf(mddev); - struct mirror_info * mirrors = conf->mirrors; + conf_t *conf = mddev_to_conf(mddev); + mirror_info_t * mirrors = conf->mirrors; int disks = MD_SB_DISKS; int i; - /* Find the drive. + /* + * Find the drive. * If it is not operational, then we have already marked it as dead * else if it is the last working disks, ignore the error, let the * next level up know. * else mark the drive as failed */ - for (i = 0; i < disks; i++) - if (mirrors[i].dev==dev && mirrors[i].operational) + if (mirrors[i].dev == dev && mirrors[i].operational) break; if (i == disks) return 0; - if (i < conf->raid_disks && conf->working_disks == 1) { - /* Don't fail the drive, act as though we were just a + if (i < conf->raid_disks && conf->working_disks == 1) + /* + * Don't fail the drive, act as though we were just a * normal single drive */ - return 1; - } mark_disk_bad(mddev, i); return 0; } @@ -790,41 +650,42 @@ #undef START_SYNCING -static void print_raid1_conf (raid1_conf_t *conf) +static void print_conf(conf_t *conf) { int i; - struct mirror_info *tmp; + mirror_info_t *tmp; printk("RAID1 conf printout:\n"); if (!conf) { - printk("(conf==NULL)\n"); + printk("(!conf)\n"); return; } printk(" --- wd:%d rd:%d nd:%d\n", conf->working_disks, - conf->raid_disks, conf->nr_disks); + conf->raid_disks, conf->nr_disks); for (i = 0; i < MD_SB_DISKS; i++) { tmp = conf->mirrors + i; printk(" disk %d, s:%d, o:%d, n:%d rd:%d us:%d dev:%s\n", - i, tmp->spare,tmp->operational, - tmp->number,tmp->raid_disk,tmp->used_slot, + i, tmp->spare, tmp->operational, + tmp->number, tmp->raid_disk, tmp->used_slot, partition_name(tmp->dev)); } } -static void close_sync(raid1_conf_t *conf) +static void close_sync(conf_t *conf) { mddev_t *mddev = conf->mddev; - /* If reconstruction was interrupted, we need to close the "active" and "pending" - * holes. - * we know that there are no active rebuild requests, os cnt_active == cnt_ready ==0 + /* + * If reconstruction was interrupted, we need to close the "active" + * and "pending" holes. + * we know that there are no active rebuild requests, + * os cnt_active == cnt_ready == 0 */ - /* this is really needed when recovery stops too... */ spin_lock_irq(&conf->segment_lock); conf->start_active = conf->start_pending; conf->start_ready = conf->start_pending; wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock); - conf->start_active =conf->start_ready = conf->start_pending = conf->start_future; + conf->start_active = conf->start_ready = conf->start_pending = conf->start_future; conf->start_future = mddev->sb->size+1; conf->cnt_pending = conf->cnt_future; conf->cnt_future = 0; @@ -838,18 +699,18 @@ wake_up(&conf->wait_done); } -static int raid1_diskop(mddev_t *mddev, mdp_disk_t **d, int state) +static int diskop(mddev_t *mddev, mdp_disk_t **d, int state) { int err = 0; - int i, failed_disk=-1, spare_disk=-1, removed_disk=-1, added_disk=-1; - raid1_conf_t *conf = mddev->private; - struct mirror_info *tmp, *sdisk, *fdisk, *rdisk, *adisk; + int i, failed_disk = -1, spare_disk = -1, removed_disk = -1, added_disk = -1; + conf_t *conf = mddev->private; + mirror_info_t *tmp, *sdisk, *fdisk, *rdisk, *adisk; mdp_super_t *sb = mddev->sb; mdp_disk_t *failed_desc, *spare_desc, *added_desc; mdk_rdev_t *spare_rdev, *failed_rdev; - print_raid1_conf(conf); - md_spin_lock_irq(&conf->device_lock); + print_conf(conf); + spin_lock_irq(&conf->device_lock); /* * find the disk ... */ @@ -871,7 +732,7 @@ } /* * When we activate a spare disk we _must_ have a disk in - * the lower (active) part of the array to replace. + * the lower (active) part of the array to replace. */ if ((failed_disk == -1) || (failed_disk >= conf->raid_disks)) { MD_BUG(); @@ -982,7 +843,7 @@ err = 1; goto abort; } - + if (sdisk->raid_disk != spare_disk) { MD_BUG(); err = 1; @@ -1007,13 +868,14 @@ spare_rdev = find_rdev_nr(mddev, spare_desc->number); failed_rdev = find_rdev_nr(mddev, failed_desc->number); - /* There must be a spare_rdev, but there may not be a - * failed_rdev. That slot might be empty... + /* + * There must be a spare_rdev, but there may not be a + * failed_rdev. That slot might be empty... */ spare_rdev->desc_nr = failed_desc->number; if (failed_rdev) failed_rdev->desc_nr = spare_desc->number; - + xchg_values(*spare_desc, *failed_desc); xchg_values(*fdisk, *sdisk); @@ -1024,7 +886,6 @@ * give the proper raid_disk number to the now activated * disk. (this means we switch back these values) */ - xchg_values(spare_desc->raid_disk, failed_desc->raid_disk); xchg_values(sdisk->raid_disk, fdisk->raid_disk); xchg_values(spare_desc->number, failed_desc->number); @@ -1054,7 +915,7 @@ rdisk = conf->mirrors + removed_disk; if (rdisk->spare && (removed_disk < conf->raid_disks)) { - MD_BUG(); + MD_BUG(); err = 1; goto abort; } @@ -1068,14 +929,14 @@ added_desc = *d; if (added_disk != added_desc->number) { - MD_BUG(); + MD_BUG(); err = 1; goto abort; } adisk->number = added_desc->number; adisk->raid_disk = added_desc->raid_disk; - adisk->dev = MKDEV(added_desc->major,added_desc->minor); + adisk->dev = MKDEV(added_desc->major, added_desc->minor); adisk->operational = 0; adisk->write_only = 0; @@ -1087,17 +948,18 @@ break; default: - MD_BUG(); + MD_BUG(); err = 1; goto abort; } abort: - md_spin_unlock_irq(&conf->device_lock); - if (state == DISKOP_SPARE_ACTIVE || state == DISKOP_SPARE_INACTIVE) - /* should move to "END_REBUILD" when such exists */ - raid1_shrink_buffers(conf); + spin_unlock_irq(&conf->device_lock); + if (state == DISKOP_SPARE_ACTIVE || state == DISKOP_SPARE_INACTIVE) { + mempool_destroy(conf->r1buf_pool); + conf->r1buf_pool = NULL; + } - print_raid1_conf(conf); + print_conf(conf); return err; } @@ -1108,6 +970,122 @@ #define REDIRECT_SECTOR KERN_ERR \ "raid1: %s: redirecting sector %lu to another mirror\n" +static int end_sync_read(struct bio *bio, int nr_sectors) +{ + int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); + r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); + + check_all_w_bios_empty(r1_bio); + if (r1_bio->read_bio != bio) + BUG(); + /* + * we have read a block, now it needs to be re-written, + * or re-read if the read failed. + * We don't do much here, just schedule handling by raid1d + */ + if (!uptodate) + md_error (r1_bio->mddev, bio->bi_dev); + else + set_bit(R1BIO_Uptodate, &r1_bio->state); + reschedule_retry(r1_bio); + + return 0; +} + +static int end_sync_write(struct bio *bio, int nr_sectors) +{ + int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); + r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); + mddev_t *mddev = r1_bio->mddev; + + if (!uptodate) + md_error(mddev, bio->bi_dev); + + if (atomic_dec_and_test(&r1_bio->remaining)) { + sync_request_done(r1_bio->sector, mddev_to_conf(mddev)); + md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, uptodate); + put_buf(r1_bio); + } + return 0; +} + +static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) +{ + conf_t *conf = mddev_to_conf(mddev); + int i, sum_bios = 0; + int disks = MD_SB_DISKS; + struct bio *bio, *mbio; + + bio = r1_bio->master_bio; + + /* + * have to allocate lots of bio structures and + * schedule writes + */ + if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) { + /* + * There is no point trying a read-for-reconstruct as + * reconstruct is about to be aborted + */ + printk(IO_ERROR, partition_name(bio->bi_dev), r1_bio->sector); + md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, 0); + return; + } + + check_all_w_bios_empty(r1_bio); + + for (i = 0; i < disks ; i++) { + if (!conf->mirrors[i].operational) + continue; + if (i == conf->last_used) + /* + * we read from here, no need to write + */ + continue; + if (i < conf->raid_disks && !conf->resync_mirrors) + /* + * don't need to write this we are just rebuilding + */ + continue; + + mbio = bio_clone(bio, GFP_NOIO); + if (r1_bio->write_bios[i]) + BUG(); + r1_bio->write_bios[i] = mbio; + mbio->bi_dev = conf->mirrors[i].dev; + mbio->bi_sector = r1_bio->sector; + mbio->bi_end_io = end_sync_write; + mbio->bi_rw = WRITE; + mbio->bi_private = r1_bio; + + sum_bios++; + } + if (i != disks) + BUG(); + atomic_set(&r1_bio->remaining, sum_bios); + + + if (!sum_bios) { + /* + * Nowhere to write this to... I guess we + * must be done + */ + printk(IO_ERROR, partition_name(bio->bi_dev), r1_bio->sector); + sync_request_done(r1_bio->sector, conf); + md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, 0); + put_buf(r1_bio); + return; + } + for (i = 0; i < disks ; i++) { + mbio = r1_bio->write_bios[i]; + if (!mbio) + continue; + + md_sync_acct(mbio->bi_dev, mbio->bi_size >> 9); + generic_make_request(mbio); + } +} + /* * This is a kernel thread which: * @@ -1115,134 +1093,56 @@ * 2. Updates the raid superblock when problems encounter. * 3. Performs writes following reads for array syncronising. */ -static void end_sync_write(struct buffer_head *bh, int uptodate); -static void end_sync_read(struct buffer_head *bh, int uptodate); -static void raid1d (void *data) +static void raid1d(void *data) { - struct raid1_bh *r1_bh; - struct buffer_head *bh; + struct list_head *head = &retry_list_head; + r1bio_t *r1_bio; + struct bio *bio; unsigned long flags; mddev_t *mddev; kdev_t dev; for (;;) { - md_spin_lock_irqsave(&retry_list_lock, flags); - r1_bh = raid1_retry_list; - if (!r1_bh) + spin_lock_irqsave(&retry_list_lock, flags); + if (list_empty(head)) break; - raid1_retry_list = r1_bh->next_r1; - md_spin_unlock_irqrestore(&retry_list_lock, flags); + r1_bio = list_entry(head->prev, r1bio_t, retry_list); + list_del(head->prev); + spin_unlock_irqrestore(&retry_list_lock, flags); + check_all_w_bios_empty(r1_bio); - mddev = r1_bh->mddev; + mddev = r1_bio->mddev; if (mddev->sb_dirty) { printk(KERN_INFO "raid1: dirty sb detected, updating.\n"); mddev->sb_dirty = 0; md_update_sb(mddev); } - bh = &r1_bh->bh_req; - switch(r1_bh->cmd) { + bio = r1_bio->master_bio; + switch(r1_bio->cmd) { case SPECIAL: - /* have to allocate lots of bh structures and - * schedule writes - */ - if (test_bit(R1BH_Uptodate, &r1_bh->state)) { - int i, sum_bhs = 0; - int disks = MD_SB_DISKS; - struct buffer_head *bhl, *mbh; - raid1_conf_t *conf; - - conf = mddev_to_conf(mddev); - bhl = raid1_alloc_bh(conf, conf->raid_disks); /* don't really need this many */ - for (i = 0; i < disks ; i++) { - if (!conf->mirrors[i].operational) - continue; - if (i==conf->last_used) - /* we read from here, no need to write */ - continue; - if (i < conf->raid_disks - && !conf->resync_mirrors) - /* don't need to write this, - * we are just rebuilding */ - continue; - mbh = bhl; - if (!mbh) { - MD_BUG(); - break; - } - bhl = mbh->b_next; - mbh->b_this_page = (struct buffer_head *)1; - - - /* - * prepare mirrored bh (fields ordered for max mem throughput): - */ - mbh->b_blocknr = bh->b_blocknr; - mbh->b_dev = conf->mirrors[i].dev; - mbh->b_rdev = conf->mirrors[i].dev; - mbh->b_rsector = bh->b_blocknr; - mbh->b_state = (1<b_count, 1); - mbh->b_size = bh->b_size; - mbh->b_page = bh->b_page; - mbh->b_data = bh->b_data; - mbh->b_list = BUF_LOCKED; - mbh->b_end_io = end_sync_write; - mbh->b_private = r1_bh; - - mbh->b_next = r1_bh->mirror_bh_list; - r1_bh->mirror_bh_list = mbh; - - sum_bhs++; - } - md_atomic_set(&r1_bh->remaining, sum_bhs); - if (bhl) raid1_free_bh(conf, bhl); - mbh = r1_bh->mirror_bh_list; - - if (!sum_bhs) { - /* nowhere to write this too... I guess we - * must be done - */ - sync_request_done(bh->b_blocknr, conf); - md_done_sync(mddev, bh->b_size>>9, 0); - raid1_free_buf(r1_bh); - } else - while (mbh) { - struct buffer_head *bh1 = mbh; - mbh = mbh->b_next; - generic_make_request(WRITE, bh1); - md_sync_acct(bh1->b_dev, bh1->b_size/512); - } - } else { - /* There is no point trying a read-for-reconstruct - * as reconstruct is about to be aborted - */ - - printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr); - md_done_sync(mddev, bh->b_size>>9, 0); - } - + sync_request_write(mddev, r1_bio); break; case READ: case READA: - dev = bh->b_dev; - raid1_map (mddev, &bh->b_dev); - if (bh->b_dev == dev) { - printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr); - raid1_end_bh_io(r1_bh, 0); - } else { - printk (REDIRECT_SECTOR, - partition_name(bh->b_dev), bh->b_blocknr); - bh->b_rdev = bh->b_dev; - bh->b_rsector = bh->b_blocknr; - generic_make_request (r1_bh->cmd, bh); + dev = bio->bi_dev; + map(mddev, &bio->bi_dev); + if (bio->bi_dev == dev) { + printk(IO_ERROR, partition_name(bio->bi_dev), r1_bio->sector); + raid_end_bio_io(r1_bio, 0, 0); + break; } + printk(REDIRECT_SECTOR, + partition_name(bio->bi_dev), r1_bio->sector); + bio->bi_sector = r1_bio->sector; + bio->bi_rw = r1_bio->cmd; + + generic_make_request(bio); break; } } - md_spin_unlock_irqrestore(&retry_list_lock, flags); + spin_unlock_irqrestore(&retry_list_lock, flags); } #undef IO_ERROR #undef REDIRECT_SECTOR @@ -1251,9 +1151,9 @@ * Private kernel thread to reconstruct mirrors after an unclean * shutdown. */ -static void raid1syncd (void *data) +static void raid1syncd(void *data) { - raid1_conf_t *conf = data; + conf_t *conf = data; mddev_t *mddev = conf->mddev; if (!conf->resync_mirrors) @@ -1271,7 +1171,56 @@ close_sync(conf); up(&mddev->recovery_sem); - raid1_shrink_buffers(conf); +} + +static int init_resync(conf_t *conf) +{ + int buffs; + + conf->start_active = 0; + conf->start_ready = 0; + conf->start_pending = 0; + conf->start_future = 0; + conf->phase = 0; + + buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE; + if (conf->r1buf_pool) + BUG(); + conf->r1buf_pool = mempool_create(buffs, r1buf_pool_alloc, r1buf_pool_free, conf); + if (!conf->r1buf_pool) + return -ENOMEM; + conf->window = 2048; + conf->cnt_future += conf->cnt_done+conf->cnt_pending; + conf->cnt_done = conf->cnt_pending = 0; + if (conf->cnt_ready || conf->cnt_active) + MD_BUG(); + return 0; +} + +static void wait_sync_pending(conf_t *conf, sector_t sector_nr) +{ + spin_lock_irq(&conf->segment_lock); + while (sector_nr >= conf->start_pending) { +// printk("wait .. sect=%lu start_active=%d ready=%d pending=%d future=%d, cnt_done=%d active=%d ready=%d pending=%d future=%d\n", sector_nr, conf->start_active, conf->start_ready, conf->start_pending, conf->start_future, conf->cnt_done, conf->cnt_active, conf->cnt_ready, conf->cnt_pending, conf->cnt_future); + wait_event_lock_irq(conf->wait_done, !conf->cnt_active, + conf->segment_lock); + wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, + conf->segment_lock); + conf->start_active = conf->start_ready; + conf->start_ready = conf->start_pending; + conf->start_pending = conf->start_future; + conf->start_future = conf->start_future+conf->window; + + // Note: falling off the end is not a problem + conf->phase = conf->phase ^1; + conf->cnt_active = conf->cnt_ready; + conf->cnt_ready = 0; + conf->cnt_pending = conf->cnt_future; + conf->cnt_future = 0; + wake_up(&conf->wait_done); + } + conf->cnt_ready++; + spin_unlock_irq(&conf->segment_lock); } /* @@ -1279,7 +1228,7 @@ * * We need to make sure that no normal I/O request - particularly write * requests - conflict with active sync requests. - * This is achieved by conceptually dividing the device space into a + * This is achieved by conceptually dividing the block space into a * number of sections: * DONE: 0 .. a-1 These blocks are in-sync * ACTIVE: a.. b-1 These blocks may have active sync requests, but @@ -1322,149 +1271,81 @@ * issue suitable write requests */ -static int raid1_sync_request (mddev_t *mddev, unsigned long sector_nr) +static int sync_request(mddev_t *mddev, sector_t sector_nr) { - raid1_conf_t *conf = mddev_to_conf(mddev); - struct mirror_info *mirror; - struct raid1_bh *r1_bh; - struct buffer_head *bh; - int bsize; - int disk; - int block_nr; + conf_t *conf = mddev_to_conf(mddev); + mirror_info_t *mirror; + r1bio_t *r1_bio; + struct bio *read_bio, *bio; + sector_t max_sector, nr_sectors; + int disk, partial; + + if (!sector_nr) + if (init_resync(conf)) + return -ENOMEM; - spin_lock_irq(&conf->segment_lock); - if (!sector_nr) { - /* initialize ...*/ - int buffs; - conf->start_active = 0; - conf->start_ready = 0; - conf->start_pending = 0; - conf->start_future = 0; - conf->phase = 0; - /* we want enough buffers to hold twice the window of 128*/ - buffs = 128 *2 / (PAGE_SIZE>>9); - buffs = raid1_grow_buffers(conf, buffs); - if (buffs < 2) - goto nomem; - - conf->window = buffs*(PAGE_SIZE>>9)/2; - conf->cnt_future += conf->cnt_done+conf->cnt_pending; - conf->cnt_done = conf->cnt_pending = 0; - if (conf->cnt_ready || conf->cnt_active) - MD_BUG(); - } - while (sector_nr >= conf->start_pending) { - PRINTK("wait .. sect=%lu start_active=%d ready=%d pending=%d future=%d, cnt_done=%d active=%d ready=%d pending=%d future=%d\n", - sector_nr, conf->start_active, conf->start_ready, conf->start_pending, conf->start_future, - conf->cnt_done, conf->cnt_active, conf->cnt_ready, conf->cnt_pending, conf->cnt_future); - wait_event_lock_irq(conf->wait_done, - !conf->cnt_active, - conf->segment_lock); - wait_event_lock_irq(conf->wait_ready, - !conf->cnt_pending, - conf->segment_lock); - conf->start_active = conf->start_ready; - conf->start_ready = conf->start_pending; - conf->start_pending = conf->start_future; - conf->start_future = conf->start_future+conf->window; - // Note: falling off the end is not a problem - conf->phase = conf->phase ^1; - conf->cnt_active = conf->cnt_ready; - conf->cnt_ready = 0; - conf->cnt_pending = conf->cnt_future; - conf->cnt_future = 0; - wake_up(&conf->wait_done); - } - conf->cnt_ready++; - spin_unlock_irq(&conf->segment_lock); - + wait_sync_pending(conf, sector_nr); - /* If reconstructing, and >1 working disc, + /* + * If reconstructing, and >1 working disc, * could dedicate one to rebuild and others to * service read requests .. */ disk = conf->last_used; /* make sure disk is operational */ while (!conf->mirrors[disk].operational) { - if (disk <= 0) disk = conf->raid_disks; + if (disk <= 0) + disk = conf->raid_disks; disk--; if (disk == conf->last_used) break; } conf->last_used = disk; - + mirror = conf->mirrors+conf->last_used; - - r1_bh = raid1_alloc_buf (conf); - r1_bh->master_bh = NULL; - r1_bh->mddev = mddev; - r1_bh->cmd = SPECIAL; - bh = &r1_bh->bh_req; - - block_nr = sector_nr; - bsize = 512; - while (!(block_nr & 1) && bsize < PAGE_SIZE - && (block_nr+2)*(bsize>>9) < (mddev->sb->size *2)) { - block_nr >>= 1; - bsize <<= 1; - } - bh->b_size = bsize; - bh->b_list = BUF_LOCKED; - bh->b_dev = mirror->dev; - bh->b_rdev = mirror->dev; - bh->b_state = (1<b_page) - BUG(); - if (!bh->b_data) - BUG(); - if (bh->b_data != page_address(bh->b_page)) + + r1_bio = mempool_alloc(conf->r1buf_pool, GFP_NOIO); + check_all_bios_empty(r1_bio); + + r1_bio->mddev = mddev; + r1_bio->sector = sector_nr; + r1_bio->cmd = SPECIAL; + + max_sector = mddev->sb->size << 1; + if (sector_nr >= max_sector) BUG(); - bh->b_end_io = end_sync_read; - bh->b_private = r1_bh; - bh->b_blocknr = sector_nr; - bh->b_rsector = sector_nr; - init_waitqueue_head(&bh->b_wait); - generic_make_request(READ, bh); - md_sync_acct(bh->b_dev, bh->b_size/512); + bio = r1_bio->master_bio; + nr_sectors = RESYNC_BLOCK_SIZE >> 9; + if (max_sector - sector_nr < nr_sectors) + nr_sectors = max_sector - sector_nr; + bio->bi_size = nr_sectors << 9; + bio->bi_vcnt = (bio->bi_size + PAGE_SIZE-1) / PAGE_SIZE; + /* + * Is there a partial page at the end of the request? + */ + partial = bio->bi_size % PAGE_SIZE; + if (partial) + bio->bi_io_vec[bio->bi_vcnt-1].bv_len = partial; - return (bsize >> 9); -nomem: - raid1_shrink_buffers(conf); - spin_unlock_irq(&conf->segment_lock); - return -ENOMEM; -} + read_bio = bio_clone(r1_bio->master_bio, GFP_NOIO); -static void end_sync_read(struct buffer_head *bh, int uptodate) -{ - struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private); + read_bio->bi_sector = sector_nr; + read_bio->bi_dev = mirror->dev; + read_bio->bi_end_io = end_sync_read; + read_bio->bi_rw = READ; + read_bio->bi_private = r1_bio; - /* we have read a block, now it needs to be re-written, - * or re-read if the read failed. - * We don't do much here, just schedule handling by raid1d - */ - if (!uptodate) - md_error (r1_bh->mddev, bh->b_dev); - else - set_bit(R1BH_Uptodate, &r1_bh->state); - raid1_reschedule_retry(r1_bh); -} + if (r1_bio->read_bio) + BUG(); + r1_bio->read_bio = read_bio; -static void end_sync_write(struct buffer_head *bh, int uptodate) -{ - struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private); - - if (!uptodate) - md_error (r1_bh->mddev, bh->b_dev); - if (atomic_dec_and_test(&r1_bh->remaining)) { - mddev_t *mddev = r1_bh->mddev; - unsigned long sect = bh->b_blocknr; - int size = bh->b_size; - raid1_free_buf(r1_bh); - sync_request_done(sect, mddev_to_conf(mddev)); - md_done_sync(mddev,size>>9, uptodate); - } + md_sync_acct(read_bio->bi_dev, nr_sectors); + + generic_make_request(read_bio); + + return nr_sectors; } #define INVALID_LEVEL KERN_WARNING \ @@ -1506,15 +1387,15 @@ #define START_RESYNC KERN_WARNING \ "raid1: raid set md%d not clean; reconstructing mirrors\n" -static int raid1_run (mddev_t *mddev) +static int run(mddev_t *mddev) { - raid1_conf_t *conf; + conf_t *conf; int i, j, disk_idx; - struct mirror_info *disk; + mirror_info_t *disk; mdp_super_t *sb = mddev->sb; mdp_disk_t *descriptor; mdk_rdev_t *rdev; - struct md_list_head *tmp; + struct list_head *tmp; int start_recovery = 0; MOD_INC_USE_COUNT; @@ -1525,11 +1406,10 @@ } /* * copy the already verified devices into our private RAID1 - * bookkeeping area. [whatever we allocate in raid1_run(), - * should be freed in raid1_stop()] + * bookkeeping area. [whatever we allocate in run(), + * should be freed in stop()] */ - - conf = kmalloc(sizeof(raid1_conf_t), GFP_KERNEL); + conf = kmalloc(sizeof(conf_t), GFP_KERNEL); mddev->private = conf; if (!conf) { printk(MEM_ERROR, mdidx(mddev)); @@ -1537,7 +1417,16 @@ } memset(conf, 0, sizeof(*conf)); - ITERATE_RDEV(mddev,rdev,tmp) { + conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc, + r1bio_pool_free, NULL); + if (!conf->r1bio_pool) { + printk(MEM_ERROR, mdidx(mddev)); + goto out; + } + +// for (tmp = (mddev)->disks.next; rdev = ((mdk_rdev_t *)((char *)(tmp)-(unsigned long)(&((mdk_rdev_t *)0)->same_set))), tmp = tmp->next, tmp->prev != &(mddev)->disks ; ) { + + ITERATE_RDEV(mddev, rdev, tmp) { if (rdev->faulty) { printk(ERRORS, partition_name(rdev->dev)); } else { @@ -1573,7 +1462,7 @@ continue; } if ((descriptor->number > MD_SB_DISKS) || - (disk_idx > sb->raid_disks)) { + (disk_idx > sb->raid_disks)) { printk(INCONSISTENT, partition_name(rdev->dev)); @@ -1586,7 +1475,7 @@ continue; } printk(OPERATIONAL, partition_name(rdev->dev), - disk_idx); + disk_idx); disk->number = descriptor->number; disk->raid_disk = disk_idx; disk->dev = rdev->dev; @@ -1616,10 +1505,9 @@ conf->raid_disks = sb->raid_disks; conf->nr_disks = sb->nr_disks; conf->mddev = mddev; - conf->device_lock = MD_SPIN_LOCK_UNLOCKED; + conf->device_lock = SPIN_LOCK_UNLOCKED; - conf->segment_lock = MD_SPIN_LOCK_UNLOCKED; - init_waitqueue_head(&conf->wait_buffer); + conf->segment_lock = SPIN_LOCK_UNLOCKED; init_waitqueue_head(&conf->wait_done); init_waitqueue_head(&conf->wait_ready); @@ -1628,25 +1516,8 @@ goto out_free_conf; } - - /* pre-allocate some buffer_head structures. - * As a minimum, 1 r1bh and raid_disks buffer_heads - * would probably get us by in tight memory situations, - * but a few more is probably a good idea. - * For now, try NR_RESERVED_BUFS r1bh and - * NR_RESERVED_BUFS*raid_disks bufferheads - * This will allow at least NR_RESERVED_BUFS concurrent - * reads or writes even if kmalloc starts failing - */ - if (raid1_grow_r1bh(conf, NR_RESERVED_BUFS) < NR_RESERVED_BUFS || - raid1_grow_bh(conf, NR_RESERVED_BUFS*conf->raid_disks) - < NR_RESERVED_BUFS*conf->raid_disks) { - printk(MEM_ERROR, mdidx(mddev)); - goto out_free_conf; - } - for (i = 0; i < MD_SB_DISKS; i++) { - + descriptor = sb->disks+i; disk_idx = descriptor->raid_disk; disk = conf->mirrors + disk_idx; @@ -1691,10 +1562,10 @@ } if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN)) && - (conf->working_disks > 1)) { + (conf->working_disks > 1)) { const char * name = "raid1syncd"; - conf->resync_thread = md_register_thread(raid1syncd, conf,name); + conf->resync_thread = md_register_thread(raid1syncd, conf, name); if (!conf->resync_thread) { printk(THREAD_ERROR, mdidx(mddev)); goto out_free_conf; @@ -1731,9 +1602,8 @@ return 0; out_free_conf: - raid1_shrink_r1bh(conf); - raid1_shrink_bh(conf); - raid1_shrink_buffers(conf); + if (conf->r1bio_pool) + mempool_destroy(conf->r1bio_pool); kfree(conf); mddev->private = NULL; out: @@ -1752,9 +1622,9 @@ #undef NONE_OPERATIONAL #undef ARRAY_IS_ACTIVE -static int raid1_stop_resync (mddev_t *mddev) +static int stop_resync(mddev_t *mddev) { - raid1_conf_t *conf = mddev_to_conf(mddev); + conf_t *conf = mddev_to_conf(mddev); if (conf->resync_thread) { if (conf->resync_mirrors) { @@ -1769,9 +1639,9 @@ return 0; } -static int raid1_restart_resync (mddev_t *mddev) +static int restart_resync(mddev_t *mddev) { - raid1_conf_t *conf = mddev_to_conf(mddev); + conf_t *conf = mddev_to_conf(mddev); if (conf->resync_mirrors) { if (!conf->resync_thread) { @@ -1785,46 +1655,45 @@ return 0; } -static int raid1_stop (mddev_t *mddev) +static int stop(mddev_t *mddev) { - raid1_conf_t *conf = mddev_to_conf(mddev); + conf_t *conf = mddev_to_conf(mddev); md_unregister_thread(conf->thread); if (conf->resync_thread) md_unregister_thread(conf->resync_thread); - raid1_shrink_r1bh(conf); - raid1_shrink_bh(conf); - raid1_shrink_buffers(conf); + if (conf->r1bio_pool) + mempool_destroy(conf->r1bio_pool); kfree(conf); mddev->private = NULL; MOD_DEC_USE_COUNT; return 0; } -static mdk_personality_t raid1_personality= +static mdk_personality_t raid1_personality = { name: "raid1", - make_request: raid1_make_request, - run: raid1_run, - stop: raid1_stop, - status: raid1_status, - error_handler: raid1_error, - diskop: raid1_diskop, - stop_resync: raid1_stop_resync, - restart_resync: raid1_restart_resync, - sync_request: raid1_sync_request + make_request: make_request, + run: run, + stop: stop, + status: status, + error_handler: error, + diskop: diskop, + stop_resync: stop_resync, + restart_resync: restart_resync, + sync_request: sync_request }; -static int md__init raid1_init (void) +static int __init raid_init(void) { - return register_md_personality (RAID1, &raid1_personality); + return register_md_personality(RAID1, &raid1_personality); } -static void raid1_exit (void) +static void raid_exit(void) { - unregister_md_personality (RAID1); + unregister_md_personality(RAID1); } -module_init(raid1_init); -module_exit(raid1_exit); +module_init(raid_init); +module_exit(raid_exit); MODULE_LICENSE("GPL"); diff -u --recursive --new-file v2.5.0/linux/drivers/media/video/Makefile linux/drivers/media/video/Makefile --- v2.5.0/linux/drivers/media/video/Makefile Fri Nov 9 14:01:22 2001 +++ linux/drivers/media/video/Makefile Tue Dec 11 10:06:03 2001 @@ -44,11 +44,10 @@ obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o obj-$(CONFIG_VIDEO_W9966) += w9966.o -obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o i2c-old.o obj-$(CONFIG_VIDEO_ZORAN_BUZ) += saa7111.o saa7185.o obj-$(CONFIG_VIDEO_ZORAN_DC10) += saa7110.o adv7175.o obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o -obj-$(CONFIG_VIDEO_LML33) += bt856.o bt819.o +obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o i2c-old.o obj-$(CONFIG_VIDEO_PMS) += pms.o obj-$(CONFIG_VIDEO_PLANB) += planb.o obj-$(CONFIG_VIDEO_VINO) += vino.o diff -u --recursive --new-file v2.5.0/linux/drivers/media/video/saa7146.h linux/drivers/media/video/saa7146.h --- v2.5.0/linux/drivers/media/video/saa7146.h Mon Dec 11 13:15:51 2000 +++ linux/drivers/media/video/saa7146.h Thu Dec 6 14:07:57 2001 @@ -74,7 +74,6 @@ unsigned int nr; unsigned long irq; /* IRQ used by SAA7146 card */ unsigned short id; - struct i2c_bus i2c; struct pci_dev *dev; unsigned char revision; unsigned char boardcfg[64]; /* 64 bytes of config from eeprom */ diff -u --recursive --new-file v2.5.0/linux/drivers/media/video/stradis.c linux/drivers/media/video/stradis.c --- v2.5.0/linux/drivers/media/video/stradis.c Sun Sep 30 12:26:06 2001 +++ linux/drivers/media/video/stradis.c Thu Dec 6 14:07:57 2001 @@ -45,7 +45,6 @@ #include #include #include -#include #include "saa7146.h" #include "saa7146reg.h" @@ -142,14 +141,13 @@ !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++) schedule(); } + /* read I2C */ -static int I2CRead(struct i2c_bus *bus, unsigned char addr, +static int I2CRead(struct saa7146 *saa, unsigned char addr, unsigned char subaddr, int dosub) { - struct saa7146 *saa = (struct saa7146 *) bus->data; int i; - if (saaread(SAA7146_I2C_STATUS) & 0x3c) I2CWipe(saa); for (i = 0; i < 1000 && @@ -194,17 +192,12 @@ printk("i2c read timeout\n"); return ((saaread(SAA7146_I2C_TRANSFER) >> 24) & 0xff); } -static int I2CReadOld(struct i2c_bus *bus, unsigned char addr) -{ - return I2CRead(bus, addr, 0, 0); -} /* set both to write both bytes, reset it to write only b1 */ -static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1, +static int I2CWrite(struct saa7146 *saa, unsigned char addr, unsigned char b1, unsigned char b2, int both) { - struct saa7146 *saa = (struct saa7146 *) bus->data; int i; u32 data; @@ -226,15 +219,14 @@ return 0; } -static void attach_inform(struct i2c_bus *bus, int id) +static void attach_inform(struct saa7146 *saa, int id) { - struct saa7146 *saa = (struct saa7146 *) bus->data; int i; DEBUG(printk(KERN_DEBUG "stradis%d: i2c: device found=%02x\n", saa->nr, id)); if (id == 0xa0) { /* we have rev2 or later board, fill in info */ for (i = 0; i < 64; i++) - saa->boardcfg[i] = I2CRead(bus, 0xa0, i, 1); + saa->boardcfg[i] = I2CRead(saa, 0xa0, i, 1); #ifdef USE_RESCUE_EEPROM_SDM275 if (saa->boardcfg[0] != 0) { printk("stradis%d: WARNING: EEPROM STORED VALUES HAVE BEEN IGNORED\n", saa->nr); @@ -250,35 +242,20 @@ } } -static void detach_inform(struct i2c_bus *bus, int id) +static void detach_inform(struct saa7146 *saa, int id) { - struct saa7146 *saa = (struct saa7146 *) bus->data; int i; i = saa->nr; } -static void I2CBusScan(struct i2c_bus *bus) +static void I2CBusScan(struct saa7146 *saa) { int i; for (i = 0; i < 0xff; i += 2) - if ((I2CRead(bus, i, 0, 0)) >= 0) - attach_inform(bus, i); + if ((I2CRead(saa, i, 0, 0)) >= 0) + attach_inform(saa, i); } -static struct i2c_bus saa7146_i2c_bus_template = -{ - "saa7146", - I2C_BUSID_BT848, - NULL, - SPIN_LOCK_UNLOCKED, - attach_inform, - detach_inform, - NULL, - NULL, - I2CReadOld, - I2CWrite, -}; - static int debiwait_maxwait = 0; static int wait_for_debi_done(struct saa7146 *saa) @@ -664,10 +641,8 @@ static void cs4341_setlevel(struct saa7146 *saa, int left, int right) { - I2CWrite(&(saa->i2c), 0x22, 0x03, - left > 94 ? 94 : left, 2); - I2CWrite(&(saa->i2c), 0x22, 0x04, - right > 94 ? 94 : right, 2); + I2CWrite(saa, 0x22, 0x03, left > 94 ? 94 : left, 2); + I2CWrite(saa, 0x22, 0x04, right > 94 ? 94 : right, 2); } static void initialize_cs4341(struct saa7146 *saa) @@ -676,15 +651,15 @@ for (i = 0; i < 200; i++) { /* auto mute off, power on, no de-emphasis */ /* I2S data up to 24-bit 64xFs internal SCLK */ - I2CWrite(&(saa->i2c), 0x22, 0x01, 0x11, 2); + I2CWrite(saa, 0x22, 0x01, 0x11, 2); /* ATAPI mixer settings */ - I2CWrite(&(saa->i2c), 0x22, 0x02, 0x49, 2); + I2CWrite(saa, 0x22, 0x02, 0x49, 2); /* attenuation left 3db */ - I2CWrite(&(saa->i2c), 0x22, 0x03, 0x00, 2); + I2CWrite(saa, 0x22, 0x03, 0x00, 2); /* attenuation right 3db */ - I2CWrite(&(saa->i2c), 0x22, 0x04, 0x00, 2); - I2CWrite(&(saa->i2c), 0x22, 0x01, 0x10, 2); - if (I2CRead(&(saa->i2c), 0x22, 0x02, 1) == 0x49) + I2CWrite(saa, 0x22, 0x04, 0x00, 2); + I2CWrite(saa, 0x22, 0x01, 0x10, 2); + if (I2CRead(saa, 0x22, 0x02, 1) == 0x49) break; schedule(); } @@ -701,10 +676,10 @@ else sequence = mode8420con; for (i = 0; i < INIT8420LEN; i++) - I2CWrite(&(saa->i2c), 0x20, init8420[i * 2], + I2CWrite(saa, 0x20, init8420[i * 2], init8420[i * 2 + 1], 2); for (i = 0; i < MODE8420LEN; i++) - I2CWrite(&(saa->i2c), 0x20, sequence[i * 2], + I2CWrite(saa, 0x20, sequence[i * 2], sequence[i * 2 + 1], 2); printk("stradis%d: CS8420 initialized\n", saa->nr); } @@ -722,39 +697,39 @@ for (i = 0; i < INIT7121LEN; i++) { if (NewCard) { /* handle new card encoder differences */ if (sequence[i*2] == 0x3a) - I2CWrite(&(saa->i2c), 0x88, 0x3a, 0x13, 2); + I2CWrite(saa, 0x88, 0x3a, 0x13, 2); else if (sequence[i*2] == 0x6b) - I2CWrite(&(saa->i2c), 0x88, 0x6b, 0x20, 2); + I2CWrite(saa, 0x88, 0x6b, 0x20, 2); else if (sequence[i*2] == 0x6c) - I2CWrite(&(saa->i2c), 0x88, 0x6c, + I2CWrite(saa, 0x88, 0x6c, dopal ? 0x09 : 0xf5, 2); else if (sequence[i*2] == 0x6d) - I2CWrite(&(saa->i2c), 0x88, 0x6d, + I2CWrite(saa, 0x88, 0x6d, dopal ? 0x20 : 0x00, 2); else if (sequence[i*2] == 0x7a) - I2CWrite(&(saa->i2c), 0x88, 0x7a, + I2CWrite(saa, 0x88, 0x7a, dopal ? (PALFirstActive - 1) : (NTSCFirstActive - 4), 2); else if (sequence[i*2] == 0x7b) - I2CWrite(&(saa->i2c), 0x88, 0x7b, + I2CWrite(saa, 0x88, 0x7b, dopal ? PALLastActive : NTSCLastActive, 2); - else I2CWrite(&(saa->i2c), 0x88, sequence[i * 2], + else I2CWrite(saa, 0x88, sequence[i * 2], sequence[i * 2 + 1], 2); } else { if (sequence[i*2] == 0x6b && mod) - I2CWrite(&(saa->i2c), 0x88, 0x6b, + I2CWrite(saa, 0x88, 0x6b, (sequence[i * 2 + 1] ^ 0x09), 2); else if (sequence[i*2] == 0x7a) - I2CWrite(&(saa->i2c), 0x88, 0x7a, + I2CWrite(saa, 0x88, 0x7a, dopal ? (PALFirstActive - 1) : (NTSCFirstActive - 4), 2); else if (sequence[i*2] == 0x7b) - I2CWrite(&(saa->i2c), 0x88, 0x7b, + I2CWrite(saa, 0x88, 0x7b, dopal ? PALLastActive : NTSCLastActive, 2); else - I2CWrite(&(saa->i2c), 0x88, sequence[i * 2], + I2CWrite(saa, 0x88, sequence[i * 2], sequence[i * 2 + 1], 2); } } @@ -2060,10 +2035,7 @@ if (!saa->saa7146_mem) return -EIO; - memcpy(&(saa->i2c), &saa7146_i2c_bus_template, sizeof(struct i2c_bus)); memcpy(&saa->video_dev, &saa_template, sizeof(saa_template)); - sprintf(saa->i2c.name, "stradis%d", num); - saa->i2c.data = saa; saawrite(0, SAA7146_IER); /* turn off all interrupts */ result = request_irq(saa->irq, saa7146_irq, SA_SHIRQ | SA_INTERRUPT, "stradis", (void *) saa); @@ -2082,10 +2054,6 @@ iounmap(saa->saa7146_mem); return -1; } -#if 0 - /* i2c generic interface is currently BROKEN */ - i2c_register_bus(&saa->i2c); -#endif return 0; } @@ -2176,7 +2144,7 @@ saawrite(4, SAA7146_PAGE2); /* dma direction: read, no byteswap */ saawrite(((SAA7146_MC2_UPLD_DMA2) << 16) | SAA7146_MC2_UPLD_DMA2, SAA7146_MC2); - I2CBusScan(&(saa->i2c)); + I2CBusScan(saa); return 0; } @@ -2194,10 +2162,6 @@ saawrite(0, SAA7146_MC2); saawrite(0, SAA7146_IER); saawrite(0xffffffffUL, SAA7146_ISR); -#if 0 - /* unregister i2c_bus */ - i2c_unregister_bus((&saa->i2c)); -#endif /* disable PCI bus-mastering */ pci_read_config_byte(saa->dev, PCI_COMMAND, &command); diff -u --recursive --new-file v2.5.0/linux/drivers/message/fusion/mptctl.c linux/drivers/message/fusion/mptctl.c --- v2.5.0/linux/drivers/message/fusion/mptctl.c Sun Sep 30 12:26:06 2001 +++ linux/drivers/message/fusion/mptctl.c Sun Dec 16 12:20:20 2001 @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include diff -u --recursive --new-file v2.5.0/linux/drivers/message/fusion/mptscsih.c linux/drivers/message/fusion/mptscsih.c --- v2.5.0/linux/drivers/message/fusion/mptscsih.c Sun Sep 30 12:26:06 2001 +++ linux/drivers/message/fusion/mptscsih.c Sun Dec 16 12:20:20 2001 @@ -65,7 +65,7 @@ #include #include #include -#include /* for io_request_lock (spinlock) decl */ +#include #include "../../scsi/scsi.h" #include "../../scsi/hosts.h" #include "../../scsi/sd.h" @@ -246,9 +246,9 @@ mf_chk = search_taskQ(1,sc,MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK); if (mf_chk != NULL) { sc->result = DID_ABORT << 16; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&sc->host->host_lock, flags); sc->scsi_done(sc); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&sc->host->host_lock, flags); return 1; } } @@ -426,9 +426,9 @@ scsi_to_pci_dma_dir(sc->sc_data_direction)); } - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&sc->host->host_lock, flags); sc->scsi_done(sc); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&sc->host->host_lock, flags); } return 1; @@ -928,9 +928,9 @@ } SCpnt->resid = SCpnt->request_bufflen - mpt_sdev->sense_sz; SCpnt->result = 0; -/* spin_lock(&io_request_lock); */ +/* spin_lock(&SCpnt->host->host_lock); */ SCpnt->scsi_done(SCpnt); -/* spin_unlock(&io_request_lock); */ +/* spin_unlock(&SCpnt->host->host_lock); */ return 0; } } @@ -1333,9 +1333,9 @@ if (ctx2abort == -1) { printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#2) for SCpnt=%p\n", SCpnt); SCpnt->result = DID_SOFT_ERROR << 16; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); SCpnt->scsi_done(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf); } else { dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort)); @@ -1352,9 +1352,9 @@ ": WARNING[2] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n", i, mf, SCpnt); SCpnt->result = DID_SOFT_ERROR << 16; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); SCpnt->scsi_done(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf); } } @@ -1428,9 +1428,9 @@ ": WARNING[3] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n", i, mf, SCpnt); SCpnt->result = DID_SOFT_ERROR << 16; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); SCpnt->scsi_done(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf); } @@ -1502,9 +1502,9 @@ ": WARNING[4] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n", i, mf, SCpnt); SCpnt->result = DID_SOFT_ERROR << 16; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); SCpnt->scsi_done(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf); } @@ -1748,9 +1748,9 @@ if (ctx2abort == -1) { printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#1) for SCpnt=%p\n", SCpnt); SCpnt->result = DID_SOFT_ERROR << 16; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); SCpnt->scsi_done(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf); continue; } @@ -1797,9 +1797,9 @@ != 0) { printk(KERN_WARNING MYNAM ": WARNING[1] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n", i, mf, SCpnt); SCpnt->result = DID_SOFT_ERROR << 16; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); SCpnt->scsi_done(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf); } else { /* Spin-Wait for TaskMgmt complete!!! */ diff -u --recursive --new-file v2.5.0/linux/drivers/message/fusion/mptscsih.h linux/drivers/message/fusion/mptscsih.h --- v2.5.0/linux/drivers/message/fusion/mptscsih.h Fri Jul 6 17:03:11 2001 +++ linux/drivers/message/fusion/mptscsih.h Wed Nov 28 10:22:27 2001 @@ -198,7 +198,6 @@ cmd_per_lun: MPT_SCSI_CMD_PER_LUN, \ unchecked_isa_dma: 0, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1 \ } #else diff -u --recursive --new-file v2.5.0/linux/drivers/message/i2o/i2o_block.c linux/drivers/message/i2o/i2o_block.c --- v2.5.0/linux/drivers/message/i2o/i2o_block.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/message/i2o/i2o_block.c Sun Dec 16 12:20:20 2001 @@ -114,15 +114,16 @@ #define I2O_BSA_DSC_VOLUME_CHANGED 0x000D #define I2O_BSA_DSC_TIMEOUT 0x000E +#define I2O_UNIT(dev) (i2ob_dev[MINOR((dev)) & 0xf0]) +#define I2O_LOCK(unit) (i2ob_dev[(unit)].req_queue->queue_lock) + /* * Some of these can be made smaller later */ static int i2ob_blksizes[MAX_I2OB<<4]; -static int i2ob_hardsizes[MAX_I2OB<<4]; static int i2ob_sizes[MAX_I2OB<<4]; static int i2ob_media_change_flag[MAX_I2OB]; -static u32 i2ob_max_sectors[MAX_I2OB<<4]; static int i2ob_context; @@ -252,9 +253,9 @@ unsigned long mptr; u64 offset; struct request *req = ireq->req; - struct buffer_head *bh = req->bh; + struct bio *bio = req->bio; int count = req->nr_sectors<<9; - char *last = NULL; + unsigned long last = ~0UL; unsigned short size = 0; // printk(KERN_INFO "i2ob_send called\n"); @@ -283,30 +284,30 @@ if(req->cmd == READ) { __raw_writel(I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid, msg+4); - while(bh!=NULL) + while(bio) { - if(bh->b_data == last) { - size += bh->b_size; - last += bh->b_size; - if(bh->b_reqnext) + if (bio_to_phys(bio) == last) { + size += bio->bi_size; + last += bio->bi_size; + if(bio->bi_next) __raw_writel(0x14000000|(size), mptr-8); else __raw_writel(0xD4000000|(size), mptr-8); } else { - if(bh->b_reqnext) - __raw_writel(0x10000000|(bh->b_size), mptr); + if(bio->bi_next) + __raw_writel(0x10000000|bio->bi_size, mptr); else - __raw_writel(0xD0000000|(bh->b_size), mptr); - __raw_writel(virt_to_bus(bh->b_data), mptr+4); + __raw_writel(0xD0000000|bio->bi_size, mptr); + __raw_writel(bio_to_phys(bio), mptr+4); mptr += 8; - size = bh->b_size; - last = bh->b_data + size; + size = bio->bi_size; + last = bio_to_phys(bio) + bio->bi_size; } - count -= bh->b_size; - bh = bh->b_reqnext; + count -= bio->bi_size; + bio = bio->bi_next; } /* * Heuristic for now since the block layer doesnt give @@ -322,30 +323,30 @@ else if(req->cmd == WRITE) { __raw_writel(I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid, msg+4); - while(bh!=NULL) + while(bio) { - if(bh->b_data == last) { - size += bh->b_size; - last += bh->b_size; - if(bh->b_reqnext) + if (bio_to_phys(bio) == last) { + size += bio->bi_size; + last += bio->bi_size; + if(bio->bi_next) __raw_writel(0x14000000|(size), mptr-8); else __raw_writel(0xD4000000|(size), mptr-8); } else { - if(bh->b_reqnext) - __raw_writel(0x14000000|(bh->b_size), mptr); + if(bio->bi_next) + __raw_writel(0x14000000|bio->bi_size, mptr); else - __raw_writel(0xD4000000|(bh->b_size), mptr); - __raw_writel(virt_to_bus(bh->b_data), mptr+4); + __raw_writel(0xD4000000|bio->bi_size, mptr); + __raw_writel(bio_to_phys(bio), mptr+4); mptr += 8; - size = bh->b_size; - last = bh->b_data + size; + size = bio->bi_size; + last = bio_to_phys(bio) + bio->bi_size; } - count -= bh->b_size; - bh = bh->b_reqnext; + count -= bio->bi_size; + bio = bio->bi_next; } if(c->battery) @@ -409,7 +410,8 @@ * unlocked. */ - while (end_that_request_first( req, !req->errors, "i2o block" )); + while (end_that_request_first(req, !req->errors, req->hard_cur_sectors)) + ; /* * It is now ok to complete the request. @@ -417,61 +419,6 @@ end_that_request_last( req ); } -/* - * Request merging functions - */ -static inline int i2ob_new_segment(request_queue_t *q, struct request *req, - int __max_segments) -{ - int max_segments = i2ob_dev[MINOR(req->rq_dev)].max_segments; - - if (__max_segments < max_segments) - max_segments = __max_segments; - - if (req->nr_segments < max_segments) { - req->nr_segments++; - return 1; - } - return 0; -} - -static int i2ob_back_merge(request_queue_t *q, struct request *req, - struct buffer_head *bh, int __max_segments) -{ - if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data) - return 1; - return i2ob_new_segment(q, req, __max_segments); -} - -static int i2ob_front_merge(request_queue_t *q, struct request *req, - struct buffer_head *bh, int __max_segments) -{ - if (bh->b_data + bh->b_size == req->bh->b_data) - return 1; - return i2ob_new_segment(q, req, __max_segments); -} - -static int i2ob_merge_requests(request_queue_t *q, - struct request *req, - struct request *next, - int __max_segments) -{ - int max_segments = i2ob_dev[MINOR(req->rq_dev)].max_segments; - int total_segments = req->nr_segments + next->nr_segments; - - if (__max_segments < max_segments) - max_segments = __max_segments; - - if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) - total_segments--; - - if (total_segments > max_segments) - return 0; - - req->nr_segments = total_segments; - return 1; -} - static int i2ob_flush(struct i2o_controller *c, struct i2ob_device *d, int unit) { unsigned long msg; @@ -512,12 +459,6 @@ struct i2ob_device *dev = &i2ob_dev[(unit&0xF0)]; /* - * Pull the lock over ready - */ - - spin_lock_prefetch(&io_request_lock); - - /* * FAILed message */ if(m[0] & (1<<13)) @@ -535,10 +476,10 @@ ireq=&i2ob_queues[c->unit]->request_queue[m[3]]; ireq->req->errors++; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&I2O_LOCK(c->unit), flags); i2ob_unhook_request(ireq, c->unit); i2ob_end_request(ireq->req); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags); /* Now flush the message by making it a NOP */ m[0]&=0x00FFFFFF; @@ -559,12 +500,12 @@ if(msg->function == I2O_CMD_BLOCK_CFLUSH) { - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&I2O_LOCK(c->unit), flags); dev->constipated=0; DEBUG(("unconstipated\n")); if(i2ob_backlog_request(c, dev)==0) i2ob_request(dev->req_queue); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags); return; } @@ -580,10 +521,10 @@ ireq=&i2ob_queues[c->unit]->request_queue[m[3]]; ireq->req->errors++; printk(KERN_WARNING "I2O Block: Data transfer to deleted device!\n"); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&I2O_LOCK(c->unit), flags); i2ob_unhook_request(ireq, c->unit); i2ob_end_request(ireq->req); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags); return; } @@ -629,7 +570,7 @@ */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&I2O_LOCK(c->unit), flags); if(err==4) { /* @@ -674,7 +615,7 @@ */ i2ob_request(dev->req_queue); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags); /* * and out @@ -682,7 +623,7 @@ return; } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags); printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name, bsa_errors[m[4]&0XFFFF]); if(m[4]&0x00FF0000) @@ -697,8 +638,8 @@ * Dequeue the request. We use irqsave locks as one day we * may be running polled controllers from a BH... */ - - spin_lock_irqsave(&io_request_lock, flags); + + spin_lock_irqsave(&I2O_LOCK(c->unit), flags); i2ob_unhook_request(ireq, c->unit); i2ob_end_request(ireq->req); atomic_dec(&i2ob_queues[c->unit]->queue_depth); @@ -710,7 +651,7 @@ if(i2ob_backlog_request(c, dev)==0) i2ob_request(dev->req_queue); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags); } /* @@ -789,8 +730,7 @@ for(i = unit; i <= unit+15; i++) { i2ob_sizes[i] = 0; - i2ob_hardsizes[i] = 0; - i2ob_max_sectors[i] = 0; + blk_queue_max_sectors(i2ob_dev[i].req_queue, 0); i2ob[i].nr_sects = 0; i2ob_gendisk.part[i].nr_sects = 0; } @@ -824,11 +764,11 @@ if(i2ob_query_device(&i2ob_dev[unit], 0x0004, 0, &size, 8) !=0 ) i2ob_query_device(&i2ob_dev[unit], 0x0000, 4, &size, 8); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&I2O_LOCK(unit), flags); i2ob_sizes[unit] = (int)(size>>10); i2ob_gendisk.part[unit].nr_sects = size>>9; i2ob[unit].nr_sects = (int)(size>>9); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&I2O_LOCK(unit), flags); break; } @@ -881,13 +821,14 @@ static void i2ob_timer_handler(unsigned long q) { + request_queue_t *req_queue = (request_queue_t *) q; unsigned long flags; /* * We cannot touch the request queue or the timer - * flag without holding the io_request_lock. + * flag without holding the queue_lock */ - spin_lock_irqsave(&io_request_lock,flags); + spin_lock_irqsave(&req_queue->queue_lock,flags); /* * Clear the timer started flag so that @@ -898,12 +839,12 @@ /* * Restart any requests. */ - i2ob_request((request_queue_t*)q); + i2ob_request(req_queue); /* * Free the lock. */ - spin_unlock_irqrestore(&io_request_lock,flags); + spin_unlock_irqrestore(&req_queue->queue_lock,flags); } static int i2ob_backlog_request(struct i2o_controller *c, struct i2ob_device *dev) @@ -1132,34 +1073,23 @@ static int i2ob_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct i2ob_device *dev; - int minor; - /* Anyone capable of this syscall can do *real bad* things */ if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!inode) + if (!inode || !inode->i_rdev) return -EINVAL; - minor = MINOR(inode->i_rdev); - if (minor >= (MAX_I2OB<<4)) - return -ENODEV; - dev = &i2ob_dev[minor]; switch (cmd) { - case BLKGETSIZE: - return put_user(i2ob[minor].nr_sects, (long *) arg); - case BLKGETSIZE64: - return put_user((u64)i2ob[minor].nr_sects << 9, (u64 *)arg); - case HDIO_GETGEO: { struct hd_geometry g; - int u=minor&0xF0; + int u = MINOR(inode->i_rdev) & 0xF0; i2o_block_biosparam(i2ob_sizes[u]<<1, &g.cylinders, &g.heads, &g.sectors); - g.start = i2ob[minor].start_sect; - return copy_to_user((void *)arg,&g, sizeof(g))?-EFAULT:0; + g.start = get_start_sect(inode->i_rdev); + return copy_to_user((void *)arg, &g, sizeof(g)) + ? -EFAULT : 0; } case BLKRRPART: @@ -1167,6 +1097,8 @@ return -EACCES; return do_i2ob_revalidate(inode->i_rdev,1); + case BLKGETSIZE: + case BLKGETSIZE64: case BLKFLSBUF: case BLKROSET: case BLKROGET: @@ -1354,8 +1286,6 @@ i2ob_query_device(dev, 0x0000, 5, &flags, 4); i2ob_query_device(dev, 0x0000, 6, &status, 4); i2ob_sizes[unit] = (int)(size>>10); - for(i=unit; i <= unit+15 ; i++) - i2ob_hardsizes[i] = blocksize; i2ob_gendisk.part[unit].nr_sects = size>>9; i2ob[unit].nr_sects = (int)(size>>9); @@ -1366,26 +1296,30 @@ /* * Max number of Scatter-Gather Elements */ - for(i=unit;i<=unit+15;i++) { - i2ob_max_sectors[i] = 256; - i2ob_dev[i].max_segments = (d->controller->status_block->inbound_frame_size - 8)/2; + request_queue_t *q = i2ob_dev[unit].req_queue; + + blk_queue_max_sectors(q, 256); + blk_queue_max_phys_segments(q, (d->controller->status_block->inbound_frame_size - 8)/2); + blk_queue_max_hw_segments(q, (d->controller->status_block->inbound_frame_size - 8)/2); if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy == 2) i2ob_dev[i].depth = 32; if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy == 1) { - i2ob_max_sectors[i] = 32; - i2ob_dev[i].max_segments = 8; + blk_queue_max_sectors(q, 32); + blk_queue_max_phys_segments(q, 8); + blk_queue_max_hw_segments(q, 8); i2ob_dev[i].depth = 4; } if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.short_req) { - i2ob_max_sectors[i] = 8; - i2ob_dev[i].max_segments = 8; + blk_queue_max_sectors(q, 8); + blk_queue_max_phys_segments(q, 8); + blk_queue_max_hw_segments(q, 8); } } @@ -1430,7 +1364,7 @@ } printk(".\n"); printk(KERN_INFO "%s: Maximum sectors/read set to %d.\n", - d->dev_name, i2ob_max_sectors[unit]); + d->dev_name, i2ob_dev[unit].req_queue->max_sectors); /* * If this is the first I2O block device found on this IOP, @@ -1450,7 +1384,7 @@ */ dev->req_queue = &i2ob_queues[c->unit]->req_queue; - grok_partitions(&i2ob_gendisk, unit>>4, 1<<4, (long)(size>>9)); + grok_partitions(MKDEV(MAJOR_NR, unit), (long)(size>>9)); /* * Register for the events we're interested in and that the @@ -1492,10 +1426,6 @@ atomic_set(&i2ob_queues[unit]->queue_depth, 0); blk_init_queue(&i2ob_queues[unit]->req_queue, i2ob_request); - blk_queue_headactive(&i2ob_queues[unit]->req_queue, 0); - i2ob_queues[unit]->req_queue.back_merge_fn = i2ob_back_merge; - i2ob_queues[unit]->req_queue.front_merge_fn = i2ob_front_merge; - i2ob_queues[unit]->req_queue.merge_requests_fn = i2ob_merge_requests; i2ob_queues[unit]->req_queue.queuedata = &i2ob_queues[unit]; return 0; @@ -1506,11 +1436,11 @@ */ static request_queue_t* i2ob_get_queue(kdev_t dev) { - int unit = MINOR(dev)&0xF0; - - return i2ob_dev[unit].req_queue; + return I2O_UNIT(dev).req_queue; } + + /* * Probe the I2O subsytem for block class devices */ @@ -1708,7 +1638,7 @@ int i = 0; unsigned long flags; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&I2O_LOCK(c->unit), flags); /* * Need to do this...we somtimes get two events from the IRTOS @@ -1730,7 +1660,7 @@ if(unit >= MAX_I2OB<<4) { printk(KERN_ERR "i2ob_del_device called, but not in dev table!\n"); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags); return; } @@ -1743,12 +1673,11 @@ { i2ob_dev[i].i2odev = NULL; i2ob_sizes[i] = 0; - i2ob_hardsizes[i] = 0; - i2ob_max_sectors[i] = 0; + blk_queue_max_sectors(i2ob_dev[i].req_queue, 0); i2ob[i].nr_sects = 0; i2ob_gendisk.part[i].nr_sects = 0; } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags); /* * Decrease usage count for module @@ -1891,13 +1820,10 @@ */ blksize_size[MAJOR_NR] = i2ob_blksizes; - hardsect_size[MAJOR_NR] = i2ob_hardsizes; blk_size[MAJOR_NR] = i2ob_sizes; - max_sectors[MAJOR_NR] = i2ob_max_sectors; blk_dev[MAJOR_NR].queue = i2ob_get_queue; blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), i2ob_request); - blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); for (i = 0; i < MAX_I2OB << 4; i++) { i2ob_dev[i].refcnt = 0; @@ -1909,7 +1835,6 @@ i2ob_dev[i].tail = NULL; i2ob_dev[i].depth = MAX_I2OB_DEPTH; i2ob_blksizes[i] = 1024; - i2ob_max_sectors[i] = 2; } /* @@ -1977,7 +1902,6 @@ MODULE_AUTHOR("Red Hat Software"); MODULE_DESCRIPTION("I2O Block Device OSM"); MODULE_LICENSE("GPL"); - void cleanup_module(void) { diff -u --recursive --new-file v2.5.0/linux/drivers/message/i2o/i2o_config.c linux/drivers/message/i2o/i2o_config.c --- v2.5.0/linux/drivers/message/i2o/i2o_config.c Mon Oct 22 08:39:56 2001 +++ linux/drivers/message/i2o/i2o_config.c Fri Nov 30 08:26:04 2001 @@ -847,7 +847,6 @@ struct i2o_cfg_info *p1, *p2; unsigned long flags; - lock_kernel(); p1 = p2 = NULL; spin_lock_irqsave(&i2o_config_lock, flags); @@ -870,7 +869,6 @@ p1 = p1->next; } spin_unlock_irqrestore(&i2o_config_lock, flags); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/message/i2o/i2o_core.c linux/drivers/message/i2o/i2o_core.c --- v2.5.0/linux/drivers/message/i2o/i2o_core.c Mon Oct 22 08:39:56 2001 +++ linux/drivers/message/i2o/i2o_core.c Tue Nov 27 09:23:27 2001 @@ -125,6 +125,7 @@ * Function table to send to bus specific layers * See for explanation of this */ +#ifdef CONFIG_I2O_PCI_MODULE static struct i2o_core_func_table i2o_core_functions = { i2o_install_controller, @@ -135,7 +136,6 @@ i2o_delete_controller }; -#ifdef CONFIG_I2O_PCI_MODULE extern int i2o_pci_core_attach(struct i2o_core_func_table *); extern void i2o_pci_core_detach(void); #endif /* CONFIG_I2O_PCI_MODULE */ diff -u --recursive --new-file v2.5.0/linux/drivers/message/i2o/i2o_scsi.c linux/drivers/message/i2o/i2o_scsi.c --- v2.5.0/linux/drivers/message/i2o/i2o_scsi.c Mon Oct 22 08:39:56 2001 +++ linux/drivers/message/i2o/i2o_scsi.c Wed Nov 28 08:49:22 2001 @@ -151,11 +151,10 @@ static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg) { Scsi_Cmnd *current_command; + spinlock_t *lock; u32 *m = (u32 *)msg; u8 as,ds,st; - spin_lock_prefetch(&io_request_lock); - if(m[0] & (1<<13)) { printk("IOP fail.\n"); @@ -190,12 +189,13 @@ { /* Create a scsi error for this */ current_command = (Scsi_Cmnd *)m[3]; + lock = ¤t_command->host->host_lock; printk("Aborted %ld\n", current_command->serial_number); - spin_lock_irq(&io_request_lock); + spin_lock_irq(lock); current_command->result = DID_ERROR << 16; current_command->scsi_done(current_command); - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(lock); /* Now flush the message by making it a NOP */ m[0]&=0x00FFFFFF; @@ -284,9 +284,10 @@ * It worked maybe ? */ current_command->result = DID_OK << 16 | ds; - spin_lock(&io_request_lock); + lock = ¤t_command->host->host_lock; + spin_lock(lock); current_command->scsi_done(current_command); - spin_unlock(&io_request_lock); + spin_unlock(lock); return; } diff -u --recursive --new-file v2.5.0/linux/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c --- v2.5.0/linux/drivers/mtd/ftl.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/mtd/ftl.c Tue Nov 27 09:23:27 2001 @@ -1166,7 +1166,7 @@ put_user(1, (char *)&geo->heads); put_user(8, (char *)&geo->sectors); put_user((sect>>3), (short *)&geo->cylinders); - put_user(ftl_hd[minor].start_sect, (u_long *)&geo->start); + put_user(get_start_sect(inode->i_rdev), (u_long *)&geo->start); break; case BLKGETSIZE: ret = put_user(ftl_hd[minor].nr_sects, (unsigned long *)arg); @@ -1206,42 +1206,27 @@ ======================================================================*/ -static int ftl_reread_partitions(int minor) +static int ftl_reread_partitions(kdev_t dev) { + int minor = MINOR(dev); partition_t *part = myparts[minor >> 4]; - int i, whole; + int res; DEBUG(0, "ftl_cs: ftl_reread_partition(%d)\n", minor); if ((atomic_read(&part->open) > 1)) { return -EBUSY; } - whole = minor & ~(MAX_PART-1); - i = MAX_PART - 1; - while (i-- > 0) { - if (ftl_hd[whole+i].nr_sects > 0) { - kdev_t rdev = MKDEV(FTL_MAJOR, whole+i); - - invalidate_device(rdev, 1); - } - ftl_hd[whole+i].start_sect = 0; - ftl_hd[whole+i].nr_sects = 0; - } + res = wipe_partitions(dev); + if (res) + goto leave; scan_header(part); register_disk(&ftl_gendisk, whole >> PART_BITS, MAX_PART, &ftl_blk_fops, le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE); -#ifdef PCMCIA_DEBUG - for (i = 0; i < MAX_PART; i++) { - if (ftl_hd[whole+i].nr_sects > 0) - printk(KERN_INFO " %d: start %ld size %ld\n", i, - ftl_hd[whole+i].start_sect, - ftl_hd[whole+i].nr_sects); - } -#endif - return 0; + return res; } /*====================================================================== @@ -1431,7 +1416,7 @@ unregister_blkdev(FTL_MAJOR, "ftl"); blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR)); - blksize_size[FTL_MAJOR] = NULL; + bklk_clear(FTL_MAJOR); del_gendisk(&ftl_gendisk); } diff -u --recursive --new-file v2.5.0/linux/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c --- v2.5.0/linux/drivers/mtd/mtdblock.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/mtd/mtdblock.c Tue Nov 27 09:23:27 2001 @@ -29,7 +29,7 @@ #if LINUX_VERSION_CODE < 0x20300 #define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync) #else -#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged) +#define QUEUE_PLUGGED (blk_queue_plugged(QUEUE)) #endif #ifdef CONFIG_DEVFS_FS @@ -402,7 +402,7 @@ /* * This is a special request_fn because it is executed in a process context - * to be able to sleep independently of the caller. The io_request_lock + * to be able to sleep independently of the caller. The queue_lock * is held upon entry and exit. * The head of our request queue is considered active so there is no need * to dequeue requests before we are done. @@ -416,7 +416,7 @@ for (;;) { INIT_REQUEST; req = CURRENT; - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&QUEUE->queue_lock); mtdblk = mtdblks[MINOR(req->rq_dev)]; res = 0; @@ -458,7 +458,7 @@ } end_req: - spin_lock_irq(&io_request_lock); + spin_lock_irq(&QUEUE->queue_lock); end_request(res); } } @@ -490,16 +490,16 @@ while (!leaving) { add_wait_queue(&thr_wq, &wait); set_current_state(TASK_INTERRUPTIBLE); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&QUEUE->queue_lock); if (QUEUE_EMPTY || QUEUE_PLUGGED) { - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&QUEUE->queue_lock); schedule(); remove_wait_queue(&thr_wq, &wait); } else { remove_wait_queue(&thr_wq, &wait); set_current_state(TASK_RUNNING); handle_mtdblock_request(); - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&QUEUE->queue_lock); } } diff -u --recursive --new-file v2.5.0/linux/drivers/mtd/nftlcore.c linux/drivers/mtd/nftlcore.c --- v2.5.0/linux/drivers/mtd/nftlcore.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/mtd/nftlcore.c Tue Nov 27 09:23:27 2001 @@ -59,11 +59,6 @@ /* .. for the Linux partition table handling. */ struct hd_struct part_table[256]; -#if LINUX_VERSION_CODE < 0x20328 -static void dummy_init (struct gendisk *crap) -{} -#endif - static struct gendisk nftl_gendisk = { major: MAJOR_NR, major_name: "nftl", @@ -166,7 +161,8 @@ #if LINUX_VERSION_CODE < 0x20328 resetup_one_dev(&nftl_gendisk, firstfree); #else - grok_partitions(&nftl_gendisk, firstfree, 1<nr_sects); + grok_partitions(MKDEV(MAJOR_NR,firstfree<nr_sects); #endif } @@ -786,7 +782,7 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { struct NFTLrecord *nftl; - int p; + int res; nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS]; @@ -799,16 +795,9 @@ g.heads = nftl->heads; g.sectors = nftl->sectors; g.cylinders = nftl->cylinders; - g.start = part_table[MINOR(inode->i_rdev)].start_sect; + g.start = get_start_sect(inode->i_rdev); return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0; } - case BLKGETSIZE: /* Return device size */ - return put_user(part_table[MINOR(inode->i_rdev)].nr_sects, - (unsigned long *) arg); - case BLKGETSIZE64: - return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9, - (u64 *)arg); - case BLKFLSBUF: if (!capable(CAP_SYS_ADMIN)) return -EACCES; fsync_dev(inode->i_rdev); @@ -825,27 +814,17 @@ * or we won't be able to re-use the partitions, * if there was a change and we don't want to reboot */ - p = (1< 0) { - kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p); - if (part_table[p].nr_sects > 0) - invalidate_device (devp, 1); + res = wipe_partitions(inode->i_rdev); + if (!res) + grok_partitions(inode->i_rdev, nftl->nr_sects); - part_table[MINOR(inode->i_dev)+p].start_sect = 0; - part_table[MINOR(inode->i_dev)+p].nr_sects = 0; - } - -#if LINUX_VERSION_CODE < 0x20328 - resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS); -#else - grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS, - 1<nr_sects); -#endif - return 0; + return res; #if (LINUX_VERSION_CODE < 0x20303) RO_IOCTLS(inode->i_rdev, arg); /* ref. linux/blk.h */ #else + case BLKGETSIZE: + case BLKGETSIZE64: case BLKROSET: case BLKROGET: case BLKSSZGET: @@ -859,7 +838,7 @@ void nftl_request(RQFUNC_ARG) { - unsigned int dev, block, nsect; + unsigned int dev, unit, block, nsect; struct NFTLrecord *nftl; char *buffer; struct request *req; @@ -871,10 +850,11 @@ /* We can do this because the generic code knows not to touch the request at the head of the queue */ - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&QUEUE->queue_lock); DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n"); - DEBUG(MTD_DEBUG_LEVEL3, "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n", + DEBUG(MTD_DEBUG_LEVEL3, + "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n", (req->cmd == READ) ? "Read " : "Write", req->sector, req->current_nr_sectors); @@ -884,8 +864,8 @@ buffer = req->buffer; res = 1; /* succeed */ - if (dev >= MAX_NFTLS * (1<> NFTL_PARTN_BITS; + if (unit >= MAX_NFTLS || dev != (unit << NFTL_PARTN_BITS)) { printk("nftl: bad minor number: device = %s\n", kdevname(req->rq_dev)); res = 0; /* fail */ @@ -906,8 +886,6 @@ goto repeat; } - block += part_table[dev].start_sect; - if (req->cmd == READ) { DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request of 0x%x sectors @ %x " "(req->nr_sectors == %lx)\n", nsect, block, req->nr_sectors); @@ -953,7 +931,7 @@ } repeat: DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&QUEUE->queue_lock); end_request(res); } } diff -u --recursive --new-file v2.5.0/linux/drivers/net/3c509.c linux/drivers/net/3c509.c --- v2.5.0/linux/drivers/net/3c509.c Sun Sep 30 12:26:06 2001 +++ linux/drivers/net/3c509.c Sun Nov 25 09:43:42 2001 @@ -175,7 +175,7 @@ }; #endif /* CONFIG_MCA */ -#if defined(CONFIG_ISAPNP) || defined(CONFIG_ISAPNP_MODULE) +#ifdef __ISAPNP__ static struct isapnp_device_id el3_isapnp_adapters[] __initdata = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5090), @@ -206,7 +206,7 @@ static u16 el3_isapnp_phys_addr[8][3]; -#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */ +#endif /* __ISAPNP__ */ static int nopnp; int __init el3_probe(struct net_device *dev) @@ -217,9 +217,9 @@ u16 phys_addr[3]; static int current_tag; int mca_slot = -1; -#if defined(CONFIG_ISAPNP) || defined(CONFIG_ISAPNP_MODULE) +#ifdef __ISAPNP__ static int pnp_cards; -#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */ +#endif /* __ISAPNP__ */ if (dev) SET_MODULE_OWNER(dev); @@ -323,7 +323,7 @@ } #endif /* CONFIG_MCA */ -#if defined(CONFIG_ISAPNP) || defined(CONFIG_ISAPNP_MODULE) +#ifdef __ISAPNP__ if (nopnp == 1) goto no_pnp; @@ -359,7 +359,7 @@ } } no_pnp: -#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */ +#endif /* __ISAPNP__ */ /* Select an open I/O location at 0x1*0 to do contention select. */ for ( ; id_port < 0x200; id_port += 0x10) { @@ -405,7 +405,7 @@ phys_addr[i] = htons(id_read_eeprom(i)); } -#if defined(CONFIG_ISAPNP) || defined(CONFIG_ISAPNP_MODULE) +#ifdef __ISAPNP__ if (nopnp == 0) { /* The ISA PnP 3c509 cards respond to the ID sequence. This check is needed in order not to register them twice. */ @@ -425,7 +425,7 @@ } } } -#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */ +#endif /* __ISAPNP__ */ { unsigned int iobase = id_read_eeprom(8); @@ -1017,10 +1017,10 @@ MODULE_PARM_DESC(irq, "EtherLink III IRQ number(s) (assigned)"); MODULE_PARM_DESC(xcvr,"EtherLink III tranceiver(s) (0=internal, 1=external)"); MODULE_PARM_DESC(max_interrupt_work, "EtherLink III maximum events handled per interrupt"); -#ifdef CONFIG_ISAPNP +#ifdef __ISAPNP__ MODULE_PARM(nopnp, "i"); MODULE_PARM_DESC(nopnp, "EtherLink III disable ISA PnP support (0-1)"); -#endif /* CONFIG_ISAPNP */ +#endif /* __ISAPNP__ */ int init_module(void) diff -u --recursive --new-file v2.5.0/linux/drivers/net/3c515.c linux/drivers/net/3c515.c --- v2.5.0/linux/drivers/net/3c515.c Sun Sep 30 12:26:06 2001 +++ linux/drivers/net/3c515.c Sun Nov 25 09:43:42 2001 @@ -359,7 +359,7 @@ { "Default", 0, 0xFF, XCVR_10baseT, 10000}, }; -#ifdef CONFIG_ISAPNP +#ifdef __ISAPNP__ static struct isapnp_device_id corkscrew_isapnp_adapters[] = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5051), @@ -372,7 +372,7 @@ static int corkscrew_isapnp_phys_addr[3]; static int nopnp; -#endif /* CONFIG_ISAPNP */ +#endif /* __ISAPNP__ */ static int corkscrew_scan(struct net_device *dev); static struct net_device *corkscrew_found_device(struct net_device *dev, @@ -450,12 +450,12 @@ { int cards_found = 0; static int ioaddr; -#ifdef CONFIG_ISAPNP +#ifdef __ISAPNP__ short i; static int pnp_cards; #endif -#ifdef CONFIG_ISAPNP +#ifdef __ISAPNP__ if(nopnp == 1) goto no_pnp; for(i=0; corkscrew_isapnp_adapters[i].vendor != 0; i++) { @@ -513,17 +513,17 @@ } } no_pnp: -#endif /* CONFIG_ISAPNP */ +#endif /* __ISAPNP__ */ /* Check all locations on the ISA bus -- evil! */ for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) { int irq; -#ifdef CONFIG_ISAPNP +#ifdef __ISAPNP__ /* Make sure this was not already picked up by isapnp */ if(ioaddr == corkscrew_isapnp_phys_addr[0]) continue; if(ioaddr == corkscrew_isapnp_phys_addr[1]) continue; if(ioaddr == corkscrew_isapnp_phys_addr[2]) continue; -#endif /* CONFIG_ISAPNP */ +#endif /* __ISAPNP__ */ if (check_region(ioaddr, CORKSCREW_TOTAL_SIZE)) continue; /* Check the resource configuration for a matching ioaddr. */ diff -u --recursive --new-file v2.5.0/linux/drivers/net/8139too.c linux/drivers/net/8139too.c --- v2.5.0/linux/drivers/net/8139too.c Fri Nov 9 13:45:35 2001 +++ linux/drivers/net/8139too.c Sat Nov 24 11:26:37 2001 @@ -1270,6 +1270,7 @@ tp->full_duplex = tp->duplex_lock; tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000; tp->twistie = 1; + tp->time_to_die = 0; rtl8139_init_ring (dev); rtl8139_hw_start (dev); diff -u --recursive --new-file v2.5.0/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.5.0/linux/drivers/net/Config.in Mon Nov 19 15:19:42 2001 +++ linux/drivers/net/Config.in Mon Dec 10 11:17:40 2001 @@ -159,7 +159,8 @@ dep_tristate ' Apricot Xen-II on board Ethernet' CONFIG_APRICOT $CONFIG_ISA dep_tristate ' CS89x0 support' CONFIG_CS89x0 $CONFIG_ISA - dep_tristate ' DECchip Tulip (dc21x4x) PCI support' CONFIG_TULIP $CONFIG_PCI + dep_tristate ' Early DECchip Tulip (dc2104x) PCI support (EXPERIMENTAL)' CONFIG_DE2104X $CONFIG_PCI $CONFIG_EXPERIMENTAL + dep_tristate ' DECchip Tulip (dc2114x) PCI support' CONFIG_TULIP $CONFIG_PCI if [ "$CONFIG_TULIP" = "y" -o "$CONFIG_TULIP" = "m" ]; then dep_bool ' New bus configuration (EXPERIMENTAL)' CONFIG_TULIP_MWI $CONFIG_EXPERIMENTAL bool ' Use PCI shared mem for NIC registers' CONFIG_TULIP_MMIO diff -u --recursive --new-file v2.5.0/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.5.0/linux/drivers/net/Makefile Fri Oct 19 08:32:28 2001 +++ linux/drivers/net/Makefile Mon Dec 10 11:17:40 2001 @@ -174,6 +174,7 @@ obj-$(CONFIG_EWRK3) += ewrk3.o obj-$(CONFIG_ATP) += atp.o obj-$(CONFIG_DE4X5) += de4x5.o +obj-$(CONFIG_DE2104X) += de2104x.o obj-$(CONFIG_NI5010) += ni5010.o obj-$(CONFIG_NI52) += ni52.o obj-$(CONFIG_NI65) += ni65.o diff -u --recursive --new-file v2.5.0/linux/drivers/net/de2104x.c linux/drivers/net/de2104x.c --- v2.5.0/linux/drivers/net/de2104x.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/de2104x.c Mon Dec 10 11:17:40 2001 @@ -0,0 +1,2141 @@ +/* de2104x.c: A Linux PCI Ethernet driver for Intel/Digital 21040/1 chips. */ +/* + Copyright 2001 Jeff Garzik + + Copyright 1994, 1995 Digital Equipment Corporation. [de4x5.c] + Written/copyright 1994-2001 by Donald Becker. [tulip.c] + + This software may be used and distributed according to the terms of + the GNU General Public License (GPL), incorporated herein by reference. + Drivers based on or derived from this code fall under the GPL and must + retain the authorship, copyright and license notice. This file is not + a complete program and may only be used when the entire operating + system is licensed under the GPL. + + See the file COPYING in this distribution for more information. + + TODO, in rough priority order: + * Support forcing media type with a module parameter, + like dl2k.c/sundance.c + * Constants (module parms?) for Rx work limit + * Complete reset on PciErr + * Jumbo frames / dev->change_mtu + * Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error + * Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error + * Implement Tx software interrupt mitigation via + Tx descriptor bit + + */ + +#define DRV_NAME "de2104x" +#define DRV_VERSION "0.5.1" +#define DRV_RELDATE "Nov 20, 2001" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* These identify the driver base version and may not be removed. */ +static char version[] __initdata = +KERN_INFO DRV_NAME " PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n"; + +MODULE_AUTHOR("Jeff Garzik "); +MODULE_DESCRIPTION("Intel/Digital 21040/1 series PCI Ethernet driver"); +MODULE_LICENSE("GPL"); + +static int debug = -1; +MODULE_PARM (debug, "i"); +MODULE_PARM_DESC (debug, "de2104x bitmapped message enable number"); + +/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */ +#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \ + || defined(__sparc_) || defined(__ia64__) \ + || defined(__sh__) || defined(__mips__) +static int rx_copybreak = 1518; +#else +static int rx_copybreak = 100; +#endif +MODULE_PARM (rx_copybreak, "i"); +MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copied"); + +#define PFX DRV_NAME ": " + +#define DE_DEF_MSG_ENABLE (NETIF_MSG_DRV | \ + NETIF_MSG_PROBE | \ + NETIF_MSG_LINK | \ + NETIF_MSG_TIMER | \ + NETIF_MSG_IFDOWN | \ + NETIF_MSG_IFUP | \ + NETIF_MSG_RX_ERR | \ + NETIF_MSG_TX_ERR) + +#define DE_RX_RING_SIZE 64 +#define DE_TX_RING_SIZE 64 +#define DE_RING_BYTES \ + ((sizeof(struct de_desc) * DE_RX_RING_SIZE) + \ + (sizeof(struct de_desc) * DE_TX_RING_SIZE)) +#define NEXT_TX(N) (((N) + 1) & (DE_TX_RING_SIZE - 1)) +#define NEXT_RX(N) (((N) + 1) & (DE_RX_RING_SIZE - 1)) +#define TX_BUFFS_AVAIL(CP) \ + (((CP)->tx_tail <= (CP)->tx_head) ? \ + (CP)->tx_tail + (DE_TX_RING_SIZE - 1) - (CP)->tx_head : \ + (CP)->tx_tail - (CP)->tx_head - 1) + +#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ +#define RX_OFFSET 2 + +#define DE_SETUP_SKB ((struct sk_buff *) 1) +#define DE_DUMMY_SKB ((struct sk_buff *) 2) +#define DE_SETUP_FRAME_WORDS 96 +#define DE_EEPROM_WORDS 256 +#define DE_MAX_MEDIA 5 + +#define DE_MEDIA_TP_AUTO 0 +#define DE_MEDIA_BNC 1 +#define DE_MEDIA_AUI 2 +#define DE_MEDIA_TP 3 +#define DE_MEDIA_TP_FD 4 +#define DE_MEDIA_INVALID DE_MAX_MEDIA +#define DE_MEDIA_FIRST 0 +#define DE_MEDIA_LAST (DE_MAX_MEDIA - 1) +#define DE_TIMER_LINK (60 * HZ) +#define DE_TIMER_NO_LINK (5 * HZ) + +#define DE_NUM_REGS 16 +#define DE_REGS_SIZE (DE_NUM_REGS * sizeof(u32)) +#define DE_REGS_VER 1 + +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (6*HZ) + +/* This is a mysterious value that can be written to CSR11 in the 21040 (only) + to support a pre-NWay full-duplex signaling mechanism using short frames. + No one knows what it should be, but if left at its default value some + 10base2(!) packets trigger a full-duplex-request interrupt. */ +#define FULL_DUPLEX_MAGIC 0x6969 + +enum { + /* NIC registers */ + BusMode = 0x00, + TxPoll = 0x08, + RxPoll = 0x10, + RxRingAddr = 0x18, + TxRingAddr = 0x20, + MacStatus = 0x28, + MacMode = 0x30, + IntrMask = 0x38, + RxMissed = 0x40, + ROMCmd = 0x48, + CSR11 = 0x58, + SIAStatus = 0x60, + CSR13 = 0x68, + CSR14 = 0x70, + CSR15 = 0x78, + PCIPM = 0x40, + + /* BusMode bits */ + CmdReset = (1 << 0), + CacheAlign16 = 0x00008000, + BurstLen4 = 0x00000400, + + /* Rx/TxPoll bits */ + NormalTxPoll = (1 << 0), + NormalRxPoll = (1 << 0), + + /* Tx/Rx descriptor status bits */ + DescOwn = (1 << 31), + RxError = (1 << 15), + RxErrLong = (1 << 7), + RxErrCRC = (1 << 1), + RxErrFIFO = (1 << 0), + RxErrRunt = (1 << 11), + RxErrFrame = (1 << 14), + RingEnd = (1 << 25), + FirstFrag = (1 << 29), + LastFrag = (1 << 30), + TxError = (1 << 15), + TxFIFOUnder = (1 << 1), + TxLinkFail = (1 << 2) | (1 << 10) | (1 << 11), + TxMaxCol = (1 << 8), + TxOWC = (1 << 9), + TxJabber = (1 << 14), + SetupFrame = (1 << 27), + TxSwInt = (1 << 31), + + /* MacStatus bits */ + IntrOK = (1 << 16), + IntrErr = (1 << 15), + RxIntr = (1 << 6), + RxEmpty = (1 << 7), + TxIntr = (1 << 0), + TxEmpty = (1 << 2), + PciErr = (1 << 13), + TxState = (1 << 22) | (1 << 21) | (1 << 20), + RxState = (1 << 19) | (1 << 18) | (1 << 17), + LinkFail = (1 << 12), + LinkPass = (1 << 4), + RxStopped = (1 << 8), + TxStopped = (1 << 1), + + /* MacMode bits */ + TxEnable = (1 << 13), + RxEnable = (1 << 1), + RxTx = TxEnable | RxEnable, + FullDuplex = (1 << 9), + AcceptAllMulticast = (1 << 7), + AcceptAllPhys = (1 << 6), + BOCnt = (1 << 5), + MacModeClear = (1<<12) | (1<<11) | (1<<10) | (1<<8) | (1<<3) | + RxTx | BOCnt | AcceptAllPhys | AcceptAllMulticast, + + /* ROMCmd bits */ + EE_SHIFT_CLK = 0x02, /* EEPROM shift clock. */ + EE_CS = 0x01, /* EEPROM chip select. */ + EE_DATA_WRITE = 0x04, /* Data from the Tulip to EEPROM. */ + EE_WRITE_0 = 0x01, + EE_WRITE_1 = 0x05, + EE_DATA_READ = 0x08, /* Data from the EEPROM chip. */ + EE_ENB = (0x4800 | EE_CS), + + /* The EEPROM commands include the alway-set leading bit. */ + EE_READ_CMD = 6, + + /* RxMissed bits */ + RxMissedOver = (1 << 16), + RxMissedMask = 0xffff, + + /* SROM-related bits */ + SROMC0InfoLeaf = 27, + MediaBlockMask = 0x3f, + MediaCustomCSRs = (1 << 6), + + /* PCIPM bits */ + PM_Sleep = (1 << 31), + PM_Snooze = (1 << 30), + PM_Mask = PM_Sleep | PM_Snooze, + + /* SIAStatus bits */ + NWayState = (1 << 14) | (1 << 13) | (1 << 12), + NWayRestart = (1 << 12), + NonselPortActive = (1 << 9), + LinkFailStatus = (1 << 2), + NetCxnErr = (1 << 1), +}; + +static const u32 de_intr_mask = + IntrOK | IntrErr | RxIntr | RxEmpty | TxIntr | TxEmpty | + LinkPass | LinkFail | PciErr; + +/* + * Set the programmable burst length to 4 longwords for all: + * DMA errors result without these values. Cache align 16 long. + */ +static const u32 de_bus_mode = CacheAlign16 | BurstLen4; + +struct de_srom_media_block { + u8 opts; + u16 csr13; + u16 csr14; + u16 csr15; +} __attribute__((packed)); + +struct de_srom_info_leaf { + u16 default_media; + u8 n_blocks; + u8 unused; + struct de_srom_media_block media[0]; +} __attribute__((packed)); + +struct de_desc { + u32 opts1; + u32 opts2; + u32 addr1; + u32 addr2; +}; + +struct media_info { + u16 type; /* DE_MEDIA_xxx */ + u16 csr13; + u16 csr14; + u16 csr15; +}; + +struct ring_info { + struct sk_buff *skb; + dma_addr_t mapping; +}; + +struct de_private { + unsigned tx_head; + unsigned tx_tail; + unsigned rx_tail; + + void *regs; + struct net_device *dev; + spinlock_t lock; + + struct de_desc *rx_ring; + struct de_desc *tx_ring; + struct ring_info tx_skb[DE_TX_RING_SIZE]; + struct ring_info rx_skb[DE_RX_RING_SIZE]; + unsigned rx_buf_sz; + dma_addr_t ring_dma; + + u32 msg_enable; + + struct net_device_stats net_stats; + + struct pci_dev *pdev; + u32 macmode; + + u16 setup_frame[DE_SETUP_FRAME_WORDS]; + + u32 media_type; + u32 media_supported; + u32 media_advertise; + struct media_info media[DE_MAX_MEDIA]; + struct timer_list media_timer; + + unsigned board_idx; + unsigned de21040 : 1; + unsigned media_lock : 1; +}; + + +static void de_set_rx_mode (struct net_device *dev); +static void de_tx (struct de_private *de); +static void de_clean_rings (struct de_private *de); +static void de_media_interrupt (struct de_private *de, u32 status); +static void de21040_media_timer (unsigned long data); +static void de21041_media_timer (unsigned long data); + + +static struct pci_device_id de_pci_tbl[] __initdata = { + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, + { }, +}; +MODULE_DEVICE_TABLE(pci, de_pci_tbl); + +static const char * const media_name[DE_MAX_MEDIA] = { + "10baseT auto", + "BNC", + "AUI", + "10baseT-HD", + "10baseT-FD" +}; + +/* 21040 transceiver register settings: + * TP AUTO(unused), BNC(unused), AUI, TP, TP FD*/ +static u16 t21040_csr13[] = { 0, 0, 0x8F09, 0x8F01, 0x8F01, }; +static u16 t21040_csr14[] = { 0, 0, 0x0705, 0xFFFF, 0xFFFD, }; +static u16 t21040_csr15[] = { 0, 0, 0x0006, 0x0000, 0x0000, }; + +/* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/ +static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }; +static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, }; +static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; + + +static inline unsigned long +msec_to_jiffies(unsigned long ms) +{ + return (((ms)*HZ+999)/1000); +} + + +#define dr32(reg) readl(de->regs + (reg)) +#define dw32(reg,val) writel((val), de->regs + (reg)) + + +static void de_rx_err_acct (struct de_private *de, unsigned rx_tail, + u32 status, u32 len) +{ + if (netif_msg_rx_err (de)) + printk (KERN_DEBUG + "%s: rx err, slot %d status 0x%x len %d\n", + de->dev->name, rx_tail, status, len); + + if ((status & 0x38000300) != 0x0300) { + /* Ingore earlier buffers. */ + if ((status & 0xffff) != 0x7fff) { + if (netif_msg_rx_err(de)) + printk(KERN_WARNING "%s: Oversized Ethernet frame " + "spanned multiple buffers, status %8.8x!\n", + de->dev->name, status); + de->net_stats.rx_length_errors++; + } + } else if (status & RxError) { + /* There was a fatal error. */ + de->net_stats.rx_errors++; /* end of a packet.*/ + if (status & 0x0890) de->net_stats.rx_length_errors++; + if (status & RxErrCRC) de->net_stats.rx_crc_errors++; + if (status & RxErrFIFO) de->net_stats.rx_fifo_errors++; + } +} + +static void de_rx (struct de_private *de) +{ + unsigned rx_tail = de->rx_tail; + unsigned rx_work = DE_RX_RING_SIZE; + unsigned drop = 0; + int rc; + + while (rx_work--) { + u32 status, len; + dma_addr_t mapping; + struct sk_buff *skb, *copy_skb; + unsigned copying_skb, buflen; + + skb = de->rx_skb[rx_tail].skb; + if (!skb) + BUG(); + rmb(); + status = le32_to_cpu(de->rx_ring[rx_tail].opts1); + if (status & DescOwn) + break; + + len = ((status >> 16) & 0x7ff) - 4; + mapping = de->rx_skb[rx_tail].mapping; + + if (unlikely(drop)) { + de->net_stats.rx_dropped++; + goto rx_next; + } + + if (unlikely((status & 0x38008300) != 0x0300)) { + de_rx_err_acct(de, rx_tail, status, len); + goto rx_next; + } + + copying_skb = (len <= rx_copybreak); + + if (unlikely(netif_msg_rx_status(de))) + printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d copying? %d\n", + de->dev->name, rx_tail, status, len, + copying_skb); + + buflen = copying_skb ? (len + RX_OFFSET) : de->rx_buf_sz; + copy_skb = dev_alloc_skb (buflen); + if (unlikely(!copy_skb)) { + de->net_stats.rx_dropped++; + drop = 1; + rx_work = 100; + goto rx_next; + } + copy_skb->dev = de->dev; + + if (!copying_skb) { + pci_unmap_single(de->pdev, mapping, + buflen, PCI_DMA_FROMDEVICE); + skb_put(skb, len); + + mapping = + de->rx_skb[rx_tail].mapping = + pci_map_single(de->pdev, copy_skb->tail, + buflen, PCI_DMA_FROMDEVICE); + de->rx_skb[rx_tail].skb = copy_skb; + } else { + pci_dma_sync_single(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); + skb_reserve(copy_skb, RX_OFFSET); + memcpy(skb_put(copy_skb, len), skb->tail, len); + + /* We'll reuse the original ring buffer. */ + skb = copy_skb; + } + + skb->protocol = eth_type_trans (skb, de->dev); + + de->net_stats.rx_packets++; + de->net_stats.rx_bytes += skb->len; + de->dev->last_rx = jiffies; + rc = netif_rx (skb); + if (rc == NET_RX_DROP) + drop = 1; + +rx_next: + de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn); + if (rx_tail == (DE_RX_RING_SIZE - 1)) + de->rx_ring[rx_tail].opts2 = + cpu_to_le32(RingEnd | de->rx_buf_sz); + else + de->rx_ring[rx_tail].opts2 = cpu_to_le32(de->rx_buf_sz); + de->rx_ring[rx_tail].addr1 = cpu_to_le32(mapping); + rx_tail = NEXT_RX(rx_tail); + } + + if (!rx_work) + printk(KERN_WARNING "%s: rx work limit reached\n", de->dev->name); + + de->rx_tail = rx_tail; +} + +static void de_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +{ + struct net_device *dev = dev_instance; + struct de_private *de = dev->priv; + u32 status; + + status = dr32(MacStatus); + if ((!(status & (IntrOK|IntrErr))) || (status == 0xFFFF)) + return; + + if (netif_msg_intr(de)) + printk(KERN_DEBUG "%s: intr, status %08x mode %08x desc %u/%u/%u\n", + dev->name, status, dr32(MacMode), de->rx_tail, de->tx_head, de->tx_tail); + + dw32(MacStatus, status); + + if (status & (RxIntr | RxEmpty)) { + de_rx(de); + if (status & RxEmpty) + dw32(RxPoll, NormalRxPoll); + } + + spin_lock(&de->lock); + + if (status & (TxIntr | TxEmpty)) + de_tx(de); + + if (status & (LinkPass | LinkFail)) + de_media_interrupt(de, status); + + spin_unlock(&de->lock); + + if (status & PciErr) { + u16 pci_status; + + pci_read_config_word(de->pdev, PCI_STATUS, &pci_status); + pci_write_config_word(de->pdev, PCI_STATUS, pci_status); + printk(KERN_ERR "%s: PCI bus error, status=%08x, PCI status=%04x\n", + dev->name, status, pci_status); + } +} + +static void de_tx (struct de_private *de) +{ + unsigned tx_head = de->tx_head; + unsigned tx_tail = de->tx_tail; + + while (tx_tail != tx_head) { + struct sk_buff *skb; + u32 status; + + rmb(); + status = le32_to_cpu(de->tx_ring[tx_tail].opts1); + if (status & DescOwn) + break; + + skb = de->tx_skb[tx_tail].skb; + if (!skb) + BUG(); + if (unlikely(skb == DE_DUMMY_SKB)) + goto next; + + if (unlikely(skb == DE_SETUP_SKB)) { + pci_unmap_single(de->pdev, de->tx_skb[tx_tail].mapping, + sizeof(de->setup_frame), PCI_DMA_TODEVICE); + goto next; + } + + pci_unmap_single(de->pdev, de->tx_skb[tx_tail].mapping, + skb->len, PCI_DMA_TODEVICE); + + if (status & LastFrag) { + if (status & TxError) { + if (netif_msg_tx_err(de)) + printk(KERN_DEBUG "%s: tx err, status 0x%x\n", + de->dev->name, status); + de->net_stats.tx_errors++; + if (status & TxOWC) + de->net_stats.tx_window_errors++; + if (status & TxMaxCol) + de->net_stats.tx_aborted_errors++; + if (status & TxLinkFail) + de->net_stats.tx_carrier_errors++; + if (status & TxFIFOUnder) + de->net_stats.tx_fifo_errors++; + } else { + de->net_stats.tx_packets++; + de->net_stats.tx_bytes += skb->len; + if (netif_msg_tx_done(de)) + printk(KERN_DEBUG "%s: tx done, slot %d\n", de->dev->name, tx_tail); + } + dev_kfree_skb_irq(skb); + } + +next: + de->tx_skb[tx_tail].skb = NULL; + + tx_tail = NEXT_TX(tx_tail); + } + + de->tx_tail = tx_tail; + + if (netif_queue_stopped(de->dev) && (TX_BUFFS_AVAIL(de) > (DE_TX_RING_SIZE / 4))) + netif_wake_queue(de->dev); +} + +static int de_start_xmit (struct sk_buff *skb, struct net_device *dev) +{ + struct de_private *de = dev->priv; + unsigned int entry, tx_free; + u32 mapping, len, flags = FirstFrag | LastFrag; + struct de_desc *txd; + + spin_lock_irq(&de->lock); + + tx_free = TX_BUFFS_AVAIL(de); + if (tx_free == 0) { + netif_stop_queue(dev); + spin_unlock_irq(&de->lock); + return 1; + } + tx_free--; + + entry = de->tx_head; + + txd = &de->tx_ring[entry]; + + len = skb->len; + mapping = pci_map_single(de->pdev, skb->data, len, PCI_DMA_TODEVICE); + if (entry == (DE_TX_RING_SIZE - 1)) + flags |= RingEnd; + if (!tx_free || (tx_free == (DE_TX_RING_SIZE / 2))) + flags |= TxSwInt; + flags |= len; + txd->opts2 = cpu_to_le32(flags); + txd->addr1 = cpu_to_le32(mapping); + + de->tx_skb[entry].skb = skb; + de->tx_skb[entry].mapping = mapping; + wmb(); + + txd->opts1 = cpu_to_le32(DescOwn); + wmb(); + + de->tx_head = NEXT_TX(entry); + if (netif_msg_tx_queued(de)) + printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n", + dev->name, entry, skb->len); + + if (tx_free == 0) + netif_stop_queue(dev); + + spin_unlock_irq(&de->lock); + + /* Trigger an immediate transmit demand. */ + dw32(TxPoll, NormalTxPoll); + dev->trans_start = jiffies; + + return 0; +} + +/* Set or clear the multicast filter for this adaptor. + Note that we only use exclusion around actually queueing the + new frame, not around filling de->setup_frame. This is non-deterministic + when re-entered but still correct. */ + +/* The little-endian AUTODIN32 ethernet CRC calculation. + N.B. Do not use for bulk data, use a table-based routine instead. + This is common code and should be moved to net/core/crc.c */ +static unsigned const ethernet_polynomial_le = 0xedb88320U; +static inline u32 ether_crc_le(int length, unsigned char *data) +{ + u32 crc = 0xffffffff; /* Initial value. */ + while(--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 8; --bit >= 0; current_octet >>= 1) { + if ((crc ^ current_octet) & 1) { + crc >>= 1; + crc ^= ethernet_polynomial_le; + } else + crc >>= 1; + } + } + return crc; +} +static unsigned const ethernet_polynomial = 0x04c11db7U; +static inline u32 ether_crc(int length, unsigned char *data) +{ + int crc = -1; + + while(--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 0; bit < 8; bit++, current_octet >>= 1) + crc = (crc << 1) ^ + ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0); + } + return crc; +} + +#undef set_bit_le +#define set_bit_le(i,p) do { ((char *)(p))[(i)/8] |= (1<<((i)%8)); } while(0) + +static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) +{ + struct de_private *de = dev->priv; + u16 hash_table[32]; + struct dev_mc_list *mclist; + int i; + u16 *eaddrs; + + memset(hash_table, 0, sizeof(hash_table)); + set_bit_le(255, hash_table); /* Broadcast entry */ + /* This should work on big-endian machines as well. */ + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) { + int index = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff; + + set_bit_le(index, hash_table); + + for (i = 0; i < 32; i++) { + *setup_frm++ = hash_table[i]; + *setup_frm++ = hash_table[i]; + } + setup_frm = &de->setup_frame[13*6]; + } + + /* Fill the final entry with our physical address. */ + eaddrs = (u16 *)dev->dev_addr; + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; +} + +static void build_setup_frame_perfect(u16 *setup_frm, struct net_device *dev) +{ + struct de_private *de = dev->priv; + struct dev_mc_list *mclist; + int i; + u16 *eaddrs; + + /* We have <= 14 addresses so we can use the wonderful + 16 address perfect filtering of the Tulip. */ + for (i = 0, mclist = dev->mc_list; i < dev->mc_count; + i++, mclist = mclist->next) { + eaddrs = (u16 *)mclist->dmi_addr; + *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; + *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; + *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; + } + /* Fill the unused entries with the broadcast address. */ + memset(setup_frm, 0xff, (15-i)*12); + setup_frm = &de->setup_frame[15*6]; + + /* Fill the final entry with our physical address. */ + eaddrs = (u16 *)dev->dev_addr; + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; +} + + +static void __de_set_rx_mode (struct net_device *dev) +{ + struct de_private *de = dev->priv; + u32 macmode; + unsigned int entry; + u32 mapping; + struct de_desc *txd; + struct de_desc *dummy_txd = NULL; + + macmode = de->macmode & ~(AcceptAllMulticast | AcceptAllPhys); + + if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ + macmode |= AcceptAllMulticast | AcceptAllPhys; + goto out; + } + + if ((dev->mc_count > 1000) || (dev->flags & IFF_ALLMULTI)) { + /* Too many to filter well -- accept all multicasts. */ + macmode |= AcceptAllMulticast; + goto out; + } + + /* Note that only the low-address shortword of setup_frame is valid! + The values are doubled for big-endian architectures. */ + if (dev->mc_count > 14) /* Must use a multicast hash table. */ + build_setup_frame_hash (de->setup_frame, dev); + else + build_setup_frame_perfect (de->setup_frame, dev); + + /* + * Now add this frame to the Tx list. + */ + + entry = de->tx_head; + + /* Avoid a chip errata by prefixing a dummy entry. */ + if (entry != 0) { + de->tx_skb[entry].skb = DE_DUMMY_SKB; + + dummy_txd = &de->tx_ring[entry]; + dummy_txd->opts2 = (entry == (DE_TX_RING_SIZE - 1)) ? + cpu_to_le32(RingEnd) : 0; + dummy_txd->addr1 = 0; + + /* Must set DescOwned later to avoid race with chip */ + + entry = NEXT_TX(entry); + } + + de->tx_skb[entry].skb = DE_SETUP_SKB; + de->tx_skb[entry].mapping = mapping = + pci_map_single (de->pdev, de->setup_frame, + sizeof (de->setup_frame), PCI_DMA_TODEVICE); + + /* Put the setup frame on the Tx list. */ + txd = &de->tx_ring[entry]; + if (entry == (DE_TX_RING_SIZE - 1)) + txd->opts2 = cpu_to_le32(SetupFrame | RingEnd | sizeof (de->setup_frame)); + else + txd->opts2 = cpu_to_le32(SetupFrame | sizeof (de->setup_frame)); + txd->addr1 = cpu_to_le32(mapping); + wmb(); + + txd->opts1 = cpu_to_le32(DescOwn); + wmb(); + + if (dummy_txd) { + dummy_txd->opts1 = cpu_to_le32(DescOwn); + wmb(); + } + + de->tx_head = NEXT_TX(entry); + + if (TX_BUFFS_AVAIL(de) < 0) + BUG(); + if (TX_BUFFS_AVAIL(de) == 0) + netif_stop_queue(dev); + + /* Trigger an immediate transmit demand. */ + dw32(TxPoll, NormalTxPoll); + +out: + if (macmode != de->macmode) { + dw32 (MacMode, macmode); + de->macmode = macmode; + } +} + +static void de_set_rx_mode (struct net_device *dev) +{ + unsigned long flags; + struct de_private *de = dev->priv; + + spin_lock_irqsave (&de->lock, flags); + __de_set_rx_mode(dev); + spin_unlock_irqrestore (&de->lock, flags); +} + +static inline void de_rx_missed(struct de_private *de, u32 rx_missed) +{ + if (unlikely(rx_missed & RxMissedOver)) + de->net_stats.rx_missed_errors += RxMissedMask; + else + de->net_stats.rx_missed_errors += (rx_missed & RxMissedMask); +} + +static void __de_get_stats(struct de_private *de) +{ + u32 tmp = dr32(RxMissed); /* self-clearing */ + + de_rx_missed(de, tmp); +} + +static struct net_device_stats *de_get_stats(struct net_device *dev) +{ + struct de_private *de = dev->priv; + + /* The chip only need report frame silently dropped. */ + spin_lock_irq(&de->lock); + if (netif_running(dev) && netif_device_present(dev)) + __de_get_stats(de); + spin_unlock_irq(&de->lock); + + return &de->net_stats; +} + +static inline int de_is_running (struct de_private *de) +{ + return (dr32(MacStatus) & (RxState | TxState)) ? 1 : 0; +} + +static void de_stop_rxtx (struct de_private *de) +{ + u32 macmode; + unsigned int work = 1000; + + macmode = dr32(MacMode); + if (macmode & RxTx) { + dw32(MacMode, macmode & ~RxTx); + dr32(MacMode); + } + + while (--work > 0) { + if (!de_is_running(de)) + return; + cpu_relax(); + } + + printk(KERN_WARNING "%s: timeout expired stopping DMA\n", de->dev->name); +} + +static inline void de_start_rxtx (struct de_private *de) +{ + u32 macmode; + + macmode = dr32(MacMode); + if ((macmode & RxTx) != RxTx) { + dw32(MacMode, macmode | RxTx); + dr32(MacMode); + } +} + +static void de_stop_hw (struct de_private *de) +{ + + udelay(5); + dw32(IntrMask, 0); + + de_stop_rxtx(de); + + dw32(MacStatus, dr32(MacStatus)); + + synchronize_irq(); + udelay(10); + + de->rx_tail = 0; + de->tx_head = de->tx_tail = 0; +} + +static void de_link_up(struct de_private *de) +{ + if (!netif_carrier_ok(de->dev)) { + netif_carrier_on(de->dev); + if (netif_msg_link(de)) + printk(KERN_INFO "%s: link up, media %s\n", + de->dev->name, media_name[de->media_type]); + } +} + +static void de_link_down(struct de_private *de) +{ + if (netif_carrier_ok(de->dev)) { + netif_carrier_off(de->dev); + if (netif_msg_link(de)) + printk(KERN_INFO "%s: link down\n", de->dev->name); + } +} + +static void de_set_media (struct de_private *de) +{ + unsigned media = de->media_type; + + if (de_is_running(de)) + BUG(); + + if (de->de21040) + dw32(CSR11, FULL_DUPLEX_MAGIC); + dw32(CSR13, 0); /* Reset phy */ + dw32(CSR14, de->media[media].csr14); + dw32(CSR15, de->media[media].csr15); + dw32(CSR13, de->media[media].csr13); + + /* must delay 10ms before writing to other registers, + * especially CSR6 + */ + mdelay(10); + + if (media == DE_MEDIA_TP_FD) + de->macmode |= FullDuplex; + else + de->macmode &= ~FullDuplex; + + if (netif_msg_link(de)) + printk(KERN_INFO "%s: set link %s, mode %x, sia %x,%x,%x,%x\n" + KERN_INFO " set mode %x, set sia %x,%x,%x\n", + de->dev->name, media_name[media], + dr32(MacMode), dr32(SIAStatus), dr32(CSR13), + dr32(CSR14), dr32(CSR15), de->macmode, + de->media[media].csr13, + de->media[media].csr14, + de->media[media].csr15); +} + +static void de21040_media_timer (unsigned long data) +{ + struct de_private *de = (struct de_private *) data; + struct net_device *dev = de->dev; + u32 status = dr32(SIAStatus); + unsigned int carrier; + + carrier = (status & NetCxnErr) ? 0 : 1; + + if (carrier) { + if (de->media_type != DE_MEDIA_AUI && (status & LinkFailStatus)) + goto no_link_yet; + + de->media_timer.expires = jiffies + DE_TIMER_LINK; + add_timer(&de->media_timer); + if (!netif_carrier_ok(dev)) + de_link_up(de); + else + if (netif_msg_timer(de)) + printk(KERN_INFO "%s: %s link ok, status %x\n", + dev->name, media_name[de->media_type], + status); + return; + } + + de_link_down(de); + + if (de->media_lock) + return; + + if (de->media_type == DE_MEDIA_AUI) + de->media_type = DE_MEDIA_TP; + else + de->media_type = DE_MEDIA_AUI; + + de_stop_rxtx(de); + de_set_media(de); + de_start_rxtx(de); + +no_link_yet: + de->media_timer.expires = jiffies + DE_TIMER_NO_LINK; + add_timer(&de->media_timer); + + if (netif_msg_timer(de)) + printk(KERN_INFO "%s: no link, trying media %s, status %x\n", + dev->name, media_name[de->media_type], status); +} + +static unsigned int de_ok_to_advertise (struct de_private *de, u32 new_media) +{ + switch (new_media) { + case DE_MEDIA_TP_AUTO: + if (!(de->media_advertise & ADVERTISED_Autoneg)) + return 0; + if (!(de->media_advertise & (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full))) + return 0; + break; + case DE_MEDIA_BNC: + if (!(de->media_advertise & ADVERTISED_BNC)) + return 0; + break; + case DE_MEDIA_AUI: + if (!(de->media_advertise & ADVERTISED_AUI)) + return 0; + break; + case DE_MEDIA_TP: + if (!(de->media_advertise & ADVERTISED_10baseT_Half)) + return 0; + break; + case DE_MEDIA_TP_FD: + if (!(de->media_advertise & ADVERTISED_10baseT_Full)) + return 0; + break; + } + + return 1; +} + +static void de21041_media_timer (unsigned long data) +{ + struct de_private *de = (struct de_private *) data; + struct net_device *dev = de->dev; + u32 status = dr32(SIAStatus), new_media; + unsigned int carrier; + + carrier = (status & NetCxnErr) ? 0 : 1; + + if (carrier) { + if ((de->media_type == DE_MEDIA_TP_AUTO || + de->media_type == DE_MEDIA_TP || + de->media_type == DE_MEDIA_TP_FD) && + (status & LinkFailStatus)) + goto no_link_yet; + + de->media_timer.expires = jiffies + DE_TIMER_LINK; + add_timer(&de->media_timer); + if (!netif_carrier_ok(dev)) + de_link_up(de); + else + if (netif_msg_timer(de)) + printk(KERN_INFO "%s: %s link ok, mode %x status %x\n", + dev->name, media_name[de->media_type], + dr32(MacMode), status); + return; + } + + de_link_down(de); + + /* if media type locked, don't switch media */ + if (de->media_lock) + goto set_media; + + /* if activity detected, use that as hint for new media type */ + if (status & NonselPortActive) { + if (de->media_type == DE_MEDIA_AUI) + de->media_type = DE_MEDIA_TP; + else + de->media_type = DE_MEDIA_AUI; + goto set_media; + } + + /* move to next advertised media */ + new_media = de->media_type; + do { + if (new_media == DE_MEDIA_LAST) + new_media = DE_MEDIA_FIRST; + else + new_media++; + } while ((!de_ok_to_advertise(de, new_media)) && + (new_media != de->media_type)); + + de->media_type = new_media; + +set_media: + de_stop_rxtx(de); + de_set_media(de); + de_start_rxtx(de); + +no_link_yet: + de->media_timer.expires = jiffies + DE_TIMER_NO_LINK; + add_timer(&de->media_timer); + + if (netif_msg_timer(de)) + printk(KERN_INFO "%s: no link, trying media %s, status %x\n", + dev->name, media_name[de->media_type], status); +} + +static void de_media_interrupt (struct de_private *de, u32 status) +{ + if (status & LinkPass) { + de_link_up(de); + mod_timer(&de->media_timer, jiffies + DE_TIMER_LINK); + return; + } + + if (!(status & LinkFail)) + BUG(); + + if (netif_carrier_ok(de->dev)) { + de_link_down(de); + mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK); + } +} + +static int de_reset_mac (struct de_private *de) +{ + unsigned tmp; + u32 status; + + /* + * Reset MAC. Copied from de4x5.c. + */ + + dr32 (BusMode); + mdelay (1); + + dw32 (BusMode, de_bus_mode | CmdReset); + mdelay (1); + + dw32 (BusMode, de_bus_mode); + mdelay (1); + + for (tmp = 0; tmp < 5; tmp++) { + dr32 (BusMode); + mdelay (1); + } + + mdelay (1); + + status = dr32(MacStatus); + if (status & (RxState | TxState)) + return -EBUSY; + if (status == 0xffffffff) + return -ENODEV; + return 0; +} + +static void de_adapter_wake (struct de_private *de) +{ + u32 pmctl; + + if (de->de21040) + return; + + pci_read_config_dword(de->pdev, PCIPM, &pmctl); + if (pmctl & PM_Mask) { + pmctl &= ~PM_Mask; + pci_write_config_dword(de->pdev, PCIPM, pmctl); + + /* de4x5.c delays, so we do too */ + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout(msec_to_jiffies(10)); + } +} + +static void de_adapter_sleep (struct de_private *de) +{ + u32 pmctl; + + if (de->de21040) + return; + + pci_read_config_dword(de->pdev, PCIPM, &pmctl); + pmctl |= PM_Sleep; + pci_write_config_dword(de->pdev, PCIPM, pmctl); +} + +static int de_init_hw (struct de_private *de) +{ + struct net_device *dev = de->dev; + int rc; + + de_adapter_wake(de); + + de->macmode = dr32(MacMode) & ~MacModeClear; + + rc = de_reset_mac(de); + if (rc) + return rc; + + de_set_media(de); /* reset phy */ + + dw32(RxRingAddr, de->ring_dma); + dw32(TxRingAddr, de->ring_dma + (sizeof(struct de_desc) * DE_RX_RING_SIZE)); + + dw32(MacMode, RxTx | de->macmode); + + dr32(RxMissed); /* self-clearing */ + + dw32(IntrMask, de_intr_mask); + + de_set_rx_mode(dev); + + return 0; +} + +static int de_refill_rx (struct de_private *de) +{ + unsigned i; + + for (i = 0; i < DE_RX_RING_SIZE; i++) { + struct sk_buff *skb; + + skb = dev_alloc_skb(de->rx_buf_sz); + if (!skb) + goto err_out; + + skb->dev = de->dev; + + de->rx_skb[i].mapping = pci_map_single(de->pdev, + skb->tail, de->rx_buf_sz, PCI_DMA_FROMDEVICE); + de->rx_skb[i].skb = skb; + + de->rx_ring[i].opts1 = cpu_to_le32(DescOwn); + if (i == (DE_RX_RING_SIZE - 1)) + de->rx_ring[i].opts2 = + cpu_to_le32(RingEnd | de->rx_buf_sz); + else + de->rx_ring[i].opts2 = cpu_to_le32(de->rx_buf_sz); + de->rx_ring[i].addr1 = cpu_to_le32(de->rx_skb[i].mapping); + de->rx_ring[i].addr2 = 0; + } + + return 0; + +err_out: + de_clean_rings(de); + return -ENOMEM; +} + +static int de_init_rings (struct de_private *de) +{ + memset(de->tx_ring, 0, sizeof(struct de_desc) * DE_TX_RING_SIZE); + de->tx_ring[DE_TX_RING_SIZE - 1].opts2 = cpu_to_le32(RingEnd); + + de->rx_tail = 0; + de->tx_head = de->tx_tail = 0; + + return de_refill_rx (de); +} + +static int de_alloc_rings (struct de_private *de) +{ + de->rx_ring = pci_alloc_consistent(de->pdev, DE_RING_BYTES, &de->ring_dma); + if (!de->rx_ring) + return -ENOMEM; + de->tx_ring = &de->rx_ring[DE_RX_RING_SIZE]; + return de_init_rings(de); +} + +static void de_clean_rings (struct de_private *de) +{ + unsigned i; + + memset(de->rx_ring, 0, sizeof(struct de_desc) * DE_RX_RING_SIZE); + de->rx_ring[DE_RX_RING_SIZE - 1].opts2 = cpu_to_le32(RingEnd); + wmb(); + memset(de->tx_ring, 0, sizeof(struct de_desc) * DE_TX_RING_SIZE); + de->tx_ring[DE_TX_RING_SIZE - 1].opts2 = cpu_to_le32(RingEnd); + wmb(); + + for (i = 0; i < DE_RX_RING_SIZE; i++) { + if (de->rx_skb[i].skb) { + pci_unmap_single(de->pdev, de->rx_skb[i].mapping, + de->rx_buf_sz, PCI_DMA_FROMDEVICE); + dev_kfree_skb(de->rx_skb[i].skb); + } + } + + for (i = 0; i < DE_TX_RING_SIZE; i++) { + if (de->tx_skb[i].skb) { + struct sk_buff *skb = de->tx_skb[i].skb; + pci_unmap_single(de->pdev, de->tx_skb[i].mapping, + skb->len, PCI_DMA_TODEVICE); + dev_kfree_skb(skb); + de->net_stats.tx_dropped++; + } + } + + memset(&de->rx_skb, 0, sizeof(struct ring_info) * DE_RX_RING_SIZE); + memset(&de->tx_skb, 0, sizeof(struct ring_info) * DE_TX_RING_SIZE); +} + +static void de_free_rings (struct de_private *de) +{ + de_clean_rings(de); + pci_free_consistent(de->pdev, DE_RING_BYTES, de->rx_ring, de->ring_dma); + de->rx_ring = NULL; + de->tx_ring = NULL; +} + +static int de_open (struct net_device *dev) +{ + struct de_private *de = dev->priv; + int rc; + + if (netif_msg_ifup(de)) + printk(KERN_DEBUG "%s: enabling interface\n", dev->name); + + de->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); + + rc = de_alloc_rings(de); + if (rc) { + printk(KERN_ERR "%s: ring allocation failure, err=%d\n", + dev->name, rc); + return rc; + } + + rc = de_init_hw(de); + if (rc) { + printk(KERN_ERR "%s: h/w init failure, err=%d\n", + dev->name, rc); + goto err_out_free; + } + + rc = request_irq(dev->irq, de_interrupt, SA_SHIRQ, dev->name, dev); + if (rc) { + printk(KERN_ERR "%s: IRQ %d request failure, err=%d\n", + dev->name, dev->irq, rc); + goto err_out_hw; + } + + netif_start_queue(dev); + + return 0; + +err_out_hw: + de_stop_hw(de); +err_out_free: + de_free_rings(de); + return rc; +} + +static int de_close (struct net_device *dev) +{ + struct de_private *de = dev->priv; + + if (netif_msg_ifdown(de)) + printk(KERN_DEBUG "%s: disabling interface\n", dev->name); + + netif_stop_queue(dev); + netif_carrier_off(dev); + del_timer_sync(&de->media_timer); + de_stop_hw(de); + free_irq(dev->irq, dev); + de_free_rings(de); + de_adapter_sleep(de); + pci_disable_device(de->pdev); + return 0; +} + +static void de_tx_timeout (struct net_device *dev) +{ + struct de_private *de = dev->priv; + + printk(KERN_DEBUG "%s: NIC status %08x mode %08x sia %08x desc %u/%u/%u\n", + dev->name, dr32(MacStatus), dr32(MacMode), dr32(SIAStatus), + de->rx_tail, de->tx_head, de->tx_tail); + + del_timer_sync(&de->media_timer); + + disable_irq(dev->irq); + spin_lock_irq(&de->lock); + + de_stop_hw(de); + netif_stop_queue(dev); + netif_carrier_off(dev); + + spin_unlock_irq(&de->lock); + enable_irq(dev->irq); + + /* Update the error counts. */ + __de_get_stats(de); + + synchronize_irq(); + de_clean_rings(de); + + de_init_hw(de); + + netif_wake_queue(dev); +} + +static int de_get_regs(struct de_private *de, u8 *buf) +{ + int i; + u32 *rbuf = (u32 *)buf; + + /* read all CSRs */ + for (i = 0; i < DE_NUM_REGS; i++) + rbuf[i] = dr32(i * 8); + + /* handle self-clearing RxMissed counter, CSR8 */ + de_rx_missed(de, rbuf[8]); + + return 0; +} + +static int de_ethtool_gset(struct de_private *de, struct ethtool_cmd *ecmd) +{ + ecmd->supported = de->media_supported; + ecmd->transceiver = XCVR_INTERNAL; + ecmd->phy_address = 0; + ecmd->advertising = de->media_advertise; + + switch (de->media_type) { + case DE_MEDIA_AUI: + ecmd->port = PORT_AUI; + ecmd->speed = 5; + break; + case DE_MEDIA_BNC: + ecmd->port = PORT_BNC; + ecmd->speed = 2; + break; + default: + ecmd->port = PORT_TP; + ecmd->speed = SPEED_10; + break; + } + + if (de->macmode & FullDuplex) + ecmd->duplex = DUPLEX_FULL; + else + ecmd->duplex = DUPLEX_HALF; + + if (de->media_lock) + ecmd->autoneg = AUTONEG_DISABLE; + else + ecmd->autoneg = AUTONEG_ENABLE; + + /* ignore maxtxpkt, maxrxpkt for now */ + + return 0; +} + +static int de_ethtool_sset(struct de_private *de, struct ethtool_cmd *ecmd) +{ + u32 new_media; + unsigned int media_lock; + + if (ecmd->speed != SPEED_10 && ecmd->speed != 5 && ecmd->speed != 2) + return -EINVAL; + if (de->de21040 && ecmd->speed == 2) + return -EINVAL; + if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL) + return -EINVAL; + if (ecmd->port != PORT_TP && ecmd->port != PORT_AUI && ecmd->port != PORT_BNC) + return -EINVAL; + if (de->de21040 && ecmd->port == PORT_BNC) + return -EINVAL; + if (ecmd->transceiver != XCVR_INTERNAL) + return -EINVAL; + if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE) + return -EINVAL; + if (ecmd->advertising & ~de->media_supported) + return -EINVAL; + if (ecmd->autoneg == AUTONEG_ENABLE && + (!(ecmd->advertising & ADVERTISED_Autoneg))) + return -EINVAL; + + switch (ecmd->port) { + case PORT_AUI: + new_media = DE_MEDIA_AUI; + if (!(ecmd->advertising & ADVERTISED_AUI)) + return -EINVAL; + break; + case PORT_BNC: + new_media = DE_MEDIA_BNC; + if (!(ecmd->advertising & ADVERTISED_BNC)) + return -EINVAL; + break; + default: + if (ecmd->autoneg == AUTONEG_ENABLE) + new_media = DE_MEDIA_TP_AUTO; + else if (ecmd->duplex == DUPLEX_FULL) + new_media = DE_MEDIA_TP_FD; + else + new_media = DE_MEDIA_TP; + if (!(ecmd->advertising & ADVERTISED_TP)) + return -EINVAL; + if (!(ecmd->advertising & (ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half))) + return -EINVAL; + break; + } + + media_lock = (ecmd->autoneg == AUTONEG_ENABLE) ? 0 : 1; + + if ((new_media == de->media_type) && + (media_lock == de->media_lock) && + (ecmd->advertising == de->media_advertise)) + return 0; /* nothing to change */ + + de_link_down(de); + de_stop_rxtx(de); + + de->media_type = new_media; + de->media_lock = media_lock; + de->media_advertise = ecmd->advertising; + de_set_media(de); + + return 0; +} + +static int de_ethtool_ioctl (struct de_private *de, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + strcpy (info.bus_info, de->pdev->slot_name); + info.regdump_len = DE_REGS_SIZE; + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get settings */ + case ETHTOOL_GSET: { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + spin_lock_irq(&de->lock); + de_ethtool_gset(de, &ecmd); + spin_unlock_irq(&de->lock); + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + } + /* set settings */ + case ETHTOOL_SSET: { + struct ethtool_cmd ecmd; + int r; + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) + return -EFAULT; + spin_lock_irq(&de->lock); + r = de_ethtool_sset(de, &ecmd); + spin_unlock_irq(&de->lock); + return r; + } + + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST: { + u32 status; + + if (de->media_type != DE_MEDIA_TP_AUTO) + return -EINVAL; + if (netif_carrier_ok(de->dev)) + de_link_down(de); + + status = dr32(SIAStatus); + dw32(SIAStatus, (status & ~NWayState) | NWayRestart); + if (netif_msg_link(de)) + printk(KERN_INFO "%s: link nway restart, status %x,%x\n", + de->dev->name, status, dr32(SIAStatus)); + return 0; + } + + /* get link status */ + case ETHTOOL_GLINK: { + struct ethtool_value edata = {ETHTOOL_GLINK}; + edata.data = (netif_carrier_ok(de->dev)) ? 1 : 0; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = de->msg_enable; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + de->msg_enable = edata.data; + return 0; + } + + /* get registers */ + case ETHTOOL_GREGS: { + struct ethtool_regs regs; + u8 regbuf[DE_REGS_SIZE]; + int r; + + if (copy_from_user(®s, useraddr, sizeof(regs))) + return -EFAULT; + + if (regs.len > DE_REGS_SIZE) { + regs.len = DE_REGS_SIZE; + } + regs.version = (DE_REGS_VER << 2) | de->de21040; + if (copy_to_user(useraddr, ®s, sizeof(regs))) + return -EFAULT; + + useraddr += offsetof(struct ethtool_regs, data); + + spin_lock_irq(&de->lock); + r = de_get_regs(de, regbuf); + spin_unlock_irq(&de->lock); + + if (r) + return r; + if (copy_to_user(useraddr, regbuf, regs.len)) + return -EFAULT; + return 0; + } + + default: + break; + } + + return -EOPNOTSUPP; +} + + +static int de_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct de_private *de = dev->priv; + int rc = 0; + + if (!netif_running(dev)) + return -EINVAL; + + switch (cmd) { + case SIOCETHTOOL: + return de_ethtool_ioctl(de, (void *) rq->ifr_data); + + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + +static void __init de21040_get_mac_address (struct de_private *de) +{ + unsigned i; + + dw32 (ROMCmd, 0); /* Reset the pointer with a dummy write. */ + + for (i = 0; i < 6; i++) { + int value, boguscnt = 100000; + do + value = dr32(ROMCmd); + while (value < 0 && --boguscnt > 0); + de->dev->dev_addr[i] = value; + if (boguscnt <= 0) + printk(KERN_WARNING PFX "timeout reading 21040 MAC address byte %u\n", i); + } +} + +/* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/ + +/* Note: this routine returns extra data bits for size detection. */ +static unsigned __init tulip_read_eeprom(void *regs, int location, int addr_len) +{ + int i; + unsigned retval = 0; + void *ee_addr = regs + ROMCmd; + int read_cmd = location | (EE_READ_CMD << addr_len); + + writel(EE_ENB & ~EE_CS, ee_addr); + writel(EE_ENB, ee_addr); + + /* Shift the read command bits out. */ + for (i = 4 + addr_len; i >= 0; i--) { + short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + writel(EE_ENB | dataval, ee_addr); + readl(ee_addr); + writel(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + readl(ee_addr); + retval = (retval << 1) | ((readl(ee_addr) & EE_DATA_READ) ? 1 : 0); + } + writel(EE_ENB, ee_addr); + readl(ee_addr); + + for (i = 16; i > 0; i--) { + writel(EE_ENB | EE_SHIFT_CLK, ee_addr); + readl(ee_addr); + retval = (retval << 1) | ((readl(ee_addr) & EE_DATA_READ) ? 1 : 0); + writel(EE_ENB, ee_addr); + readl(ee_addr); + } + + /* Terminate the EEPROM access. */ + writel(EE_ENB & ~EE_CS, ee_addr); + return retval; +} + +static void __init tulip_get_srom_info (struct de_private *de) +{ + unsigned i, sa_offset = 0, ofs; + u8 ee_data[DE_EEPROM_WORDS * sizeof(u16)]; + unsigned ee_addr_size = tulip_read_eeprom(de->regs, 0xff, 8) & 0x40000 ? 8 : 6; + struct de_srom_info_leaf *il; + + /* download entire eeprom */ + for (i = 0; i < sizeof(ee_data)/2; i++) + ((u16 *)ee_data)[i] = + le16_to_cpu(tulip_read_eeprom(de->regs, i, ee_addr_size)); + + /* DEC now has a specification but early board makers + just put the address in the first EEPROM locations. */ + /* This does memcmp(eedata, eedata+16, 8) */ + for (i = 0; i < 8; i ++) + if (ee_data[i] != ee_data[16+i]) + sa_offset = 20; + + /* store MAC address */ + for (i = 0; i < 6; i ++) + de->dev->dev_addr[i] = ee_data[i + sa_offset]; + + /* get offset of controller 0 info leaf. ignore 2nd byte. */ + ofs = ee_data[SROMC0InfoLeaf]; + if (ofs >= (sizeof(ee_data) - sizeof(struct de_srom_info_leaf) - sizeof(struct de_srom_media_block))) + goto bad_srom; + + /* get pointer to info leaf */ + il = (struct de_srom_info_leaf *) &ee_data[ofs]; + + /* paranoia checks */ + if (il->n_blocks == 0) + goto bad_srom; + if ((sizeof(ee_data) - ofs) < + (sizeof(struct de_srom_info_leaf) + (sizeof(struct de_srom_media_block) * il->n_blocks))) + goto bad_srom; + + /* get default media type */ + switch (il->default_media) { + case 0x0001: de->media_type = DE_MEDIA_BNC; break; + case 0x0002: de->media_type = DE_MEDIA_AUI; break; + case 0x0204: de->media_type = DE_MEDIA_TP_FD; break; + default: de->media_type = DE_MEDIA_TP_AUTO; break; + } + + /* init SIA register values to defaults */ + for (i = 0; i < DE_MAX_MEDIA; i++) { + de->media[i].type = DE_MEDIA_INVALID; + de->media[i].csr13 = 0xffff; + de->media[i].csr14 = 0xffff; + de->media[i].csr15 = 0xffff; + } + + /* parse media blocks to see what medias are supported, + * and if any custom CSR values are provided + */ + for (i = 0; i < il->n_blocks; i++) { + struct de_srom_media_block *ib = &il[i].media[0]; + unsigned idx; + + /* index based on media type in media block */ + switch(ib->opts & MediaBlockMask) { + case 0: /* 10baseT */ + de->media_supported |= SUPPORTED_TP | SUPPORTED_10baseT_Half + | SUPPORTED_Autoneg; + idx = DE_MEDIA_TP; + de->media[DE_MEDIA_TP_AUTO].type = DE_MEDIA_TP_AUTO; + break; + case 1: /* BNC */ + de->media_supported |= SUPPORTED_BNC; + idx = DE_MEDIA_BNC; + break; + case 2: /* AUI */ + de->media_supported |= SUPPORTED_AUI; + idx = DE_MEDIA_AUI; + break; + case 4: /* 10baseT-FD */ + de->media_supported |= SUPPORTED_TP | SUPPORTED_10baseT_Full + | SUPPORTED_Autoneg; + idx = DE_MEDIA_TP_FD; + de->media[DE_MEDIA_TP_AUTO].type = DE_MEDIA_TP_AUTO; + break; + default: + goto bad_srom; + } + + if (ib->opts & MediaCustomCSRs) { + de->media[idx].csr13 = ib->csr13; + de->media[idx].csr14 = ib->csr14; + de->media[idx].csr15 = ib->csr15; + } + + de->media[idx].type = idx; + de->media_advertise |= de->media_supported; + } + +fill_defaults: + /* fill in defaults, for cases where custom CSRs not used */ + for (i = 0; i < DE_MAX_MEDIA; i++) { + if (de->media[i].csr13 == 0xffff) + de->media[i].csr13 = t21041_csr13[i]; + if (de->media[i].csr14 == 0xffff) + de->media[i].csr14 = t21041_csr14[i]; + if (de->media[i].csr15 == 0xffff) + de->media[i].csr15 = t21041_csr15[i]; + } + + if (netif_msg_link(de)) + printk(KERN_INFO "de%d: SROM-listed ports: %s%s%s\n", + de->board_idx, + de->media_supported & SUPPORTED_TP ? "TP " : "", + de->media_supported & SUPPORTED_BNC ? "BNC " : "", + de->media_supported & SUPPORTED_AUI ? "AUI" : ""); + + return; + +bad_srom: + /* for error cases, it's ok to assume we support all these */ + for (i = 0; i < DE_MAX_MEDIA; i++) + de->media[i].type = i; + de->media_supported = + SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_TP | + SUPPORTED_AUI | + SUPPORTED_BNC; + goto fill_defaults; +} + +static int __init de_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct net_device *dev; + struct de_private *de; + int rc; + void *regs; + long pciaddr; + static int board_idx = -1; + + board_idx++; + +#ifndef MODULE + if (board_idx == 0) + printk("%s", version); +#endif + + /* allocate a new ethernet device structure, and fill in defaults */ + dev = alloc_etherdev(sizeof(struct de_private)); + if (!dev) + return -ENOMEM; + + SET_MODULE_OWNER(dev); + dev->open = de_open; + dev->stop = de_close; + dev->set_multicast_list = de_set_rx_mode; + dev->hard_start_xmit = de_start_xmit; + dev->get_stats = de_get_stats; + dev->do_ioctl = de_ioctl; + dev->tx_timeout = de_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + dev->irq = pdev->irq; + + de = dev->priv; + de->de21040 = ent->driver_data == 0 ? 1 : 0; + de->pdev = pdev; + de->dev = dev; + de->msg_enable = (debug < 0 ? DE_DEF_MSG_ENABLE : debug); + de->board_idx = board_idx; + spin_lock_init (&de->lock); + init_timer(&de->media_timer); + if (de->de21040) + de->media_timer.function = de21040_media_timer; + else + de->media_timer.function = de21041_media_timer; + de->media_timer.data = (unsigned long) de; + + netif_carrier_off(dev); + netif_stop_queue(dev); + + /* wake up device, assign resources */ + rc = pci_enable_device(pdev); + if (rc) + goto err_out_free; + + /* reserve PCI resources to ensure driver atomicity */ + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) + goto err_out_disable; + + /* check for invalid IRQ value */ + if (pdev->irq < 2) { + rc = -EIO; + printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n", + pdev->irq, pdev->slot_name); + goto err_out_res; + } + + /* obtain and check validity of PCI I/O address */ + pciaddr = pci_resource_start(pdev, 1); + if (!pciaddr) { + rc = -EIO; + printk(KERN_ERR PFX "no MMIO resource for pci dev %s\n", + pdev->slot_name); + goto err_out_res; + } + if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) { + rc = -EIO; + printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", + pci_resource_len(pdev, 1), pdev->slot_name); + goto err_out_res; + } + + /* remap CSR registers */ + regs = ioremap_nocache(pciaddr, DE_REGS_SIZE); + if (!regs) { + rc = -EIO; + printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", + pci_resource_len(pdev, 1), pciaddr, pdev->slot_name); + goto err_out_res; + } + dev->base_addr = (unsigned long) regs; + de->regs = regs; + + de_adapter_wake(de); + + /* make sure hardware is not running */ + de_stop_hw(de); + + /* get MAC address, and some register values related to media types */ + if (de->de21040) { + unsigned i; + + de21040_get_mac_address(de); + + de->media_type = DE_MEDIA_TP; + de->media_supported |= SUPPORTED_TP | SUPPORTED_10baseT_Full | + SUPPORTED_10baseT_Half | SUPPORTED_AUI; + de->media_advertise = de->media_supported; + for (i = 0; i < DE_MAX_MEDIA; i++) { + switch (i) { + case DE_MEDIA_AUI: + case DE_MEDIA_TP: + case DE_MEDIA_TP_FD: + de->media[i].type = i; + de->media[i].csr13 = t21040_csr13[i]; + de->media[i].csr14 = t21040_csr14[i]; + de->media[i].csr15 = t21040_csr15[i]; + break; + default: + de->media[i].type = DE_MEDIA_INVALID; + break; + } + } + } else { + tulip_get_srom_info(de); + } + + /* register new network interface with kernel */ + rc = register_netdev(dev); + if (rc) + goto err_out_iomap; + + /* print info about board and interface just registered */ + printk (KERN_INFO "%s: %s at 0x%lx, " + "%02x:%02x:%02x:%02x:%02x:%02x, " + "IRQ %d\n", + dev->name, + de->de21040 ? "21040" : "21041", + dev->base_addr, + dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], + dev->dev_addr[4], dev->dev_addr[5], + dev->irq); + + pci_set_drvdata(pdev, dev); + + /* enable busmastering */ + pci_set_master(pdev); + + /* put adapter to sleep */ + de_adapter_sleep(de); + + return 0; + +err_out_iomap: + iounmap(regs); +err_out_res: + pci_release_regions(pdev); +err_out_disable: + pci_disable_device(pdev); +err_out_free: + kfree(dev); + return rc; +} + +static void __exit de_remove_one (struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct de_private *de = dev->priv; + + if (!dev) + BUG(); + unregister_netdev(dev); + iounmap(de->regs); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + kfree(dev); +} + +#ifdef CONFIG_PM + +static int de_suspend (struct pci_dev *pdev, u32 state) +{ + struct net_device *dev = pci_get_drvdata (pdev); + struct de_private *de = dev->priv; + + rtnl_lock(); + if (netif_running (dev)) { + del_timer_sync(&de->media_timer); + + disable_irq(dev->irq); + spin_lock_irq(&de->lock); + + de_stop_hw(de); + netif_stop_queue(dev); + netif_device_detach(dev); + netif_carrier_off(dev); + + spin_unlock_irq(&de->lock); + enable_irq(dev->irq); + + /* Update the error counts. */ + __de_get_stats(de); + + synchronize_irq(); + de_clean_rings(de); + + de_adapter_sleep(de); + pci_disable_device(pdev); + } else { + netif_device_detach(dev); + } + rtnl_unlock(); + return 0; +} + +static int de_resume (struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata (pdev); + struct de_private *de = dev->priv; + + rtnl_lock(); + if (netif_device_present(dev)) + goto out; + if (netif_running(dev)) { + pci_enable_device(pdev); + de_init_hw(de); + netif_device_attach(dev); + } else { + netif_device_attach(dev); + } +out: + rtnl_unlock(); + return 0; +} + +#endif /* CONFIG_PM */ + +static struct pci_driver de_driver = { + name: DRV_NAME, + id_table: de_pci_tbl, + probe: de_init_one, + remove: de_remove_one, +#ifdef CONFIG_PM + suspend: de_suspend, + resume: de_resume, +#endif +}; + +static int __init de_init (void) +{ +#ifdef MODULE + printk("%s", version); +#endif + return pci_module_init (&de_driver); +} + +static void __exit de_exit (void) +{ + pci_unregister_driver (&de_driver); +} + +module_init(de_init); +module_exit(de_exit); diff -u --recursive --new-file v2.5.0/linux/drivers/net/fc/iph5526.c linux/drivers/net/fc/iph5526.c --- v2.5.0/linux/drivers/net/fc/iph5526.c Sun Sep 30 12:26:08 2001 +++ linux/drivers/net/fc/iph5526.c Wed Nov 28 10:22:27 2001 @@ -3802,7 +3802,6 @@ fi->host = host; //host->max_id = MAX_SCSI_TARGETS; host->max_id = 5; - host->hostt->use_new_eh_code = 1; host->this_id = tmpt->this_id; pci_maddr = pci_resource_start(pdev, 0); diff -u --recursive --new-file v2.5.0/linux/drivers/net/hamradio/baycom_epp.c linux/drivers/net/hamradio/baycom_epp.c --- v2.5.0/linux/drivers/net/hamradio/baycom_epp.c Mon Sep 10 09:04:53 2001 +++ linux/drivers/net/hamradio/baycom_epp.c Sun Nov 25 09:48:47 2001 @@ -807,10 +807,11 @@ /* --------------------------------------------------------------------- */ #ifdef __i386__ +#include #define GETTICK(x) \ ({ \ if (cpu_has_tsc) \ - __asm__ __volatile__("rdtsc" : "=a" (x) : : "dx");\ + rdtscl(x); \ }) #else /* __i386__ */ #define GETTICK(x) diff -u --recursive --new-file v2.5.0/linux/drivers/net/irda/irda-usb.c linux/drivers/net/irda/irda-usb.c --- v2.5.0/linux/drivers/net/irda/irda-usb.c Fri Nov 9 14:22:17 2001 +++ linux/drivers/net/irda/irda-usb.c Sat Dec 8 20:28:45 2001 @@ -256,7 +256,7 @@ /* Grab the speed URB */ purb = &self->speed_urb; - if (purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { WARNING(__FUNCTION__ "(), URB still in use!\n"); return; } @@ -301,7 +301,7 @@ } /* Check for timeout and other USB nasties */ - if(purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { /* I get a lot of -ECONNABORTED = -103 here - Jean II */ IRDA_DEBUG(0, __FUNCTION__ "(), URB complete status %d, transfer_flags 0x%04X\n", purb->status, purb->transfer_flags); @@ -314,7 +314,7 @@ } /* urb is now available */ - purb->status = USB_ST_NOERROR; + purb->status = 0; /* If it was the speed URB, allow the stack to send more packets */ if(purb == &self->speed_urb) { @@ -372,7 +372,7 @@ } } - if (purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { WARNING(__FUNCTION__ "(), URB still in use!\n"); dev_kfree_skb(skb); return 0; @@ -490,7 +490,7 @@ purb->context = NULL; /* Check for timeout and other USB nasties */ - if(purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { /* I get a lot of -ECONNABORTED = -103 here - Jean II */ IRDA_DEBUG(0, __FUNCTION__ "(), URB complete status %d, transfer_flags 0x%04X\n", purb->status, purb->transfer_flags); @@ -504,7 +504,7 @@ } /* urb is now available */ - purb->status = USB_ST_NOERROR; + purb->status = 0; /* If the network is closed, stop everything */ if ((!self->netopen) || (!self->present)) { @@ -547,11 +547,11 @@ /* Check speed URB */ purb = &(self->speed_urb); - if (purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { IRDA_DEBUG(0, "%s: Speed change timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags); switch (purb->status) { - case USB_ST_URB_PENDING: /* -EINPROGRESS == -115 */ + case -EINPROGRESS: usb_unlink_urb(purb); /* Note : above will *NOT* call netif_wake_queue() * in completion handler, we will come back here. @@ -563,7 +563,7 @@ case -ETIMEDOUT: /* -110 */ case -ENOENT: /* -2 (urb unlinked by us) */ default: /* ??? - Play safe */ - purb->status = USB_ST_NOERROR; + purb->status = 0; netif_wake_queue(self->netdev); done = 1; break; @@ -572,7 +572,7 @@ /* Check Tx URB */ purb = &(self->tx_urb); - if (purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { struct sk_buff *skb = purb->context; IRDA_DEBUG(0, "%s: Tx timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags); @@ -590,7 +590,7 @@ #endif /* IU_BUG_KICK_TIMEOUT */ switch (purb->status) { - case USB_ST_URB_PENDING: /* -EINPROGRESS == -115 */ + case -EINPROGRESS: usb_unlink_urb(purb); /* Note : above will *NOT* call netif_wake_queue() * in completion handler, because purb->status will @@ -610,7 +610,7 @@ dev_kfree_skb_any(skb); purb->context = NULL; } - purb->status = USB_ST_NOERROR; + purb->status = 0; netif_wake_queue(self->netdev); done = 1; break; @@ -727,7 +727,7 @@ purb->transfer_flags = USB_QUEUE_BULK; /* Note : unlink *must* be synchronous because of the code in * irda_usb_net_close() -> free the skb - Jean II */ - purb->status = USB_ST_NOERROR; + purb->status = 0; purb->next = NULL; /* Don't auto resubmit URBs */ ret = usb_submit_urb(purb); @@ -768,9 +768,9 @@ } /* Check the status */ - if(purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { switch (purb->status) { - case USB_ST_CRC: /* -EILSEQ */ + case -EILSEQ: self->stats.rx_errors++; self->stats.rx_crc_errors++; break; @@ -1442,9 +1442,9 @@ ret = usb_set_interface(dev, ifnum, 0); IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", ifnum, ret); switch (ret) { - case USB_ST_NOERROR: /* 0 */ + case 0: break; - case USB_ST_STALL: /* -EPIPE = -32 */ + case -EPIPE: /* -EPIPE = -32 */ usb_clear_halt(dev, usb_sndctrlpipe(dev, 0)); IRDA_DEBUG(0, __FUNCTION__ "(), Clearing stall on control interface\n" ); break; diff -u --recursive --new-file v2.5.0/linux/drivers/net/irda/vlsi_ir.c linux/drivers/net/irda/vlsi_ir.c --- v2.5.0/linux/drivers/net/irda/vlsi_ir.c Fri Nov 9 13:41:42 2001 +++ linux/drivers/net/irda/vlsi_ir.c Fri Nov 30 13:25:10 2001 @@ -2,7 +2,7 @@ * * vlsi_ir.c: VLSI82C147 PCI IrDA controller driver for Linux * - * Version: 0.3, Sep 30, 2001 + * Version: 0.3a, Nov 10, 2001 * * Copyright (c) 2001 Martin Diehl * @@ -490,7 +490,7 @@ if (mode == IFF_FIR) config ^= IRENABLE_FIR_ON; else if (mode == IFF_MIR) - config ^= (IRENABLE_FIR_ON|IRENABLE_CRC16_ON); + config ^= (IRENABLE_MIR_ON|IRENABLE_CRC16_ON); else config ^= IRENABLE_SIR_ON; @@ -877,6 +877,7 @@ idev->irlap = irlap_open(ndev,&idev->qos,hwname); netif_start_queue(ndev); + outw(0, ndev->base_addr+VLSI_PIO_PROMPT); /* kick hw state machine */ printk(KERN_INFO "%s: device %s operational using (%d,%d) tx,rx-ring\n", __FUNCTION__, ndev->name, ringsize[0], ringsize[1]); @@ -1200,7 +1201,6 @@ int alloc_size; - vlsi_reg_debug(0x3000, "vlsi initial state"); if (pci_enable_device(pdev)) goto out; diff -u --recursive --new-file v2.5.0/linux/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c --- v2.5.0/linux/drivers/net/ppp_generic.c Thu Oct 11 09:18:31 2001 +++ linux/drivers/net/ppp_generic.c Fri Nov 30 08:26:04 2001 @@ -325,7 +325,6 @@ { struct ppp_file *pf = (struct ppp_file *) file->private_data; - lock_kernel(); if (pf != 0) { file->private_data = 0; if (atomic_dec_and_test(&pf->refcnt)) { @@ -339,7 +338,6 @@ } } } - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c --- v2.5.0/linux/drivers/net/smc-ultra.c Sun Sep 30 12:26:07 2001 +++ linux/drivers/net/smc-ultra.c Sun Nov 25 09:43:42 2001 @@ -80,7 +80,7 @@ int ultra_probe(struct net_device *dev); static int ultra_probe1(struct net_device *dev, int ioaddr); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ static int ultra_probe_isapnp(struct net_device *dev); #endif @@ -100,7 +100,7 @@ const unsigned char *buf, const int start_page); static int ultra_close_card(struct net_device *dev); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ static struct isapnp_device_id ultra_device_ids[] __initdata = { { ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416), ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416), @@ -140,7 +140,7 @@ else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ /* Look for any installed ISAPnP cards */ if (isapnp_present() && (ultra_probe_isapnp(dev) == 0)) return 0; @@ -279,7 +279,7 @@ return retval; } -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ static int __init ultra_probe_isapnp(struct net_device *dev) { int i; @@ -544,7 +544,7 @@ /* NB: ultra_close_card() does free_irq */ int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ struct pci_dev *idev = (struct pci_dev *)ei_status.priv; if (idev) idev->deactivate(idev); diff -u --recursive --new-file v2.5.0/linux/drivers/net/tlan.c linux/drivers/net/tlan.c --- v2.5.0/linux/drivers/net/tlan.c Sun Sep 30 12:26:08 2001 +++ linux/drivers/net/tlan.c Tue Nov 27 09:23:27 2001 @@ -2265,8 +2265,8 @@ printk("TLAN: Partner capability: "); for (i = 5; i <= 10; i++) if (partner & (1<base_addr, TLAN_LED_REG, TLAN_LED_LINK ); diff -u --recursive --new-file v2.5.0/linux/drivers/net/tulip/ChangeLog linux/drivers/net/tulip/ChangeLog --- v2.5.0/linux/drivers/net/tulip/ChangeLog Mon Nov 19 15:19:42 2001 +++ linux/drivers/net/tulip/ChangeLog Tue Dec 11 10:47:49 2001 @@ -1,3 +1,8 @@ +2001-12-11 Jeff Garzik + + * eeprom.c, timer.c, media.c, tulip_core.c: + Remove 21040 and 21041 chip support. + 2001-11-13 David S. Miller * tulip_core.c (tulip_mwi_config): Kill unused label early_out. diff -u --recursive --new-file v2.5.0/linux/drivers/net/tulip/eeprom.c linux/drivers/net/tulip/eeprom.c --- v2.5.0/linux/drivers/net/tulip/eeprom.c Tue Oct 2 09:00:58 2001 +++ linux/drivers/net/tulip/eeprom.c Tue Dec 11 10:47:49 2001 @@ -136,23 +136,6 @@ subsequent_board: if (ee_data[27] == 0) { /* No valid media table. */ - } else if (tp->chip_id == DC21041) { - unsigned char *p = (void *)ee_data + ee_data[27 + controller_index*3]; - int media = get_u16(p); - int count = p[2]; - p += 3; - - printk(KERN_INFO "%s: 21041 Media table, default media %4.4x (%s).\n", - dev->name, media, - media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]); - for (i = 0; i < count; i++) { - unsigned char media_block = *p++; - int media_code = media_block & MEDIA_MASK; - if (media_block & 0x40) - p += 6; - printk(KERN_INFO "%s: 21041 media #%d, %s.\n", - dev->name, media_code, medianame[media_code]); - } } else { unsigned char *p = (void *)ee_data + ee_data[27]; unsigned char csr12dir = 0; diff -u --recursive --new-file v2.5.0/linux/drivers/net/tulip/media.c linux/drivers/net/tulip/media.c --- v2.5.0/linux/drivers/net/tulip/media.c Tue Jul 17 18:53:55 2001 +++ linux/drivers/net/tulip/media.c Tue Dec 11 10:47:49 2001 @@ -21,12 +21,6 @@ #include "tulip.h" -/* This is a mysterious value that can be written to CSR11 in the 21040 (only) - to support a pre-NWay full-duplex signaling mechanism using short frames. - No one knows what it should be, but if left at its default value some - 10base2(!) packets trigger a full-duplex-request interrupt. */ -#define FULL_DUPLEX_MAGIC 0x6969 - /* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually met by back-to-back PCI I/O cycles, but we insert a delay to avoid "overclocking" issues or future 66Mhz PCI. */ @@ -326,17 +320,6 @@ printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %2.2x.\n", dev->name, medianame[dev->if_port], inl(ioaddr + CSR12) & 0xff); - } else if (tp->chip_id == DC21041) { - int port = dev->if_port <= 4 ? dev->if_port : 0; - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: 21041 using media %s, CSR12 is %4.4x.\n", - dev->name, medianame[port == 3 ? 12: port], - inl(ioaddr + CSR12)); - outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */ - outl(t21041_csr14[port], ioaddr + CSR14); - outl(t21041_csr15[port], ioaddr + CSR15); - outl(t21041_csr13[port], ioaddr + CSR13); - new_csr6 = 0x80020000; } else if (tp->chip_id == LC82C168) { if (startup && ! tp->medialock) dev->if_port = tp->mii_cnt ? 11 : 0; @@ -363,26 +346,6 @@ new_csr6 = 0x00420000; outl(0x1F078, ioaddr + 0xB8); } - } else if (tp->chip_id == DC21040) { /* 21040 */ - /* Turn on the xcvr interface. */ - int csr12 = inl(ioaddr + CSR12); - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: 21040 media type is %s, CSR12 is %2.2x.\n", - dev->name, medianame[dev->if_port], csr12); - if (tulip_media_cap[dev->if_port] & MediaAlwaysFD) - tp->full_duplex = 1; - new_csr6 = 0x20000; - /* Set the full duplux match frame. */ - outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11); - outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */ - if (t21040_csr13[dev->if_port] & 8) { - outl(0x0705, ioaddr + CSR14); - outl(0x0006, ioaddr + CSR15); - } else { - outl(0xffff, ioaddr + CSR14); - outl(0x0000, ioaddr + CSR15); - } - outl(0x8f01 | t21040_csr13[dev->if_port], ioaddr + CSR13); } else { /* Unknown chip type with no media table. */ if (tp->default_port == 0) dev->if_port = tp->mii_cnt ? 11 : 3; diff -u --recursive --new-file v2.5.0/linux/drivers/net/tulip/timer.c linux/drivers/net/tulip/timer.c --- v2.5.0/linux/drivers/net/tulip/timer.c Wed Jun 20 11:15:44 2001 +++ linux/drivers/net/tulip/timer.c Tue Dec 11 10:47:49 2001 @@ -33,60 +33,6 @@ inl(ioaddr + CSR14), inl(ioaddr + CSR15)); } switch (tp->chip_id) { - case DC21040: - if (!tp->medialock && csr12 & 0x0002) { /* Network error */ - printk(KERN_INFO "%s: No link beat found.\n", - dev->name); - dev->if_port = (dev->if_port == 2 ? 0 : 2); - tulip_select_media(dev, 0); - dev->trans_start = jiffies; - } - break; - case DC21041: - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: 21041 media tick CSR12 %8.8x.\n", - dev->name, csr12); - if (tp->medialock) break; - switch (dev->if_port) { - case 0: case 3: case 4: - if (csr12 & 0x0004) { /*LnkFail */ - /* 10baseT is dead. Check for activity on alternate port. */ - tp->mediasense = 1; - if (csr12 & 0x0200) - dev->if_port = 2; - else - dev->if_port = 1; - printk(KERN_INFO "%s: No 21041 10baseT link beat, Media switched to %s.\n", - dev->name, medianame[dev->if_port]); - outl(0, ioaddr + CSR13); /* Reset */ - outl(t21041_csr14[dev->if_port], ioaddr + CSR14); - outl(t21041_csr15[dev->if_port], ioaddr + CSR15); - outl(t21041_csr13[dev->if_port], ioaddr + CSR13); - next_tick = 10*HZ; /* 2.4 sec. */ - } else - next_tick = 30*HZ; - break; - case 1: /* 10base2 */ - case 2: /* AUI */ - if (csr12 & 0x0100) { - next_tick = (30*HZ); /* 30 sec. */ - tp->mediasense = 0; - } else if ((csr12 & 0x0004) == 0) { - printk(KERN_INFO "%s: 21041 media switched to 10baseT.\n", - dev->name); - dev->if_port = 0; - tulip_select_media(dev, 0); - next_tick = (24*HZ)/10; /* 2.4 sec. */ - } else if (tp->mediasense || (csr12 & 0x0002)) { - dev->if_port = 3 - dev->if_port; /* Swap ports. */ - tulip_select_media(dev, 0); - next_tick = 20*HZ; - } else { - next_tick = 20*HZ; - } - break; - } - break; case DC21140: case DC21142: case MX98713: diff -u --recursive --new-file v2.5.0/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c --- v2.5.0/linux/drivers/net/tulip/tulip_core.c Mon Nov 19 15:19:42 2001 +++ linux/drivers/net/tulip/tulip_core.c Tue Dec 11 10:47:49 2001 @@ -15,8 +15,8 @@ */ #define DRV_NAME "tulip" -#define DRV_VERSION "0.9.15-pre9" -#define DRV_RELDATE "Nov 6, 2001" +#define DRV_VERSION "1.1.0" +#define DRV_RELDATE "Dec 11, 2001" #include #include @@ -130,12 +130,8 @@ */ struct tulip_chip_table tulip_tbl[] = { - /* DC21040 */ - { "Digital DC21040 Tulip", 128, 0x0001ebef, 0, tulip_timer }, - - /* DC21041 */ - { "Digital DC21041 Tulip", 128, 0x0001ebef, - HAS_MEDIA_TABLE | HAS_NWAY, tulip_timer }, + { }, /* placeholder for array, slot unused currently */ + { }, /* placeholder for array, slot unused currently */ /* DC21140 */ { "Digital DS21140 Tulip", 128, 0x0001ebef, @@ -192,8 +188,6 @@ static struct pci_device_id tulip_pci_tbl[] __devinitdata = { - { 0x1011, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21040 }, - { 0x1011, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21041 }, { 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 }, { 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21143 }, { 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 }, @@ -224,19 +218,6 @@ /* A full-duplex map for media types. */ const char tulip_media_cap[32] = {0,0,0,16, 3,19,16,24, 27,4,7,5, 0,20,23,20, 28,31,0,0, }; -u8 t21040_csr13[] = {2,0x0C,8,4, 4,0,0,0, 0,0,0,0, 4,0,0,0}; - -/* 21041 transceiver register settings: 10-T, 10-2, AUI, 10-T, 10T-FD*/ -u16 t21041_csr13[] = { - csr13_mask_10bt, /* 10-T */ - csr13_mask_auibnc, /* 10-2 */ - csr13_mask_auibnc, /* AUI */ - csr13_mask_10bt, /* 10-T */ - csr13_mask_10bt, /* 10T-FD */ -}; -u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, }; -u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; - static void tulip_tx_timeout(struct net_device *dev); static void tulip_init_ring(struct net_device *dev); @@ -388,19 +369,6 @@ outl(0x0008, ioaddr + CSR15); } tulip_select_media(dev, 1); - } else if (tp->chip_id == DC21041) { - dev->if_port = 0; - tp->nway = tp->mediasense = 1; - tp->nwayset = tp->lpar = 0; - outl(0x00000000, ioaddr + CSR13); - outl(0xFFFFFFFF, ioaddr + CSR14); - outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ - tp->csr6 = 0x80020000; - if (tp->sym_advertise & 0x0040) - tp->csr6 |= FullDuplex; - outl(tp->csr6, ioaddr + CSR6); - outl(0x0000EF01, ioaddr + CSR13); - } else if (tp->chip_id == DC21142) { if (tp->mii_cnt) { tulip_select_media(dev, 1); @@ -538,33 +506,6 @@ if (tulip_debug > 1) printk(KERN_WARNING "%s: Transmit timeout using MII device.\n", dev->name); - } else if (tp->chip_id == DC21040) { - if ( !tp->medialock && inl(ioaddr + CSR12) & 0x0002) { - dev->if_port = (dev->if_port == 2 ? 0 : 2); - printk(KERN_INFO "%s: 21040 transmit timed out, switching to " - "%s.\n", - dev->name, medianame[dev->if_port]); - tulip_select_media(dev, 0); - } - goto out; - } else if (tp->chip_id == DC21041) { - int csr12 = inl(ioaddr + CSR12); - - printk(KERN_WARNING "%s: 21041 transmit timed out, status %8.8x, " - "CSR12 %8.8x, CSR13 %8.8x, CSR14 %8.8x, resetting...\n", - dev->name, inl(ioaddr + CSR5), csr12, - inl(ioaddr + CSR13), inl(ioaddr + CSR14)); - tp->mediasense = 1; - if ( ! tp->medialock) { - if (dev->if_port == 1 || dev->if_port == 2) - if (csr12 & 0x0004) { - dev->if_port = 2 - dev->if_port; - } else - dev->if_port = 0; - else - dev->if_port = 1; - tulip_select_media(dev, 0); - } } else if (tp->chip_id == DC21140 || tp->chip_id == DC21142 || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881 || tp->chip_id == DM910X) { @@ -636,7 +577,6 @@ tp->stats.tx_errors++; -out: spin_unlock_irqrestore (&tp->lock, flags); dev->trans_start = jiffies; netif_wake_queue (dev); @@ -802,10 +742,6 @@ /* release any unconsumed transmit buffers */ tulip_clean_tx_ring(tp); - /* 21040 -- Leave the card in 10baseT state. */ - if (tp->chip_id == DC21040) - outl (0x00000004, ioaddr + CSR13); - if (inl (ioaddr + CSR6) != 0xffffffff) tp->stats.rx_missed_errors += inl (ioaddr + CSR8) & 0xffff; @@ -966,16 +902,14 @@ 0x1848 + ((csr12&0x7000) == 0x5000 ? 0x20 : 0) + ((csr12&0x06) == 6 ? 0 : 4); - if (tp->chip_id != DC21041) - data->val_out |= 0x6048; + data->val_out |= 0x6048; break; case 4: /* Advertised value, bogus 10baseTx-FD value from CSR6. */ data->val_out = ((inl(ioaddr + CSR6) >> 3) & 0x0040) + ((csr14 >> 1) & 0x20) + 1; - if (tp->chip_id != DC21041) - data->val_out |= ((csr14 >> 9) & 0x03C0); + data->val_out |= ((csr14 >> 9) & 0x03C0); break; case 5: data->val_out = tp->lpar; break; default: data->val_out = 0; break; @@ -1358,7 +1292,6 @@ long ioaddr; static int board_idx = -1; int chip_idx = ent->driver_data; - unsigned int t2104x_mode = 0; unsigned int eeprom_missing = 0; unsigned int force_csr0 = 0; @@ -1527,31 +1460,12 @@ /* Clear the missed-packet counter. */ inl(ioaddr + CSR8); - if (chip_idx == DC21041) { - if (inl(ioaddr + CSR9) & 0x8000) { - chip_idx = DC21040; - t2104x_mode = 1; - } else { - t2104x_mode = 2; - } - } - /* The station address ROM is read byte serially. The register must be polled, waiting for the value to be read bit serially from the EEPROM. */ sum = 0; - if (chip_idx == DC21040) { - outl(0, ioaddr + CSR9); /* Reset the pointer with a dummy write. */ - for (i = 0; i < 6; i++) { - int value, boguscnt = 100000; - do - value = inl(ioaddr + CSR9); - while (value < 0 && --boguscnt > 0); - dev->dev_addr[i] = value; - sum += value & 0xff; - } - } else if (chip_idx == LC82C168) { + if (chip_idx == LC82C168) { for (i = 0; i < 3; i++) { int value, boguscnt = 100000; outl(0x600 | i, ioaddr + 0x98); @@ -1719,10 +1633,6 @@ dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr); pci_set_drvdata(pdev, dev); - if (t2104x_mode == 1) - printk(" 21040 compatible mode,"); - else if (t2104x_mode == 2) - printk(" 21041 mode,"); if (eeprom_missing) printk(" EEPROM not present,"); for (i = 0; i < 6; i++) @@ -1731,26 +1641,13 @@ if (tp->chip_id == PNIC2) tp->link_change = pnic2_lnk_change; - else if ((tp->flags & HAS_NWAY) || tp->chip_id == DC21041) + else if (tp->flags & HAS_NWAY) tp->link_change = t21142_lnk_change; else if (tp->flags & HAS_PNICNWAY) tp->link_change = pnic_lnk_change; /* Reset the xcvr interface and turn on heartbeat. */ switch (chip_idx) { - case DC21041: - if (tp->sym_advertise == 0) - tp->sym_advertise = 0x0061; - outl(0x00000000, ioaddr + CSR13); - outl(0xFFFFFFFF, ioaddr + CSR14); - outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ - outl(inl(ioaddr + CSR6) | csr6_fd, ioaddr + CSR6); - outl(0x0000EF01, ioaddr + CSR13); - break; - case DC21040: - outl(0x00000000, ioaddr + CSR13); - outl(0x00000004, ioaddr + CSR13); - break; case DC21140: case DM910X: default: diff -u --recursive --new-file v2.5.0/linux/drivers/net/wan/cosa.c linux/drivers/net/wan/cosa.c --- v2.5.0/linux/drivers/net/wan/cosa.c Thu Sep 13 16:04:43 2001 +++ linux/drivers/net/wan/cosa.c Fri Nov 30 08:26:04 2001 @@ -974,13 +974,11 @@ struct cosa_data *cosa; unsigned long flags; - lock_kernel(); cosa = channel->cosa; spin_lock_irqsave(&cosa->lock, flags); cosa->usage--; channel->usage--; spin_unlock_irqrestore(&cosa->lock, flags); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/pci/setup-res.c linux/drivers/pci/setup-res.c --- v2.5.0/linux/drivers/pci/setup-res.c Thu Oct 4 18:47:08 2001 +++ linux/drivers/pci/setup-res.c Mon Nov 26 14:23:58 2001 @@ -219,9 +219,8 @@ cmd |= PCI_COMMAND_IO; } - /* ??? Always turn on bus mastering. If the device doesn't support - it, the bit will go into the bucket. */ - cmd |= PCI_COMMAND_MASTER; + /* Do not enable bus mastering. A device could corrupt + * system memory by DMAing before a driver is ready for it. */ /* Set the cache line and default latency (32). */ pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, diff -u --recursive --new-file v2.5.0/linux/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c --- v2.5.0/linux/drivers/pcmcia/ds.c Mon Nov 12 09:39:01 2001 +++ linux/drivers/pcmcia/ds.c Fri Nov 30 08:26:04 2001 @@ -597,7 +597,6 @@ DEBUG(0, "ds_release(socket %d)\n", i); if ((i >= sockets) || (sockets == 0)) return 0; - lock_kernel(); s = &socket_table[i]; user = file->private_data; if (CHECK_USER(user)) @@ -615,7 +614,6 @@ user->user_magic = 0; kfree(user); out: - unlock_kernel(); return 0; } /* ds_release */ diff -u --recursive --new-file v2.5.0/linux/drivers/pcmcia/i82365.c linux/drivers/pcmcia/i82365.c --- v2.5.0/linux/drivers/pcmcia/i82365.c Mon Nov 12 09:39:01 2001 +++ linux/drivers/pcmcia/i82365.c Sun Nov 25 09:43:42 2001 @@ -813,11 +813,7 @@ #ifdef CONFIG_ISA -#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE)) -#define I82365_ISAPNP -#endif - -#ifdef I82365_ISAPNP +#ifdef __ISAPNP__ static struct isapnp_device_id id_table[] __initdata = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_FUNCTION(0x0e00), (unsigned long) "Intel 82365-Compatible" }, @@ -836,7 +832,7 @@ { int i, j, sock, k, ns, id; ioaddr_t port; -#ifdef I82365_ISAPNP +#ifdef __ISAPNP__ struct isapnp_device_id *devid; struct pci_dev *dev; @@ -1647,7 +1643,7 @@ i365_set(i, I365_CSCINT, 0); release_region(socket[i].ioaddr, 2); } -#if defined(CONFIG_ISA) && defined(I82365_ISAPNP) +#if defined(CONFIG_ISA) && defined(__ISAPNP__) if (i82365_pnpdev && i82365_pnpdev->deactivate) i82365_pnpdev->deactivate(i82365_pnpdev); #endif diff -u --recursive --new-file v2.5.0/linux/drivers/pnp/isapnp_proc.c linux/drivers/pnp/isapnp_proc.c --- v2.5.0/linux/drivers/pnp/isapnp_proc.c Wed Jan 17 13:29:14 2001 +++ linux/drivers/pnp/isapnp_proc.c Fri Nov 30 08:26:04 2001 @@ -170,12 +170,10 @@ kfree(buffer); return -ENOMEM; } - lock_kernel(); buffer->curr = buffer->buffer; file->private_data = buffer; if (mode == O_RDONLY) isapnp_info_read(buffer); - unlock_kernel(); return 0; } @@ -187,12 +185,10 @@ if ((buffer = (isapnp_info_buffer_t *) file->private_data) == NULL) return -EINVAL; mode = file->f_flags & O_ACCMODE; - lock_kernel(); if (mode == O_WRONLY) isapnp_info_write(buffer); vfree(buffer->buffer); kfree(buffer); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c --- v2.5.0/linux/drivers/s390/block/dasd.c Fri Nov 9 14:05:02 2001 +++ linux/drivers/s390/block/dasd.c Sat Dec 8 20:02:47 2001 @@ -730,13 +730,6 @@ goto out_hardsect_size; memset (hardsect_size[major], 0, (1 << MINORBITS) * sizeof (int)); - /* init max_sectors */ - max_sectors[major] = - (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC); - if (!max_sectors[major]) - goto out_max_sectors; - memset (max_sectors[major], 0, (1 << MINORBITS) * sizeof (int)); - /* finally do the gendisk stuff */ major_info->gendisk.part = kmalloc ((1 << MINORBITS) * sizeof (struct hd_struct), @@ -755,10 +748,6 @@ /* error handling - free the prior allocated memory */ out_gendisk: - kfree (max_sectors[major]); - max_sectors[major] = NULL; - - out_max_sectors: kfree (hardsect_size[major]); hardsect_size[major] = NULL; @@ -825,12 +814,8 @@ kfree (blk_size[major]); kfree (blksize_size[major]); kfree (hardsect_size[major]); - kfree (max_sectors[major]); - blk_size[major] = NULL; - blksize_size[major] = NULL; - hardsect_size[major] = NULL; - max_sectors[major] = NULL; + blk_clear(major); rc = devfs_unregister_blkdev (major, DASD_NAME); if (rc < 0) { @@ -1704,10 +1689,6 @@ dasd_end_request (req, 0); dasd_dequeue_request (queue,req); } else { - /* relocate request according to partition table */ - req->sector += - device->major_info->gendisk. - part[MINOR (req->rq_dev)].start_sect; cqr = device->discipline->build_cp_from_req (device, req); if (cqr == NULL) { @@ -1716,10 +1697,7 @@ "on request %p\n", device->devinfo.devno, req); - /* revert relocation of request */ - req->sector -= - device->major_info->gendisk. - part[MINOR (req->rq_dev)].start_sect; + break; /* terminate request queue loop */ } @@ -1769,10 +1747,10 @@ dasd_run_bh (dasd_device_t * device) { long flags; - spin_lock_irqsave (&io_request_lock, flags); + spin_lock_irqsave (&device->request_queue.queue_lock, flags); atomic_set (&device->bh_scheduled, 0); dasd_process_queues (device); - spin_unlock_irqrestore (&io_request_lock, flags); + spin_unlock_irqrestore (&device->request_queue.queue_lock, flags); } /* @@ -2468,14 +2446,12 @@ dasd_info.chanq_len = 0; if (device->request_queue->request_fn) { struct list_head *l; + request_queue_t *q = drive->request_queue; ccw_req_t *cqr = device->queue.head; - spin_lock_irqsave (&io_request_lock, flags); - list_for_each (l, - &device->request_queue-> - queue_head) { + spin_lock_irqsave (&q->queue_lock, flags); + list_for_each (l, q->queue_head, queue_head) dasd_info.req_queue_len++; - } - spin_unlock_irqrestore (&io_request_lock, + spin_unlock_irqrestore (&q->queue_lock, flags); s390irq_spin_lock_irqsave (device->devinfo.irq, flags); @@ -2668,7 +2644,7 @@ /* SECTION: Management of device list */ int -dasd_fillgeo(int kdev,struct hd_geometry *geo) +dasd_fillgeo(kdev_t kdev,struct hd_geometry *geo) { dasd_device_t *device = dasd_device_from_kdev (kdev); @@ -2679,8 +2655,7 @@ return -EINVAL; device->discipline->fill_geometry (device, geo); - geo->start = device->major_info->gendisk.part[MINOR(kdev)].start_sect - >> device->sizes.s2b_shift;; + geo->start = get_start_sect(kdev); return 0; } @@ -3365,6 +3340,11 @@ int major = MAJOR(device->kdev); int minor = MINOR(device->kdev); + device->request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL); + device->request_queue->queuedata = device; + blk_init_queue (device->request_queue, do_dasd_request); + elevator_init (&(device->request_queue->elevator),ELEVATOR_NOOP); + for (i = 0; i < (1 << DASD_PARTN_BITS); i++) { if (i == 0) device->major_info->gendisk.sizes[minor] = @@ -3374,17 +3354,11 @@ device->major_info->gendisk.sizes[minor + i] = 0; hardsect_size[major][minor + i] = device->sizes.bp_block; blksize_size[major][minor + i] = device->sizes.bp_block; - max_sectors[major][minor + i] = - device->discipline->max_blocks << - device->sizes.s2b_shift; + blk_queue_max_sectors(device->request_queue, + device->discipline->max_blocks << device->sizes.s2b_shift); device->major_info->gendisk.part[minor+i].start_sect = 0; device->major_info->gendisk.part[minor+i].nr_sects = 0; } - device->request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL); - device->request_queue->queuedata = device; - blk_init_queue (device->request_queue, do_dasd_request); - blk_queue_headactive (device->request_queue, 0); - elevator_init (&(device->request_queue->elevator),ELEVATOR_NOOP); return rc; } @@ -3411,7 +3385,6 @@ device->major_info->gendisk.sizes[minor + i] = 0; hardsect_size[major][minor + i] = 0; blksize_size[major][minor + i] = 0; - max_sectors[major][minor + i] = 0; } if (device->request_queue) { blk_cleanup_queue (device->request_queue); diff -u --recursive --new-file v2.5.0/linux/drivers/s390/block/xpram.c linux/drivers/s390/block/xpram.c --- v2.5.0/linux/drivers/s390/block/xpram.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/s390/block/xpram.c Sat Dec 8 20:02:47 2001 @@ -1041,7 +1041,6 @@ #elif (XPRAM_VERSION == 24) q = BLK_DEFAULT_QUEUE (major); blk_init_queue (q, xpram_request); - blk_queue_headactive (BLK_DEFAULT_QUEUE (major), 0); #endif /* V22/V24 */ read_ahead[major] = xpram_rahead; @@ -1213,8 +1212,7 @@ { int i; - /* first of all, flush it all and reset all the data structures */ - + /* first of all, flush it all and reset all the data structures */ for (i=0; iblk_minor]=2048; // blocks are 2k by default. hardsect_size[tapeblock_major][ti->blk_minor]=512; blk_init_queue (&ti->request_queue, tape_request_fn); - blk_queue_headactive (&ti->request_queue, 0); #ifdef CONFIG_DEVFS_FS tapeblock_mkdevfstree(ti); #endif @@ -366,12 +365,14 @@ static void run_tapeblock_exec_IO (tape_info_t* ti) { long flags_390irq,flags_ior; - spin_lock_irqsave (&io_request_lock, flags_ior); + request_queue_t *q = &tape->request_queue; + + spin_lock_irqsave (&q->queue_lock, flags_ior); s390irq_spin_lock_irqsave(ti->devinfo.irq,flags_390irq); atomic_set(&ti->bh_scheduled,0); tapeblock_exec_IO(ti); s390irq_spin_unlock_irqrestore(ti->devinfo.irq,flags_390irq); - spin_unlock_irqrestore (&io_request_lock, flags_ior); + spin_unlock_irqrestore (&q->queue_lock, flags_ior); } void diff -u --recursive --new-file v2.5.0/linux/drivers/sbus/char/jsflash.c linux/drivers/sbus/char/jsflash.c --- v2.5.0/linux/drivers/sbus/char/jsflash.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/sbus/char/jsflash.c Sat Dec 8 20:02:47 2001 @@ -662,7 +662,6 @@ blk_size[JSFD_MAJOR] = jsfd_sizes; blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); - /* blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); */ for (i = 0; i < JSF_MAX; i++) { if ((i & JSF_PART_MASK) >= JSF_NPART) continue; jsf = &jsf0; /* actually, &jsfv[i >> JSF_PART_BITS] */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/3w-xxxx.h linux/drivers/scsi/3w-xxxx.h --- v2.5.0/linux/drivers/scsi/3w-xxxx.h Fri Nov 9 14:05:02 2001 +++ linux/drivers/scsi/3w-xxxx.h Wed Nov 28 10:22:27 2001 @@ -461,7 +461,6 @@ present : 0, \ unchecked_isa_dma : 0, \ use_clustering : ENABLE_CLUSTERING, \ - use_new_eh_code : 1, \ emulated : 1 \ } #endif /* _3W_XXXX_H */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c --- v2.5.0/linux/drivers/scsi/53c7,8xx.c Thu Oct 25 13:53:48 2001 +++ linux/drivers/scsi/53c7,8xx.c Mon Nov 26 14:23:58 2001 @@ -1427,13 +1427,14 @@ return -1; } -#ifdef __powerpc__ if ( ! (command & PCI_COMMAND_MASTER)) { - printk("SCSI: PCI Master Bit has not been set. Setting...\n"); + printk(KERN_INFO "SCSI: PCI Master Bit has not been set. Setting...\n"); command |= PCI_COMMAND_MASTER|PCI_COMMAND_IO; pci_write_config_word(pdev, PCI_COMMAND, command); + } - if (io_port >= 0x10000000 && is_prep ) { +#ifdef __powerpc__ + if (io_port >= 0x10000000 && is_prep ) { /* Mapping on PowerPC can't handle this! */ unsigned long new_io_port; new_io_port = (io_port & 0x00FFFFFF) | 0x01000000; @@ -1441,7 +1442,6 @@ io_port = new_io_port; pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, io_port); pdev->base_address[0] = io_port; - } } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/53c700.c linux/drivers/scsi/53c700.c --- v2.5.0/linux/drivers/scsi/53c700.c Thu Oct 11 09:43:29 2001 +++ linux/drivers/scsi/53c700.c Wed Nov 28 10:22:27 2001 @@ -267,7 +267,6 @@ tpnt->sg_tablesize = NCR_700_SG_SEGMENTS; tpnt->cmd_per_lun = NCR_700_MAX_TAGS; tpnt->use_clustering = DISABLE_CLUSTERING; - tpnt->use_new_eh_code = 1; tpnt->proc_info = NCR_700_proc_directory_info; if(tpnt->name == NULL) diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in --- v2.5.0/linux/drivers/scsi/Config.in Fri Nov 9 15:22:54 2001 +++ linux/drivers/scsi/Config.in Tue Nov 27 09:23:27 2001 @@ -20,10 +20,6 @@ comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs' -#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' Enable extra checks in new queueing code' CONFIG_SCSI_DEBUG_QUEUES -#fi - bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile --- v2.5.0/linux/drivers/scsi/Makefile Wed Nov 21 09:59:11 2001 +++ linux/drivers/scsi/Makefile Sun Dec 16 12:20:20 2001 @@ -133,11 +133,9 @@ obj-$(CONFIG_CHR_DEV_SG) += sg.o list-multi := scsi_mod.o sd_mod.o sr_mod.o initio.o a100u2w.o cpqfc.o -scsi_mod-objs := scsi.o hosts.o scsi_ioctl.o constants.o \ - scsicam.o scsi_proc.o scsi_error.o \ - scsi_obsolete.o scsi_queue.o scsi_lib.o \ - scsi_merge.o scsi_dma.o scsi_scan.o \ - scsi_syms.o +scsi_mod-objs := scsi.o hosts.o scsi_ioctl.o constants.o scsicam.o \ + scsi_proc.o scsi_error.o scsi_queue.o scsi_lib.o \ + scsi_merge.o scsi_scan.o scsi_syms.o sd_mod-objs := sd.o sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o initio-objs := ini9100u.o i91uscsi.o diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/README.ncr53c8xx linux/drivers/scsi/README.ncr53c8xx --- v2.5.0/linux/drivers/scsi/README.ncr53c8xx Thu Jul 5 11:28:17 2001 +++ linux/drivers/scsi/README.ncr53c8xx Sun Dec 16 12:20:20 2001 @@ -1,6 +1,6 @@ The Linux NCR53C8XX/SYM53C8XX drivers README file -Written by Gerard Roudier +Written by Gerard Roudier 21 Rue Carnot 95170 DEUIL LA BARRE - FRANCE @@ -87,7 +87,7 @@ The initial Linux ncr53c8xx driver has been a port of the ncr driver from FreeBSD that has been achieved in November 1995 by: - Gerard Roudier + Gerard Roudier The original driver has been written for 386bsd and FreeBSD by: Wolfgang Stanglmeier @@ -1287,7 +1287,7 @@ be sure I will receive it. Obviously, a bug in the driver code is possible. - My email address: Gerard Roudier + My email address: Gerard Roudier Allowing disconnections is important if you use several devices on your SCSI bus but often causes problems with buggy devices. diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/advansys.h linux/drivers/scsi/advansys.h --- v2.5.0/linux/drivers/scsi/advansys.h Thu Jul 19 21:07:47 2001 +++ linux/drivers/scsi/advansys.h Wed Nov 28 10:22:27 2001 @@ -77,7 +77,6 @@ release: advansys_release, \ info: advansys_info, \ queuecommand: advansys_queuecommand, \ - use_new_eh_code: 1, \ eh_bus_reset_handler: advansys_reset, \ bios_param: advansys_biosparam, \ /* \ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/aha152x.h linux/drivers/scsi/aha152x.h --- v2.5.0/linux/drivers/scsi/aha152x.h Thu Jul 19 21:08:07 2001 +++ linux/drivers/scsi/aha152x.h Thu Nov 29 13:58:14 2001 @@ -49,8 +49,7 @@ cmd_per_lun: 1, \ present: 0, \ unchecked_isa_dma: 0, \ - use_clustering: DISABLE_CLUSTERING, \ - use_new_eh_code: 1 } + use_clustering: DISABLE_CLUSTERING } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/aha1542.h linux/drivers/scsi/aha1542.h --- v2.5.0/linux/drivers/scsi/aha1542.h Thu Jul 19 21:08:11 2001 +++ linux/drivers/scsi/aha1542.h Wed Nov 28 10:22:27 2001 @@ -166,7 +166,6 @@ sg_tablesize: AHA1542_SCATTER, \ cmd_per_lun: AHA1542_CMDLUN, \ unchecked_isa_dma: 1, \ - use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1} - + use_clustering: ENABLE_CLUSTERING \ +} #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/aic7xxx/aic7xxx_linux.c linux/drivers/scsi/aic7xxx/aic7xxx_linux.c --- v2.5.0/linux/drivers/scsi/aic7xxx/aic7xxx_linux.c Wed Nov 21 14:05:29 2001 +++ linux/drivers/scsi/aic7xxx/aic7xxx_linux.c Tue Nov 27 09:23:27 2001 @@ -1123,9 +1123,9 @@ if (host == NULL) return (ENOMEM); - ahc_lock(ahc, &s); *((struct ahc_softc **)host->hostdata) = ahc; ahc->platform_data->host = host; + ahc_lock(ahc, &s); host->can_queue = AHC_MAX_QUEUE; host->cmd_per_lun = 2; host->sg_tablesize = AHC_NSEG; @@ -1272,7 +1272,9 @@ TAILQ_INIT(&ahc->platform_data->completeq); TAILQ_INIT(&ahc->platform_data->device_runq); ahc->platform_data->hw_dma_mask = 0xFFFFFFFF; - ahc_lockinit(ahc); + /* + * ahc_lockinit done by scsi_register, as we don't own that lock + */ ahc_done_lockinit(ahc); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); @@ -1530,22 +1532,17 @@ int ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) { - struct ahc_softc *ahc; + struct ahc_softc *ahc = *(struct ahc_softc **)cmd->host->hostdata; struct ahc_linux_device *dev; - u_long flags; - - ahc = *(struct ahc_softc **)cmd->host->hostdata; /* * Save the callback on completion function. */ cmd->scsi_done = scsi_done; - ahc_lock(ahc, &flags); dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target, cmd->lun, /*alloc*/TRUE); if (dev == NULL) { - ahc_unlock(ahc, &flags); printf("aic7xxx_linux_queue: Unable to allocate device!\n"); return (-ENOMEM); } @@ -1556,7 +1553,6 @@ dev->flags |= AHC_DEV_ON_RUN_LIST; ahc_linux_run_device_queues(ahc); } - ahc_unlock(ahc, &flags); return (0); } @@ -2408,12 +2404,10 @@ flag == SCB_ABORT ? "n ABORT" : " TARGET RESET"); /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. + * we used to drop io_request_lock and lock ahc from here, but + * now that the global lock is gone the upper layer have already + * done what ahc_lock would do /jens */ - spin_unlock_irq(&io_request_lock); - - ahc_lock(ahc, &s); /* * First determine if we currently own this command. @@ -2661,7 +2655,7 @@ ahc_unlock(ahc, &s); if (acmd != NULL) ahc_linux_run_complete_queue(ahc, acmd); - spin_lock_irq(&io_request_lock); + ahc_lock(ahc, &s); return (retval); } @@ -2704,14 +2698,7 @@ u_long s; int found; - /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. - */ - spin_unlock_irq(&io_request_lock); - ahc = *(struct ahc_softc **)cmd->host->hostdata; - ahc_lock(ahc, &s); found = ahc_reset_channel(ahc, cmd->channel + 'A', /*initiate reset*/TRUE); acmd = TAILQ_FIRST(&ahc->platform_data->completeq); @@ -2724,7 +2711,7 @@ if (acmd != NULL) ahc_linux_run_complete_queue(ahc, acmd); - spin_lock_irq(&io_request_lock); + ahc_lock(ahc, &s); return SUCCESS; } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/aic7xxx/aic7xxx_linux_host.h linux/drivers/scsi/aic7xxx/aic7xxx_linux_host.h --- v2.5.0/linux/drivers/scsi/aic7xxx/aic7xxx_linux_host.h Thu Oct 25 13:53:49 2001 +++ linux/drivers/scsi/aic7xxx/aic7xxx_linux_host.h Wed Nov 28 10:22:27 2001 @@ -89,7 +89,7 @@ present: 0, /* number of 7xxx's present */\ unchecked_isa_dma: 0, /* no memory DMA restrictions */\ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1 \ + highmem_io: 1 \ } #endif /* _AIC7XXX_LINUX_HOST_H_ */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h linux/drivers/scsi/aic7xxx/aic7xxx_osm.h --- v2.5.0/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h Thu Oct 25 13:53:49 2001 +++ linux/drivers/scsi/aic7xxx/aic7xxx_osm.h Tue Nov 27 09:23:27 2001 @@ -575,9 +575,6 @@ TAILQ_HEAD(, ahc_linux_device) device_runq; struct ahc_completeq completeq; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) - spinlock_t spin_lock; -#endif u_int qfrozen; struct timer_list reset_timer; struct semaphore eh_sem; @@ -716,20 +713,20 @@ static __inline void ahc_lockinit(struct ahc_softc *ahc) { - spin_lock_init(&ahc->platform_data->spin_lock); + spin_lock_init(&ahc->platform_data->host->host_lock); } static __inline void ahc_lock(struct ahc_softc *ahc, unsigned long *flags) { *flags = 0; - spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags); + spin_lock_irqsave(&ahc->platform_data->host->host_lock, *flags); } static __inline void ahc_unlock(struct ahc_softc *ahc, unsigned long *flags) { - spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags); + spin_unlock_irqrestore(&ahc->platform_data->host->host_lock, *flags); } static __inline void @@ -741,14 +738,18 @@ static __inline void ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags) { + struct Scsi_Host *host = ahc->platform_data->host; + *flags = 0; - spin_lock_irqsave(&io_request_lock, *flags); + spin_lock_irqsave(&host->host_lock, *flags); } static __inline void ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags) { - spin_unlock_irqrestore(&io_request_lock, *flags); + struct Scsi_Host *host = ahc->platform_data->host; + + spin_unlock_irqrestore(&host->host_lock, *flags); } #else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/aic7xxx_old/aic7xxx.h linux/drivers/scsi/aic7xxx_old/aic7xxx.h --- v2.5.0/linux/drivers/scsi/aic7xxx_old/aic7xxx.h Sun Mar 4 14:30:18 2001 +++ linux/drivers/scsi/aic7xxx_old/aic7xxx.h Wed Nov 28 10:22:27 2001 @@ -55,7 +55,6 @@ present: 0, /* number of 7xxx's present */\ unchecked_isa_dma: 0, /* no memory DMA restrictions */\ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 0 \ } extern int aic7xxx_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/aic7xxx_old.c linux/drivers/scsi/aic7xxx_old.c --- v2.5.0/linux/drivers/scsi/aic7xxx_old.c Wed Nov 21 14:05:29 2001 +++ linux/drivers/scsi/aic7xxx_old.c Sun Dec 16 12:20:20 2001 @@ -3084,7 +3084,7 @@ * we check data_cmnd[0]. This catches the conditions for st.c, but * I'm still not sure if request.cmd is valid for sg devices. */ - if ( (cmd->request.cmd == WRITE) || (cmd->data_cmnd[0] == WRITE_6) || + if ( (rq_data_dir(&cmd->request) == WRITE) || (cmd->data_cmnd[0] == WRITE_6) || (cmd->data_cmnd[0] == WRITE_FILEMARKS) ) { sp->w_total++; @@ -4127,7 +4127,7 @@ unsigned long cpu_flags = 0; struct aic7xxx_scb *scb; - spin_lock_irqsave(&io_request_lock, cpu_flags); + spin_lock_irqsave(&p->host->host_lock, cpu_flags); p->dev_timer_active &= ~(0x01 << MAX_TARGETS); if ( (p->dev_timer_active & (0x01 << p->scsi_id)) && time_after_eq(jiffies, p->dev_expires[p->scsi_id]) ) @@ -4184,7 +4184,7 @@ } aic7xxx_run_waiting_queues(p); - spin_unlock_irqrestore(&io_request_lock, cpu_flags); + spin_unlock_irqrestore(&p->host->host_lock, cpu_flags); } /*+F************************************************************************* @@ -4294,7 +4294,7 @@ { printk(INFO_LEAD "Underflow - Wanted %u, %s %u, residual SG " "count %d.\n", p->host_no, CTL_OF_SCB(scb), cmd->underflow, - (cmd->request.cmd == WRITE) ? "wrote" : "read", actual, + (rq_data_dir(&cmd->request) == WRITE) ? "wrote" : "read", actual, hscb->residual_SG_segment_count); printk(INFO_LEAD "status 0x%x.\n", p->host_no, CTL_OF_SCB(scb), hscb->target_status); @@ -7011,7 +7011,7 @@ p = (struct aic7xxx_host *)dev_id; if(!p) return; - spin_lock_irqsave(&io_request_lock, cpu_flags); + spin_lock_irqsave(&p->host->host_lock, cpu_flags); p->flags |= AHC_IN_ISR; do { @@ -7020,7 +7020,7 @@ aic7xxx_done_cmds_complete(p); aic7xxx_run_waiting_queues(p); p->flags &= ~AHC_IN_ISR; - spin_unlock_irqrestore(&io_request_lock, cpu_flags); + spin_unlock_irqrestore(&p->host->host_lock, cpu_flags); } /*+F************************************************************************* @@ -11148,7 +11148,7 @@ disable_irq(p->irq); aic7xxx_print_card(p); aic7xxx_print_scratch_ram(p); - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&p->host->host_lock); for(;;) barrier(); } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/atp870u.h linux/drivers/scsi/atp870u.h --- v2.5.0/linux/drivers/scsi/atp870u.h Thu Jul 19 21:08:56 2001 +++ linux/drivers/scsi/atp870u.h Wed Nov 28 10:22:27 2001 @@ -65,7 +65,6 @@ present: 0, /* number of 7xxx's present */\ unchecked_isa_dma: 0, /* no memory DMA restrictions */\ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 0 \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/cpqfc.Readme linux/drivers/scsi/cpqfc.Readme --- v2.5.0/linux/drivers/scsi/cpqfc.Readme Thu Oct 25 13:53:50 2001 +++ linux/drivers/scsi/cpqfc.Readme Mon Dec 10 14:18:02 2001 @@ -7,6 +7,11 @@ SEST size 512 Exchanges (simultaneous I/Os) limited by module kmalloc() max of 128k bytes contiguous. +Ver 2.5.0 Nov 29, 2001 + * eliminated io_request_lock. This change makes the driver specific + to the 2.5.x kernels. + * silenced excessively noisy printks. + Ver 2.1.1 Oct 18, 2001 * reinitialize Cmnd->SCp.sent_command (used to identify commands as passthrus) on calling scsi_done, since the scsi mid layer does not diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/cpqfcTS.h linux/drivers/scsi/cpqfcTS.h --- v2.5.0/linux/drivers/scsi/cpqfcTS.h Sun Aug 5 13:12:41 2001 +++ linux/drivers/scsi/cpqfcTS.h Wed Nov 28 10:22:27 2001 @@ -38,7 +38,6 @@ present: 0, \ unchecked_isa_dma: 0, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1 \ } #endif /* CPQFCTS_H */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/cpqfcTScontrol.c linux/drivers/scsi/cpqfcTScontrol.c --- v2.5.0/linux/drivers/scsi/cpqfcTScontrol.c Thu Oct 25 13:53:50 2001 +++ linux/drivers/scsi/cpqfcTScontrol.c Mon Dec 10 14:19:02 2001 @@ -97,11 +97,11 @@ fcChip->Exchanges = NULL; cpqfcHBAdata->fcLQ = NULL; - printk("Allocating %u for %u Exchanges ", - (ULONG)sizeof(FC_EXCHANGES), TACH_MAX_XID); + /* printk("Allocating %u for %u Exchanges ", + (ULONG)sizeof(FC_EXCHANGES), TACH_MAX_XID); */ fcChip->Exchanges = pci_alloc_consistent(cpqfcHBAdata->PciDev, sizeof(FC_EXCHANGES), &fcChip->exch_dma_handle); - printk("@ %p\n", fcChip->Exchanges); + /* printk("@ %p\n", fcChip->Exchanges); */ if( fcChip->Exchanges == NULL ) // fatal error!! { @@ -112,10 +112,10 @@ memset( fcChip->Exchanges, 0, sizeof( FC_EXCHANGES)); - printk("Allocating %u for LinkQ ", (ULONG)sizeof(FC_LINK_QUE)); + /* printk("Allocating %u for LinkQ ", (ULONG)sizeof(FC_LINK_QUE)); */ cpqfcHBAdata->fcLQ = pci_alloc_consistent(cpqfcHBAdata->PciDev, sizeof( FC_LINK_QUE), &cpqfcHBAdata->fcLQ_dma_handle); - printk("@ %p (%u elements)\n", cpqfcHBAdata->fcLQ, FC_LINKQ_DEPTH); + /* printk("@ %p (%u elements)\n", cpqfcHBAdata->fcLQ, FC_LINKQ_DEPTH); */ memset( cpqfcHBAdata->fcLQ, 0, sizeof( FC_LINK_QUE)); if( cpqfcHBAdata->fcLQ == NULL ) // fatal error!! @@ -222,8 +222,8 @@ // power-of-2 boundary // LIVE DANGEROUSLY! Assume the boundary for SEST mem will // be on physical page (e.g. 4k) boundary. - printk("Allocating %u for TachSEST for %u Exchanges\n", - (ULONG)sizeof(TachSEST), TACH_SEST_LEN); + /* printk("Allocating %u for TachSEST for %u Exchanges\n", + (ULONG)sizeof(TachSEST), TACH_SEST_LEN); */ fcChip->SEST = fcMemManager( cpqfcHBAdata->PciDev, &cpqfcHBAdata->dynamic_mem[0], sizeof(TachSEST), 4, 0L, &SESTdma ); @@ -289,7 +289,7 @@ // set the Host's pointer for Tachyon to access - printk(" cpqfcTS: writing IMQ BASE %Xh ", fcChip->IMQ->base ); + /* printk(" cpqfcTS: writing IMQ BASE %Xh ", fcChip->IMQ->base ); */ writel( fcChip->IMQ->base, (fcChip->Registers.ReMapMemBase + IMQ_BASE)); @@ -315,9 +315,9 @@ return -1; // failed } #endif -//#if DBG +#if DBG printk(" PI %Xh\n", (ULONG)ulAddr ); -//#endif +#endif writel( (ULONG)ulAddr, (fcChip->Registers.ReMapMemBase + IMQ_PRODUCER_INDEX)); @@ -337,9 +337,9 @@ writel( fcChip->SEST->base, (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE)); - printk(" cpqfcTS: SEST %p(virt): Wrote base %Xh @ %p\n", + /* printk(" cpqfcTS: SEST %p(virt): Wrote base %Xh @ %p\n", fcChip->SEST, fcChip->SEST->base, - fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE); + fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE); */ writel( fcChip->SEST->length, (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_LENGTH)); @@ -1723,7 +1723,7 @@ UCHAR Minor = (UCHAR)(RevId & 0x3); UCHAR Major = (UCHAR)((RevId & 0x1C) >>2); - printk(" HBA Tachyon RevId %d.%d\n", Major, Minor); + /* printk(" HBA Tachyon RevId %d.%d\n", Major, Minor); */ if( (Major == 1) && (Minor == 2) ) { sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS12); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/cpqfcTSinit.c linux/drivers/scsi/cpqfcTSinit.c --- v2.5.0/linux/drivers/scsi/cpqfcTSinit.c Thu Oct 25 13:53:50 2001 +++ linux/drivers/scsi/cpqfcTSinit.c Mon Dec 10 14:22:21 2001 @@ -188,7 +188,7 @@ DEBUG_PCI(printk(" IOBaseU = %x\n", cpqfcHBAdata->fcChip.Registers.IOBaseU)); - printk(" ioremap'd Membase: %p\n", cpqfcHBAdata->fcChip.Registers.ReMapMemBase); + /* printk(" ioremap'd Membase: %p\n", cpqfcHBAdata->fcChip.Registers.ReMapMemBase); */ DEBUG_PCI(printk(" SFQconsumerIndex.address = %p\n", cpqfcHBAdata->fcChip.Registers.SFQconsumerIndex.address)); @@ -242,7 +242,7 @@ cpqfcHBAdata->notify_wt = &sem; /* must unlock before kernel_thread(), for it may cause a reschedule. */ - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&HostAdapter->host_lock); kernel_thread((int (*)(void *))cpqfcTSWorkerThread, (void *) HostAdapter, 0); /* @@ -250,7 +250,7 @@ */ down (&sem); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&HostAdapter->host_lock); cpqfcHBAdata->notify_wt = NULL; LEAVE("launch_FC_worker_thread"); @@ -312,8 +312,8 @@ } // NOTE: (kernel 2.2.12-32) limits allocation to 128k bytes... - printk(" scsi_register allocating %d bytes for FC HBA\n", - (ULONG)sizeof(CPQFCHBA)); + /* printk(" scsi_register allocating %d bytes for FC HBA\n", + (ULONG)sizeof(CPQFCHBA)); */ HostAdapter = scsi_register( ScsiHostTemplate, sizeof( CPQFCHBA ) ); @@ -403,9 +403,11 @@ DEBUG_PCI(printk(" Requesting 255 I/O addresses @ %x\n", cpqfcHBAdata->fcChip.Registers.IOBaseU )); - + + // start our kernel worker thread + spin_lock_irq(&HostAdapter->host_lock); launch_FCworker_thread(HostAdapter); @@ -445,15 +447,16 @@ unsigned long stop_time; - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&HostAdapter->host_lock); stop_time = jiffies + 4*HZ; while ( time_before(jiffies, stop_time) ) schedule(); // (our worker task needs to run) - spin_lock_irq(&io_request_lock); } + spin_lock_irq(&HostAdapter->host_lock); NumberOfAdapters++; + spin_unlock_irq(&HostAdapter->host_lock); } // end of while() } @@ -1593,9 +1596,9 @@ int retval; Scsi_Device *SDpnt = Cmnd->device; // printk(" ENTERING cpqfcTS_eh_device_reset() \n"); - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&Cmnd->host->host_lock); retval = cpqfcTS_TargetDeviceReset( SDpnt, 0); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&Cmnd->host->host_lock); return retval; } @@ -1650,8 +1653,7 @@ UCHAR IntPending; ENTER("intr_handler"); - - spin_lock_irqsave( &io_request_lock, flags); + spin_lock_irqsave( &HostAdapter->host_lock, flags); // is this our INT? IntPending = readb( cpqfcHBA->fcChip.Registers.INTPEND.address); @@ -1700,7 +1702,7 @@ } } } - spin_unlock_irqrestore( &io_request_lock, flags); + spin_unlock_irqrestore( &HostAdapter->host_lock, flags); LEAVE("intr_handler"); } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/cpqfcTSstructs.h linux/drivers/scsi/cpqfcTSstructs.h --- v2.5.0/linux/drivers/scsi/cpqfcTSstructs.h Thu Oct 25 13:53:50 2001 +++ linux/drivers/scsi/cpqfcTSstructs.h Mon Dec 10 14:15:19 2001 @@ -32,8 +32,8 @@ #define CPQFCTS_DRIVER_VER(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) // don't forget to also change MODULE_DESCRIPTION in cpqfcTSinit.c #define VER_MAJOR 2 -#define VER_MINOR 1 -#define VER_SUBMINOR 1 +#define VER_MINOR 5 +#define VER_SUBMINOR 0 // Macros for kernel (esp. SMP) tracing using a PCI analyzer // (e.g. x86). diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/cpqfcTSworker.c linux/drivers/scsi/cpqfcTSworker.c --- v2.5.0/linux/drivers/scsi/cpqfcTSworker.c Thu Oct 25 13:53:50 2001 +++ linux/drivers/scsi/cpqfcTSworker.c Mon Dec 10 14:15:19 2001 @@ -227,7 +227,7 @@ PCI_TRACE( 0x90) // first, take the IO lock so the SCSI upper layers can't call // into our _quecommand function (this also disables INTs) - spin_lock_irqsave( &io_request_lock, flags); // STOP _que function + spin_lock_irqsave( &HostAdapter->host_lock, flags); // STOP _que function PCI_TRACE( 0x90) CPQ_SPINLOCK_HBA( cpqfcHBAdata) @@ -241,7 +241,7 @@ PCI_TRACE( 0x90) // release the IO lock (and re-enable interrupts) - spin_unlock_irqrestore( &io_request_lock, flags); + spin_unlock_irqrestore( &HostAdapter->host_lock, flags); // disable OUR HBA interrupt (keep them off as much as possible // during error recovery) @@ -3077,7 +3077,8 @@ if( cpqfcHBAdata->BoardLock) // Worker Task Running? goto Skip; - spin_lock_irqsave( &io_request_lock, flags); // STOP _que function + // STOP _que function + spin_lock_irqsave( &cpqfcHBAdata->HostAdapter->host_lock, flags); PCI_TRACE( 0xA8) @@ -3085,7 +3086,7 @@ cpqfcHBAdata->BoardLock = &BoardLock; // stop Linux SCSI command queuing // release the IO lock (and re-enable interrupts) - spin_unlock_irqrestore( &io_request_lock, flags); + spin_unlock_irqrestore( &cpqfcHBAdata->HostAdapter->host_lock, flags); // Ensure no contention from _quecommand or Worker process CPQ_SPINLOCK_HBA( cpqfcHBAdata) diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/dc390.h linux/drivers/scsi/dc390.h --- v2.5.0/linux/drivers/scsi/dc390.h Thu Jul 19 21:08:49 2001 +++ linux/drivers/scsi/dc390.h Wed Nov 28 10:22:27 2001 @@ -64,7 +64,6 @@ this_id: 7, \ sg_tablesize: SG_ALL, \ cmd_per_lun: 16, \ - NEW_EH \ unchecked_isa_dma: 0, \ use_clustering: DISABLE_CLUSTERING \ } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/dpt_i2o.c linux/drivers/scsi/dpt_i2o.c --- v2.5.0/linux/drivers/scsi/dpt_i2o.c Fri Nov 9 14:05:06 2001 +++ linux/drivers/scsi/dpt_i2o.c Wed Nov 28 10:22:27 2001 @@ -178,7 +178,6 @@ adpt_hba* pHba; adpt_init(); - sht->use_new_eh_code = 1; PINFO("Detecting Adaptec I2O RAID controllers...\n"); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/dpti.h linux/drivers/scsi/dpti.h --- v2.5.0/linux/drivers/scsi/dpti.h Fri Sep 7 09:28:38 2001 +++ linux/drivers/scsi/dpti.h Wed Nov 28 10:22:27 2001 @@ -95,7 +95,6 @@ sg_tablesize: 0, /* max scatter-gather cmds */\ cmd_per_lun: 256, /* cmds per lun (linked cmds) */\ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1, \ proc_name: "dpt_i2o" /* this is the name of our proc node*/ \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c --- v2.5.0/linux/drivers/scsi/eata.c Fri Nov 9 14:05:06 2001 +++ linux/drivers/scsi/eata.c Wed Dec 12 09:20:22 2001 @@ -1,6 +1,9 @@ /* * eata.c - Low-level driver for EATA/DMA SCSI host adapters. * + * 11 Dec 2001 Rev. 7.00 for linux 2.5.1 + * + Use host->host_lock instead of io_request_lock. + * * 1 May 2001 Rev. 6.05 for linux 2.4.4 * + Clean up all pci related routines. * + Fix data transfer direction for opcode SEND_CUE_SHEET (0x5d) @@ -438,13 +441,6 @@ #include #include -#define SPIN_FLAGS unsigned long spin_flags; -#define SPIN_LOCK spin_lock_irq(&io_request_lock); -#define SPIN_LOCK_SAVE spin_lock_irqsave(&io_request_lock, spin_flags); -#define SPIN_UNLOCK spin_unlock_irq(&io_request_lock); -#define SPIN_UNLOCK_RESTORE \ - spin_unlock_irqrestore(&io_request_lock, spin_flags); - /* Subversion values */ #define ISA 0 #define ESA 1 @@ -1589,10 +1585,12 @@ #endif HD(j)->in_reset = TRUE; - SPIN_UNLOCK + + spin_unlock_irq(&sh[j]->host_lock); time = jiffies; while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); - SPIN_LOCK + spin_lock_irq(&sh[j]->host_lock); + printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); for (i = 0; i < sh[j]->can_queue; i++) { @@ -2036,14 +2034,14 @@ static void do_interrupt_handler(int irq, void *shap, struct pt_regs *regs) { unsigned int j; - SPIN_FLAGS + unsigned long spin_flags; /* Check if the interrupt must be processed by this handler */ if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return; - SPIN_LOCK_SAVE + spin_lock_irqsave(&sh[j]->host_lock, spin_flags); ihdlr(irq, j); - SPIN_UNLOCK_RESTORE + spin_unlock_irqrestore(&sh[j]->host_lock, spin_flags); } int eata2x_release(struct Scsi_Host *shpnt) { @@ -2077,4 +2075,4 @@ #ifndef MODULE __setup("eata=", option_setup); #endif /* end MODULE */ -MODULE_LICENSE("Dual BSD/GPL"); +MODULE_LICENSE("GPL"); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/eata.h linux/drivers/scsi/eata.h --- v2.5.0/linux/drivers/scsi/eata.h Sat May 19 17:43:06 2001 +++ linux/drivers/scsi/eata.h Wed Dec 12 09:20:22 2001 @@ -13,7 +13,7 @@ int eata2x_reset(Scsi_Cmnd *); int eata2x_biosparam(Disk *, kdev_t, int *); -#define EATA_VERSION "6.05.00" +#define EATA_VERSION "7.00.00" #define EATA { \ name: "EATA/DMA 2.0x rev. " EATA_VERSION " ", \ @@ -30,7 +30,6 @@ this_id: 7, \ unchecked_isa_dma: 1, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1 /* Enable new error code */ \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/esp.c linux/drivers/scsi/esp.c --- v2.5.0/linux/drivers/scsi/esp.c Sun Feb 18 19:49:55 2001 +++ linux/drivers/scsi/esp.c Sun Dec 16 12:20:20 2001 @@ -1,4 +1,4 @@ -/* $Id: esp.c,v 1.99 2001/02/13 01:17:01 davem Exp $ +/* $Id: esp.c,v 1.100 2001/12/11 04:55:48 davem Exp $ * esp.c: EnhancedScsiProcessor Sun SCSI driver code. * * Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu) @@ -1035,9 +1035,6 @@ { int i; - /* Driver spinlock... */ - spin_lock_init(&esp->lock); - /* Command queues... */ esp->current_SC = NULL; esp->disconnected_SC = NULL; @@ -1816,7 +1813,6 @@ int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { struct esp *esp; - unsigned long flags; /* Set up func ptr and initial driver cmd-phase. */ SCpnt->scsi_done = done; @@ -1834,8 +1830,6 @@ SCpnt->SCp.Message = 0xff; SCpnt->SCp.sent_command = 0; - spin_lock_irqsave(&esp->lock, flags); - /* Place into our queue. */ if (SCpnt->cmnd[0] == REQUEST_SENSE) { ESPQUEUE(("RQSENSE\n")); @@ -1849,8 +1843,6 @@ if (!esp->current_SC && !esp->resetting_bus) esp_exec_cmd(esp); - spin_unlock_irqrestore(&esp->lock, flags); - return 0; } @@ -1926,7 +1918,7 @@ unsigned long flags; int don; - spin_lock_irqsave(&esp->lock, flags); + spin_lock_irqsave(&esp->ehost->host_lock, flags); ESPLOG(("esp%d: Aborting command\n", esp->esp_id)); esp_dump_state(esp); @@ -1942,7 +1934,7 @@ esp->msgout_len = 1; esp->msgout_ctr = 0; esp_cmd(esp, ESP_CMD_SATN); - spin_unlock_irqrestore(&esp->lock, flags); + spin_unlock_irqrestore(&esp->ehost->host_lock, flags); return SCSI_ABORT_PENDING; } @@ -1964,14 +1956,14 @@ *prev = (Scsi_Cmnd *) this->host_scribble; this->host_scribble = NULL; - spin_unlock_irqrestore(&esp->lock, flags); - esp_release_dmabufs(esp, this); this->result = DID_ABORT << 16; this->scsi_done(this); + if (don) ESP_INTSON(esp->dregs); + spin_unlock_irqrestore(&esp->ehost->host_lock, flags); return SCSI_ABORT_SUCCESS; } } @@ -1985,7 +1977,7 @@ if (esp->current_SC) { if (don) ESP_INTSON(esp->dregs); - spin_unlock_irqrestore(&esp->lock, flags); + spin_unlock_irqrestore(&esp->ehost->host_lock, flags); return SCSI_ABORT_BUSY; } @@ -1998,7 +1990,7 @@ if (don) ESP_INTSON(esp->dregs); - spin_unlock_irqrestore(&esp->lock, flags); + spin_unlock_irqrestore(&esp->ehost->host_lock, flags); return SCSI_ABORT_SNOOZE; } @@ -2014,16 +2006,11 @@ /* Clean up currently executing command, if any. */ if (sp != NULL) { esp->current_SC = NULL; - spin_unlock(&esp->lock); esp_release_dmabufs(esp, sp); sp->result = (DID_RESET << 16); - spin_lock(&io_request_lock); sp->scsi_done(sp); - spin_unlock(&io_request_lock); - - spin_lock(&esp->lock); } /* Clean up disconnected queue, they have been invalidated @@ -2031,16 +2018,10 @@ */ if (esp->disconnected_SC) { while ((sp = remove_first_SC(&esp->disconnected_SC)) != NULL) { - spin_unlock(&esp->lock); - esp_release_dmabufs(esp, sp); sp->result = (DID_RESET << 16); - spin_lock(&io_request_lock); sp->scsi_done(sp); - spin_unlock(&io_request_lock); - - spin_lock(&esp->lock); } } @@ -2071,9 +2052,9 @@ struct esp *esp = (struct esp *) SCptr->host->hostdata; unsigned long flags; - spin_lock_irqsave(&esp->lock, flags); + spin_lock_irqsave(&esp->ehost->host_lock, flags); (void) esp_do_resetbus(esp); - spin_unlock_irqrestore(&esp->lock, flags); + spin_unlock_irqrestore(&esp->ehost->host_lock, flags); return SCSI_RESET_PENDING; } @@ -2085,16 +2066,12 @@ esp->current_SC = NULL; - spin_unlock(&esp->lock); esp_release_dmabufs(esp, done_SC); done_SC->result = error; - spin_lock(&io_request_lock); done_SC->scsi_done(done_SC); - spin_unlock(&io_request_lock); /* Bus is free, issue any commands in the queue. */ - spin_lock(&esp->lock); if (esp->issue_SC && !esp->current_SC) esp_exec_cmd(esp); @@ -4344,7 +4321,7 @@ struct esp *esp = dev_id; unsigned long flags; - spin_lock_irqsave(&esp->lock, flags); + spin_lock_irqsave(&esp->ehost->host_lock, flags); if (ESP_IRQ_P(esp->dregs)) { ESP_INTSOFF(esp->dregs); @@ -4354,7 +4331,7 @@ ESP_INTSON(esp->dregs); } - spin_unlock_irqrestore(&esp->lock, flags); + spin_unlock_irqrestore(&esp->ehost->host_lock, flags); } int esp_revoke(Scsi_Device* SDptr) diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/esp.h linux/drivers/scsi/esp.h --- v2.5.0/linux/drivers/scsi/esp.h Mon Sep 18 13:40:17 2000 +++ linux/drivers/scsi/esp.h Sun Dec 16 12:20:20 2001 @@ -1,4 +1,4 @@ -/* $Id: esp.h,v 1.28 2000/03/30 01:33:17 davem Exp $ +/* $Id: esp.h,v 1.29 2001/12/11 04:55:47 davem Exp $ * esp.h: Defines and structures for the Sparc ESP (Enhanced SCSI * Processor) driver under Linux. * @@ -64,7 +64,6 @@ /* We get one of these for each ESP probed. */ struct esp { - spinlock_t lock; unsigned long eregs; /* ESP controller registers */ unsigned long dregs; /* DMA controller registers */ struct sbus_dma *dma; /* DMA controller sw state */ @@ -416,7 +415,7 @@ sg_tablesize: SG_ALL, \ cmd_per_lun: 1, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 0 \ + highmem_io: 1, \ } /* For our interrupt engine. */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/fcal.h linux/drivers/scsi/fcal.h --- v2.5.0/linux/drivers/scsi/fcal.h Mon Mar 15 16:11:31 1999 +++ linux/drivers/scsi/fcal.h Wed Nov 28 10:22:27 2001 @@ -35,7 +35,6 @@ sg_tablesize: 1, \ cmd_per_lun: 1, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: FCP_SCSI_USE_NEW_EH_CODE, \ abort: fcp_old_abort, \ eh_abort_handler: fcp_scsi_abort, \ eh_device_reset_handler:fcp_scsi_dev_reset, \ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/gdth.h linux/drivers/scsi/gdth.h --- v2.5.0/linux/drivers/scsi/gdth.h Fri Sep 7 09:28:37 2001 +++ linux/drivers/scsi/gdth.h Thu Nov 29 13:55:59 2001 @@ -1059,8 +1059,7 @@ cmd_per_lun: GDTH_MAXC_P_L, \ present: 0, \ unchecked_isa_dma: 1, \ - use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1 /* use new error code */ } + use_clustering: ENABLE_CLUSTERING } #elif LINUX_VERSION_CODE >= 0x02015F int gdth_bios_param(Disk *,kdev_t,int *); @@ -1091,8 +1090,7 @@ cmd_per_lun: GDTH_MAXC_P_L, \ present: 0, \ unchecked_isa_dma: 1, \ - use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1 /* use new error code */ } + use_clustering: ENABLE_CLUSTERING } #elif LINUX_VERSION_CODE >= 0x010300 int gdth_bios_param(Disk *,kdev_t,int *); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c --- v2.5.0/linux/drivers/scsi/hosts.c Thu Jul 5 11:28:17 2001 +++ linux/drivers/scsi/hosts.c Sun Dec 16 15:49:23 2001 @@ -129,8 +129,9 @@ * once we are 100% sure that we want to use this host adapter - it is a * pain to reverse this, so we try to avoid it */ - -struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){ +extern int blk_nohighio; +struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j) +{ struct Scsi_Host * retval, *shpnt, *o_shp; Scsi_Host_Name *shn, *shn2; int flag_new = 1; @@ -160,6 +161,7 @@ break; } } + spin_lock_init(&retval->host_lock); atomic_set(&retval->host_active,0); retval->host_busy = 0; retval->host_failed = 0; @@ -235,6 +237,8 @@ retval->cmd_per_lun = tpnt->cmd_per_lun; retval->unchecked_isa_dma = tpnt->unchecked_isa_dma; retval->use_clustering = tpnt->use_clustering; + if (!blk_nohighio) + retval->highmem_io = tpnt->highmem_io; retval->select_queue_depths = tpnt->select_queue_depths; retval->max_sectors = tpnt->max_sectors; diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h --- v2.5.0/linux/drivers/scsi/hosts.h Thu Nov 22 11:49:15 2001 +++ linux/drivers/scsi/hosts.h Sun Dec 16 15:46:45 2001 @@ -280,17 +280,12 @@ unsigned use_clustering:1; /* - * True if this driver uses the new error handling code. This flag is - * really only temporary until all of the other drivers get converted - * to use the new error handling code. - */ - unsigned use_new_eh_code:1; - - /* * True for emulated SCSI host adapters (e.g. ATAPI) */ unsigned emulated:1; + unsigned highmem_io:1; + /* * Name of proc directory */ @@ -317,6 +312,7 @@ struct Scsi_Host * next; Scsi_Device * host_queue; + spinlock_t host_lock; struct task_struct * ehandler; /* Error recovery thread. */ struct semaphore * eh_wait; /* The error recovery thread waits on @@ -338,7 +334,6 @@ int resetting; /* if set, it means that last_reset is a valid value */ unsigned long last_reset; - /* * These three parameters can be used to allow for wide scsi, * and for host adapters that support multiple busses @@ -390,6 +385,7 @@ unsigned in_recovery:1; unsigned unchecked_isa_dma:1; unsigned use_clustering:1; + unsigned highmem_io:1; /* * True if this host was loaded as a loadable module */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c --- v2.5.0/linux/drivers/scsi/ide-scsi.c Sun Sep 30 12:26:07 2001 +++ linux/drivers/scsi/ide-scsi.c Tue Dec 11 09:44:13 2001 @@ -235,14 +235,14 @@ kfree(atapi_buf); } -static inline void idescsi_free_bh (struct buffer_head *bh) +static inline void idescsi_free_bio (struct bio *bio) { - struct buffer_head *bhp; + struct bio *bhp; - while (bh) { - bhp = bh; - bh = bh->b_reqnext; - kfree (bhp); + while (bio) { + bhp = bio; + bio = bio->bi_next; + bio_put(bhp); } } @@ -261,12 +261,13 @@ ide_drive_t *drive = hwgroup->drive; idescsi_scsi_t *scsi = drive->driver_data; struct request *rq = hwgroup->rq; - idescsi_pc_t *pc = (idescsi_pc_t *) rq->buffer; + idescsi_pc_t *pc = (idescsi_pc_t *) rq->special; int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); + struct Scsi_Host *host; u8 *scsi_buf; unsigned long flags; - if (rq->cmd != IDESCSI_PC_RQ) { + if (!(rq->flags & REQ_SPECIAL)) { ide_end_request (uptodate, hwgroup); return; } @@ -291,10 +292,11 @@ } else printk("\n"); } } - spin_lock_irqsave(&io_request_lock,flags); + host = pc->scsi_cmd->host; + spin_lock_irqsave(&host->host_lock, flags); pc->done(pc->scsi_cmd); - spin_unlock_irqrestore(&io_request_lock,flags); - idescsi_free_bh (rq->bh); + spin_unlock_irqrestore(&host->host_lock, flags); + idescsi_free_bio (rq->bio); kfree(pc); kfree(rq); scsi->pc = NULL; } @@ -427,7 +429,7 @@ pc->current_position=pc->buffer; bcount = IDE_MIN (pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */ - if (drive->using_dma && rq->bh) + if (drive->using_dma && rq->bio) dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive); SELECT_DRIVE(HWIF(drive), drive); @@ -461,10 +463,10 @@ printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors); #endif /* IDESCSI_DEBUG_LOG */ - if (rq->cmd == IDESCSI_PC_RQ) { - return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->buffer); + if (rq->flags & REQ_SPECIAL) { + return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->special); } - printk (KERN_ERR "ide-scsi: %s: unsupported command in request queue (%x)\n", drive->name, rq->cmd); + blk_dump_rq_flags(rq, "ide-scsi: unsup command"); idescsi_end_request (0,HWGROUP (drive)); return ide_stopped; } @@ -653,25 +655,26 @@ return -EINVAL; } -static inline struct buffer_head *idescsi_kmalloc_bh (int count) +static inline struct bio *idescsi_kmalloc_bio (int count) { - struct buffer_head *bh, *bhp, *first_bh; + struct bio *bh, *bhp, *first_bh; - if ((first_bh = bhp = bh = kmalloc (sizeof(struct buffer_head), GFP_ATOMIC)) == NULL) + if ((first_bh = bhp = bh = bio_alloc(GFP_ATOMIC, 1)) == NULL) goto abort; - memset (bh, 0, sizeof (struct buffer_head)); - bh->b_reqnext = NULL; + bio_init(bh); + bh->bi_vcnt = 1; while (--count) { - if ((bh = kmalloc (sizeof(struct buffer_head), GFP_ATOMIC)) == NULL) + if ((bh = bio_alloc(GFP_ATOMIC, 1)) == NULL) goto abort; - memset (bh, 0, sizeof (struct buffer_head)); - bhp->b_reqnext = bh; + bio_init(bh); + bh->bi_vcnt = 1; + bhp->bi_next = bh; bhp = bh; - bh->b_reqnext = NULL; + bh->bi_next = NULL; } return first_bh; abort: - idescsi_free_bh (first_bh); + idescsi_free_bio (first_bh); return NULL; } @@ -689,9 +692,9 @@ } } -static inline struct buffer_head *idescsi_dma_bh (ide_drive_t *drive, idescsi_pc_t *pc) +static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc) { - struct buffer_head *bh = NULL, *first_bh = NULL; + struct bio *bh = NULL, *first_bh = NULL; int segments = pc->scsi_cmd->use_sg; struct scatterlist *sg = pc->scsi_cmd->request_buffer; @@ -700,25 +703,43 @@ if (idescsi_set_direction(pc)) return NULL; if (segments) { - if ((first_bh = bh = idescsi_kmalloc_bh (segments)) == NULL) + if ((first_bh = bh = idescsi_kmalloc_bio (segments)) == NULL) return NULL; #if IDESCSI_DEBUG_LOG printk ("ide-scsi: %s: building DMA table, %d segments, %dkB total\n", drive->name, segments, pc->request_transfer >> 10); #endif /* IDESCSI_DEBUG_LOG */ while (segments--) { - bh->b_data = sg->address; - bh->b_size = sg->length; - bh = bh->b_reqnext; + struct page *page = sg->page; + int offset = sg->offset; + + if (!page) { + BUG_ON(!sg->address); + page = virt_to_page(sg->address); + offset = (unsigned long) sg->address & ~PAGE_MASK; + } + + bh->bi_io_vec[0].bv_page = page; + bh->bi_io_vec[0].bv_len = sg->length; + bh->bi_io_vec[0].bv_offset = offset; + bh->bi_size = sg->length; + bh = bh->bi_next; + /* + * just until scsi_merge is fixed up... + */ + BUG_ON(PageHighMem(page)); + sg->address = page_address(page) + offset; sg++; } } else { - if ((first_bh = bh = idescsi_kmalloc_bh (1)) == NULL) + if ((first_bh = bh = idescsi_kmalloc_bio (1)) == NULL) return NULL; #if IDESCSI_DEBUG_LOG printk ("ide-scsi: %s: building DMA table for a single buffer (%dkB)\n", drive->name, pc->request_transfer >> 10); #endif /* IDESCSI_DEBUG_LOG */ - bh->b_data = pc->scsi_cmd->request_buffer; - bh->b_size = pc->request_transfer; + bh->bi_io_vec[0].bv_page = virt_to_page(pc->scsi_cmd->request_buffer); + bh->bi_io_vec[0].bv_len = pc->request_transfer; + bh->bi_io_vec[0].bv_offset = (unsigned long) pc->scsi_cmd->request_buffer & ~PAGE_MASK; + bh->bi_size = pc->request_transfer; } return first_bh; } @@ -782,12 +803,12 @@ } ide_init_drive_cmd (rq); - rq->buffer = (char *) pc; - rq->bh = idescsi_dma_bh (drive, pc); - rq->cmd = IDESCSI_PC_RQ; - spin_unlock(&io_request_lock); + rq->special = (char *) pc; + rq->bio = idescsi_dma_bio (drive, pc); + rq->flags = REQ_SPECIAL; + spin_unlock(&cmd->host->host_lock); (void) ide_do_drive_cmd (drive, rq, ide_end); - spin_lock_irq(&io_request_lock); + spin_lock_irq(&cmd->host->host_lock); return 0; abort: if (pc) kfree (pc); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/imm.c linux/drivers/scsi/imm.c --- v2.5.0/linux/drivers/scsi/imm.c Sun Sep 30 12:26:07 2001 +++ linux/drivers/scsi/imm.c Sat Dec 8 20:02:47 2001 @@ -124,11 +124,6 @@ int i, nhosts, try_again; struct parport *pb; - /* - * unlock to allow the lowlevel parport driver to probe - * the irqs - */ - spin_unlock_irq(&io_request_lock); pb = parport_enumerate(); printk("imm: Version %s\n", IMM_VERSION); @@ -137,7 +132,6 @@ if (!pb) { printk("imm: parport reports no devices.\n"); - spin_lock_irq(&io_request_lock); return 0; } retry_entry: @@ -163,7 +157,6 @@ "pardevice is owning the port for too longtime!\n", i); parport_unregister_device (imm_hosts[i].dev); - spin_lock_irq(&io_request_lock); return 0; } } @@ -219,13 +212,11 @@ } if (nhosts == 0) { if (try_again == 1) { - spin_lock_irq(&io_request_lock); return 0; } try_again = 1; goto retry_entry; } else { - spin_lock_irq (&io_request_lock); return 1; /* return number of hosts detected */ } } @@ -834,7 +825,7 @@ if (cmd->SCp.buffers_residual--) { cmd->SCp.buffer++; cmd->SCp.this_residual = cmd->SCp.buffer->length; - cmd->SCp.ptr = cmd->SCp.buffer->address; + cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset; /* * Make sure that we transfer even number of bytes @@ -897,6 +888,7 @@ { imm_struct *tmp = (imm_struct *) data; Scsi_Cmnd *cmd = tmp->cur_cmd; + struct Scsi_Host *host = cmd->host; unsigned long flags; if (!cmd) { @@ -948,10 +940,10 @@ if (cmd->SCp.phase > 0) imm_pb_release(cmd->host->unique_id); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); tmp->cur_cmd = 0; cmd->scsi_done(cmd); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return; } @@ -1008,7 +1000,7 @@ /* if many buffers are available, start filling the first */ cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; cmd->SCp.this_residual = cmd->SCp.buffer->length; - cmd->SCp.ptr = cmd->SCp.buffer->address; + cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset; } else { /* else fill the only available buffer */ cmd->SCp.buffer = NULL; diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/imm.h linux/drivers/scsi/imm.h --- v2.5.0/linux/drivers/scsi/imm.h Fri Mar 2 18:38:38 2001 +++ linux/drivers/scsi/imm.h Wed Nov 28 10:22:27 2001 @@ -175,7 +175,6 @@ eh_device_reset_handler: NULL, \ eh_bus_reset_handler: imm_reset, \ eh_host_reset_handler: imm_reset, \ - use_new_eh_code: 1, \ bios_param: imm_biosparam, \ this_id: 7, \ sg_tablesize: SG_ALL, \ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/in2000.h linux/drivers/scsi/in2000.h --- v2.5.0/linux/drivers/scsi/in2000.h Thu Jul 19 21:08:18 2001 +++ linux/drivers/scsi/in2000.h Wed Nov 28 10:22:27 2001 @@ -423,7 +423,6 @@ sg_tablesize: IN2000_SG, /* scatter-gather table size */ \ cmd_per_lun: IN2000_CPL, /* commands per lun */ \ use_clustering: DISABLE_CLUSTERING, /* ENABLE_CLUSTERING may speed things up */ \ - use_new_eh_code: 0 /* new error code - not using it yet */ \ } #endif /* IN2000_H */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/ini9100u.h linux/drivers/scsi/ini9100u.h --- v2.5.0/linux/drivers/scsi/ini9100u.h Thu Oct 11 09:43:30 2001 +++ linux/drivers/scsi/ini9100u.h Wed Nov 28 10:22:27 2001 @@ -115,7 +115,6 @@ present: 0, \ unchecked_isa_dma: 0, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 0 \ } #define VIRT_TO_BUS(i) (unsigned int) virt_to_bus((void *)(i)) diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/inia100.h linux/drivers/scsi/inia100.h --- v2.5.0/linux/drivers/scsi/inia100.h Thu Oct 11 09:43:30 2001 +++ linux/drivers/scsi/inia100.h Wed Nov 28 10:22:27 2001 @@ -110,7 +110,6 @@ present: 0, \ unchecked_isa_dma: 0, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 0 \ } #define VIRT_TO_BUS(i) (unsigned int) virt_to_bus((void *)(i)) diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/ips.h linux/drivers/scsi/ips.h --- v2.5.0/linux/drivers/scsi/ips.h Sun Sep 30 12:26:08 2001 +++ linux/drivers/scsi/ips.h Wed Nov 28 10:22:27 2001 @@ -472,7 +472,6 @@ present : 0, \ unchecked_isa_dma : 0, \ use_clustering : ENABLE_CLUSTERING, \ - use_new_eh_code : 1 \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/mac53c94.h linux/drivers/scsi/mac53c94.h --- v2.5.0/linux/drivers/scsi/mac53c94.h Tue Sep 19 08:31:53 2000 +++ linux/drivers/scsi/mac53c94.h Wed Nov 28 10:22:27 2001 @@ -28,7 +28,6 @@ sg_tablesize: SG_ALL, \ cmd_per_lun: 1, \ use_clustering: DISABLE_CLUSTERING, \ - use_new_eh_code: 1, \ } /* diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/mac_esp.h linux/drivers/scsi/mac_esp.h --- v2.5.0/linux/drivers/scsi/mac_esp.h Sun Jul 9 22:51:43 2000 +++ linux/drivers/scsi/mac_esp.h Thu Nov 29 13:55:59 2001 @@ -34,8 +34,7 @@ this_id: 7, \ sg_tablesize: SG_ALL, \ cmd_per_lun: 1, \ - use_clustering: DISABLE_CLUSTERING, \ - use_new_eh_code: 0 } + use_clustering: DISABLE_CLUSTERING } #endif /* MAC_ESP_H */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c --- v2.5.0/linux/drivers/scsi/megaraid.c Thu Oct 25 13:53:51 2001 +++ linux/drivers/scsi/megaraid.c Tue Nov 27 09:23:27 2001 @@ -586,8 +586,10 @@ #define DRIVER_LOCK(p) #define DRIVER_UNLOCK(p) #define IO_LOCK_T unsigned long io_flags = 0 -#define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags); -#define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags); +#define IO_LOCK(host) spin_lock_irqsave(&(host)->host_lock,io_flags) +#define IO_UNLOCK(host) spin_unlock_irqrestore(&(host)->host_lock,io_flags) +#define IO_LOCK_IRQ(host) spin_lock_irq(&(host)->host_lock) +#define IO_UNLOCK_IRQ(host) spin_unlock_irq(&(host)->host_lock) #define queue_task_irq(a,b) queue_task(a,b) #define queue_task_irq_off(a,b) queue_task(a,b) @@ -612,8 +614,8 @@ #define DRIVER_LOCK(p) #define DRIVER_UNLOCK(p) #define IO_LOCK_T unsigned long io_flags = 0 -#define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags); -#define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags); +#define IO_LOCK(host) spin_lock_irqsave(&io_request_lock,io_flags); +#define IO_UNLOCK(host) spin_unlock_irqrestore(&io_request_lock,io_flags); #define pci_free_consistent(a,b,c,d) #define pci_unmap_single(a,b,c,d) @@ -2101,7 +2103,7 @@ for (idx = 0; idx < MAX_FIRMWARE_STATUS; idx++) completed[idx] = 0; - IO_LOCK; + IO_LOCK(megaCfg->host); megaCfg->nInterrupts++; qCnt = 0xff; @@ -2220,7 +2222,7 @@ megaCfg->flag &= ~IN_ISR; /* Loop through any pending requests */ mega_runpendq (megaCfg); - IO_UNLOCK; + IO_UNLOCK(megaCfg->host); } @@ -3032,9 +3034,7 @@ sizeof (mega_mailbox64), &(megaCfg->dma_handle64)); - mega_register_mailbox (megaCfg, - virt_to_bus ((void *) megaCfg-> - mailbox64ptr)); + mega_register_mailbox (megaCfg, megaCfg->dma_handle64); #else mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg-> @@ -3800,7 +3800,7 @@ if (pScb->SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) { init_MUTEX_LOCKED (&pScb->ioctl_sem); - spin_unlock_irq (&io_request_lock); + IO_UNLOCK_IRQ(megaCfg->host); down (&pScb->ioctl_sem); user_area = (char *)*((u32*)&pScb->SCpnt->cmnd[4]); if (copy_to_user @@ -3809,7 +3809,7 @@ ("megaraid: Error copying ioctl return value to user buffer.\n"); pScb->SCpnt->result = (DID_ERROR << 16); } - spin_lock_irq (&io_request_lock); + IO_LOCK_IRQ(megaCfg->host); DRIVER_LOCK (megaCfg); kfree (pScb->buff_ptr); pScb->buff_ptr = NULL; @@ -4744,10 +4744,10 @@ init_MUTEX_LOCKED(&mimd_ioctl_sem); - IO_LOCK; + IO_LOCK(shpnt); megaraid_queue(scsicmd, megadev_ioctl_done); - IO_UNLOCK; + IO_UNLOCK(shpnt); down(&mimd_ioctl_sem); @@ -4893,10 +4893,10 @@ init_MUTEX_LOCKED (&mimd_ioctl_sem); - IO_LOCK; + IO_LOCK(shpnt); megaraid_queue (scsicmd, megadev_ioctl_done); - IO_UNLOCK; + IO_UNLOCK(shpnt); down (&mimd_ioctl_sem); if (!scsicmd->result && outlen) { diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/megaraid.h linux/drivers/scsi/megaraid.h --- v2.5.0/linux/drivers/scsi/megaraid.h Thu Oct 25 13:53:51 2001 +++ linux/drivers/scsi/megaraid.h Tue Nov 27 09:23:27 2001 @@ -223,7 +223,8 @@ cmd_per_lun: MAX_CMD_PER_LUN, /* SCSI Commands per LUN */\ present: 0, /* Present */\ unchecked_isa_dma: 0, /* Default Unchecked ISA DMA */\ - use_clustering: ENABLE_CLUSTERING /* Enable Clustering */\ + use_clustering: ENABLE_CLUSTERING, /* Enable Clustering */\ + highmem_io: 1, \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/mesh.h linux/drivers/scsi/mesh.h --- v2.5.0/linux/drivers/scsi/mesh.h Tue Sep 19 08:31:53 2000 +++ linux/drivers/scsi/mesh.h Wed Nov 28 10:22:27 2001 @@ -28,7 +28,6 @@ sg_tablesize: SG_ALL, \ cmd_per_lun: 2, \ use_clustering: DISABLE_CLUSTERING, \ - use_new_eh_code: 1, \ } /* diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.5.0/linux/drivers/scsi/ncr53c8xx.c Sun Sep 30 12:26:07 2001 +++ linux/drivers/scsi/ncr53c8xx.c Sun Dec 16 12:20:20 2001 @@ -22,7 +22,7 @@ ** This driver has been ported to Linux from the FreeBSD NCR53C8XX driver ** and is currently maintained by ** -** Gerard Roudier +** Gerard Roudier ** ** Being given that this driver originates from the FreeBSD version, and ** in order to keep synergy on both, any suggested enhancements and corrections @@ -63,7 +63,7 @@ ** August 18 1997 by Cort : ** Support for Power/PC (Big Endian). ** -** June 20 1998 by Gerard Roudier : +** June 20 1998 by Gerard Roudier ** Support for up to 64 tags per lun. ** O(1) everywhere (C and SCRIPTS) for normal cases. ** Low PCI traffic for command handling when on-chip RAM is present. @@ -8127,10 +8127,14 @@ segment = 1; } } - else if (use_sg <= MAX_SCATTER) { + else { struct scatterlist *scatter = (struct scatterlist *)cmd->buffer; use_sg = map_scsi_sg_data(np, cmd); + if (use_sg > MAX_SCATTER) { + unmap_scsi_data(np, cmd); + return -1; + } data = &data[MAX_SCATTER - use_sg]; while (segment < use_sg) { @@ -8142,9 +8146,6 @@ cp->data_len += len; ++segment; } - } - else { - return -1; } return segment; diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/ncr53c8xx.h linux/drivers/scsi/ncr53c8xx.h --- v2.5.0/linux/drivers/scsi/ncr53c8xx.h Tue Mar 6 19:34:25 2001 +++ linux/drivers/scsi/ncr53c8xx.h Sun Dec 16 12:20:20 2001 @@ -22,7 +22,7 @@ ** This driver has been ported to Linux from the FreeBSD NCR53C8XX driver ** and is currently maintained by ** -** Gerard Roudier +** Gerard Roudier ** ** Being given that this driver originates from the FreeBSD version, and ** in order to keep synergy on both, any suggested enhancements and corrections diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/pci2000.h linux/drivers/scsi/pci2000.h --- v2.5.0/linux/drivers/scsi/pci2000.h Thu Jul 19 21:07:53 2001 +++ linux/drivers/scsi/pci2000.h Wed Nov 28 10:22:27 2001 @@ -218,7 +218,6 @@ present: 0, \ unchecked_isa_dma:0, \ use_clustering: DISABLE_CLUSTERING, \ - use_new_eh_code:0 \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/pci2220i.h linux/drivers/scsi/pci2220i.h --- v2.5.0/linux/drivers/scsi/pci2220i.h Thu Jul 19 21:07:54 2001 +++ linux/drivers/scsi/pci2220i.h Wed Nov 28 10:22:27 2001 @@ -56,6 +56,5 @@ present: 0, \ unchecked_isa_dma: 0, \ use_clustering: DISABLE_CLUSTERING, \ - use_new_eh_code: 0 \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/pcmcia/nsp_cs.c linux/drivers/scsi/pcmcia/nsp_cs.c --- v2.5.0/linux/drivers/scsi/pcmcia/nsp_cs.c Thu Oct 11 09:04:57 2001 +++ linux/drivers/scsi/pcmcia/nsp_cs.c Wed Nov 28 10:22:27 2001 @@ -149,7 +149,6 @@ /* present: 0,*/ /* unchecked_isa_dma: 0,*/ use_clustering: DISABLE_CLUSTERING, - use_new_eh_code: 0, /* emulated: 0,*/ }; diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/pluto.h linux/drivers/scsi/pluto.h --- v2.5.0/linux/drivers/scsi/pluto.h Thu Jan 27 12:53:32 2000 +++ linux/drivers/scsi/pluto.h Wed Nov 28 10:22:27 2001 @@ -53,7 +53,6 @@ sg_tablesize: 1, \ cmd_per_lun: 1, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: FCP_SCSI_USE_NEW_EH_CODE, \ abort: fcp_old_abort, \ eh_abort_handler: fcp_scsi_abort, \ eh_device_reset_handler:fcp_scsi_dev_reset, \ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/ppa.h linux/drivers/scsi/ppa.h --- v2.5.0/linux/drivers/scsi/ppa.h Fri Mar 2 18:38:39 2001 +++ linux/drivers/scsi/ppa.h Wed Nov 28 10:22:27 2001 @@ -183,7 +183,6 @@ eh_device_reset_handler: NULL, \ eh_bus_reset_handler: ppa_reset, \ eh_host_reset_handler: ppa_reset, \ - use_new_eh_code: 1, \ bios_param: ppa_biosparam, \ this_id: -1, \ sg_tablesize: SG_ALL, \ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/qla1280.h linux/drivers/scsi/qla1280.h --- v2.5.0/linux/drivers/scsi/qla1280.h Mon Sep 17 13:16:31 2001 +++ linux/drivers/scsi/qla1280.h Wed Nov 28 10:22:27 2001 @@ -1726,7 +1726,6 @@ present: 0, /* number of 7xxx's present */\ unchecked_isa_dma: 0, /* no memory DMA restrictions */\ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 0, \ emulated: 0 \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c --- v2.5.0/linux/drivers/scsi/qlogicfc.c Thu Oct 25 13:53:51 2001 +++ linux/drivers/scsi/qlogicfc.c Sun Dec 16 12:20:20 2001 @@ -734,7 +734,6 @@ scsi_set_pci_device(host, pdev); host->max_id = QLOGICFC_MAX_ID + 1; host->max_lun = QLOGICFC_MAX_LUN; - host->hostt->use_new_eh_code = 1; hostdata = (struct isp2x00_hostdata *) host->hostdata; memset(hostdata, 0, sizeof(struct isp2x00_hostdata)); @@ -1376,7 +1375,7 @@ hostdata->explore_timer.data = 0; del_timer(&hostdata->explore_timer); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); if (hostdata->adapter_state & AS_REDO_FABRIC_PORTDB || hostdata->adapter_state & AS_REDO_LOOP_PORTDB) { isp2x00_make_portdb(host); @@ -1423,7 +1422,7 @@ hostdata->adapter_state = AS_LOOP_GOOD; } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); } @@ -1431,11 +1430,12 @@ void do_isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs) { + struct Scsi_Host *host = dev_id; unsigned long flags; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); isp2x00_intr_handler(irq, dev_id, regs); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); } void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs) @@ -2042,10 +2042,7 @@ return 1; } - if (!(command & PCI_COMMAND_MASTER)) { - printk("qlogicfc%d : bus mastering is disabled\n", hostdata->host_id); - return 1; - } + pci_set_master(pdev); if (revision != ISP2100_REV_ID1 && revision != ISP2100_REV_ID3 && revision != ISP2200_REV_ID5) printk("qlogicfc%d : new isp2x00 revision ID (%d)\n", hostdata->host_id, revision); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/qlogicfc.h linux/drivers/scsi/qlogicfc.h --- v2.5.0/linux/drivers/scsi/qlogicfc.h Sun Oct 21 10:36:54 2001 +++ linux/drivers/scsi/qlogicfc.h Tue Nov 27 09:23:27 2001 @@ -95,7 +95,8 @@ cmd_per_lun: QLOGICFC_CMD_PER_LUN, \ present: 0, \ unchecked_isa_dma: 0, \ - use_clustering: ENABLE_CLUSTERING \ + use_clustering: ENABLE_CLUSTERING, \ + highmem_io: 1 \ } #endif /* _QLOGICFC_H */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c --- v2.5.0/linux/drivers/scsi/qlogicisp.c Thu Oct 25 13:53:51 2001 +++ linux/drivers/scsi/qlogicisp.c Sun Dec 16 12:20:20 2001 @@ -970,11 +970,12 @@ void do_isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs) { + struct Scsi_Host *host = dev_id; unsigned long flags; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); isp1020_intr_handler(irq, dev_id, regs); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); } void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs) @@ -1403,11 +1404,6 @@ command &= ~PCI_COMMAND_MEMORY; #endif - if (!(command & PCI_COMMAND_MASTER)) { - printk("qlogicisp : bus mastering is disabled\n"); - return 1; - } - sh->io_port = io_base; if (!request_region(sh->io_port, 0xff, "qlogicisp")) { @@ -1471,6 +1467,8 @@ printk("qlogicisp : can't allocate request queue\n"); goto out_unmap; } + + pci_set_master(pdev); LEAVE("isp1020_init"); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/qlogicpti.c linux/drivers/scsi/qlogicpti.c --- v2.5.0/linux/drivers/scsi/qlogicpti.c Tue Oct 30 15:08:11 2001 +++ linux/drivers/scsi/qlogicpti.c Sun Dec 16 12:20:20 2001 @@ -1445,7 +1445,7 @@ spin_unlock(&qpti->lock); if (dq != NULL) { - spin_lock(&io_request_lock); + spin_lock(&qpti->qhost->host_lock); do { Scsi_Cmnd *next; @@ -1453,7 +1453,7 @@ dq->scsi_done(dq); dq = next; } while (dq != NULL); - spin_unlock(&io_request_lock); + spin_unlock(&qpti->qhost->host_lock); } __restore_flags(flags); } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/qlogicpti.h linux/drivers/scsi/qlogicpti.h --- v2.5.0/linux/drivers/scsi/qlogicpti.h Mon Dec 20 22:06:42 1999 +++ linux/drivers/scsi/qlogicpti.h Sun Dec 16 12:20:20 2001 @@ -524,7 +524,7 @@ sg_tablesize: QLOGICPTI_MAX_SG(QLOGICPTI_REQ_QUEUE_LEN), \ cmd_per_lun: 1, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 0 \ + highmem_io: 1, \ } /* For our interrupt engine. */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.5.0/linux/drivers/scsi/scsi.c Fri Nov 9 14:05:06 2001 +++ linux/drivers/scsi/scsi.c Sun Dec 16 12:20:20 2001 @@ -55,6 +55,7 @@ #include #include #include +#include #define __KERNEL_SYSCALLS__ @@ -83,6 +84,18 @@ static void scsi_dump_status(int level); #endif +#define SG_MEMPOOL_NR 5 +#define SG_MEMPOOL_SIZE 32 + +struct scsi_host_sg_pool { + int size; + kmem_cache_t *slab; + mempool_t *pool; +}; + +static const int scsi_host_sg_pool_sizes[SG_MEMPOOL_NR] = { 8, 16, 32, 64, MAX_PHYS_SEGMENTS }; +struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR]; + /* static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $"; */ @@ -151,14 +164,6 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt); /* - * These are the interface to the old error handling code. It should go away - * someday soon. - */ -extern void scsi_old_done(Scsi_Cmnd * SCpnt); -extern void scsi_old_times_out(Scsi_Cmnd * SCpnt); - - -/* * Function: scsi_initialize_queue() * * Purpose: Selects queue handler function for a device. @@ -186,10 +191,25 @@ * handler in the list - ultimately they call scsi_request_fn * to do the dirty deed. */ -void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) { - blk_init_queue(&SDpnt->request_queue, scsi_request_fn); - blk_queue_headactive(&SDpnt->request_queue, 0); - SDpnt->request_queue.queuedata = (void *) SDpnt; +void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) +{ + request_queue_t *q = &SDpnt->request_queue; + + blk_init_queue(q, scsi_request_fn, &SHpnt->host_lock); + q->queuedata = (void *) SDpnt; + + /* Hardware imposed limit. */ + blk_queue_max_hw_segments(q, SHpnt->sg_tablesize); + + /* + * When we remove scsi_malloc soonish, this can die too + */ + blk_queue_max_phys_segments(q, PAGE_SIZE / sizeof(struct scatterlist)); + + blk_queue_max_sectors(q, SHpnt->max_sectors); + + if (!SHpnt->use_clustering) + clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); } #ifdef MODULE @@ -227,9 +247,8 @@ req = &SCpnt->request; req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ - if (req->waiting != NULL) { + if (req->waiting) complete(req->waiting); - } } /* @@ -620,8 +639,6 @@ unsigned long flags = 0; unsigned long timeout; - ASSERT_LOCK(&io_request_lock, 0); - #if DEBUG unsigned long *ret = 0; #ifdef __mips__ @@ -633,6 +650,8 @@ host = SCpnt->host; + ASSERT_LOCK(&host->host_lock, 0); + /* Assign a unique nonzero serial_number. */ if (++serial_number == 0) serial_number = 1; @@ -660,12 +679,8 @@ mdelay(1 + 999 / HZ); host->resetting = 0; } - if (host->hostt->use_new_eh_code) { - scsi_add_timer(SCpnt, SCpnt->timeout_per_command, scsi_times_out); - } else { - scsi_add_timer(SCpnt, SCpnt->timeout_per_command, - scsi_old_times_out); - } + + scsi_add_timer(SCpnt, SCpnt->timeout_per_command, scsi_times_out); /* * We will use a queued command if possible, otherwise we will emulate the @@ -682,59 +697,37 @@ SCSI_LOG_MLQUEUE(3, printk("queuecommand : routine at %p\n", host->hostt->queuecommand)); /* - * Use the old error handling code if we haven't converted the driver - * to use the new one yet. Note - only the new queuecommand variant - * passes a meaningful return value. + * Before we queue this command, check if the command + * length exceeds what the host adapter can handle. */ - if (host->hostt->use_new_eh_code) { - /* - * Before we queue this command, check if the command - * length exceeds what the host adapter can handle. - */ - if (CDB_SIZE(SCpnt) <= SCpnt->host->max_cmd_len) { - spin_lock_irqsave(&io_request_lock, flags); - rtn = host->hostt->queuecommand(SCpnt, scsi_done); - spin_unlock_irqrestore(&io_request_lock, flags); - if (rtn != 0) { - scsi_delete_timer(SCpnt); - scsi_mlqueue_insert(SCpnt, SCSI_MLQUEUE_HOST_BUSY); - SCSI_LOG_MLQUEUE(3, printk("queuecommand : request rejected\n")); - } - } else { - SCSI_LOG_MLQUEUE(3, printk("queuecommand : command too long.\n")); - SCpnt->result = (DID_ABORT << 16); - spin_lock_irqsave(&io_request_lock, flags); - scsi_done(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); - rtn = 1; + if (CDB_SIZE(SCpnt) <= SCpnt->host->max_cmd_len) { + spin_lock_irqsave(&host->host_lock, flags); + rtn = host->hostt->queuecommand(SCpnt, scsi_done); + spin_unlock_irqrestore(&host->host_lock, flags); + if (rtn != 0) { + scsi_delete_timer(SCpnt); + scsi_mlqueue_insert(SCpnt, SCSI_MLQUEUE_HOST_BUSY); + SCSI_LOG_MLQUEUE(3, + printk("queuecommand : request rejected\n")); } } else { - /* - * Before we queue this command, check if the command - * length exceeds what the host adapter can handle. - */ - if (CDB_SIZE(SCpnt) <= SCpnt->host->max_cmd_len) { - spin_lock_irqsave(&io_request_lock, flags); - host->hostt->queuecommand(SCpnt, scsi_old_done); - spin_unlock_irqrestore(&io_request_lock, flags); - } else { - SCSI_LOG_MLQUEUE(3, printk("queuecommand : command too long.\n")); - SCpnt->result = (DID_ABORT << 16); - spin_lock_irqsave(&io_request_lock, flags); - scsi_old_done(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); - rtn = 1; - } + SCSI_LOG_MLQUEUE(3, + printk("queuecommand : command too long.\n")); + SCpnt->result = (DID_ABORT << 16); + spin_lock_irqsave(&host->host_lock, flags); + scsi_done(SCpnt); + spin_unlock_irqrestore(&host->host_lock, flags); + rtn = 1; } } else { int temp; SCSI_LOG_MLQUEUE(3, printk("command() : routine at %p\n", host->hostt->command)); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); temp = host->hostt->command(SCpnt); SCpnt->result = temp; #ifdef DEBUG_DELAY - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); clock = jiffies + 4 * HZ; while (time_before(jiffies, clock)) { barrier(); @@ -742,14 +735,10 @@ } printk("done(host = %d, result = %04x) : routine at %p\n", host->host_no, temp, host->hostt->command); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); #endif - if (host->hostt->use_new_eh_code) { - scsi_done(SCpnt); - } else { - scsi_old_done(SCpnt); - } - spin_unlock_irqrestore(&io_request_lock, flags); + scsi_done(SCpnt); + spin_unlock_irqrestore(&host->host_lock, flags); } SCSI_LOG_MLQUEUE(3, printk("leaving scsi_dispatch_cmnd()\n")); return rtn; @@ -769,11 +758,13 @@ int timeout, int retries) { DECLARE_COMPLETION(wait); + request_queue_t *q = &SRpnt->sr_device->request_queue; SRpnt->sr_request.waiting = &wait; SRpnt->sr_request.rq_status = RQ_SCSI_BUSY; scsi_do_req (SRpnt, (void *) cmnd, buffer, bufflen, scsi_wait_done, timeout, retries); + generic_unplug_device(q); wait_for_completion(&wait); SRpnt->sr_request.waiting = NULL; if( SRpnt->sr_command != NULL ) @@ -817,7 +808,7 @@ Scsi_Device * SDpnt = SRpnt->sr_device; struct Scsi_Host *host = SDpnt->host; - ASSERT_LOCK(&io_request_lock, 0); + ASSERT_LOCK(&host->host_lock, 0); SCSI_LOG_MLQUEUE(4, { @@ -914,7 +905,7 @@ { struct Scsi_Host *host = SCpnt->host; - ASSERT_LOCK(&io_request_lock, 0); + ASSERT_LOCK(&host->host_lock, 0); SCpnt->owner = SCSI_OWNER_MIDLEVEL; SRpnt->sr_command = SCpnt; @@ -1004,7 +995,7 @@ { struct Scsi_Host *host = SCpnt->host; - ASSERT_LOCK(&io_request_lock, 0); + ASSERT_LOCK(&host->host_lock, 0); SCpnt->pid = scsi_pid++; SCpnt->owner = SCSI_OWNER_MIDLEVEL; @@ -1355,11 +1346,11 @@ Scsi_Request * SRpnt; unsigned long flags; - ASSERT_LOCK(&io_request_lock, 0); - host = SCpnt->host; device = SCpnt->device; + ASSERT_LOCK(&host->host_lock, 0); + /* * We need to protect the decrement, as otherwise a race condition * would exist. Fiddling with SCpnt isn't a problem as the @@ -1367,10 +1358,10 @@ * one execution context, but the device and host structures are * shared. */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); host->host_busy--; /* Indicate that we are free */ device->device_busy--; /* Decrement device usage counter. */ - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); /* * Clear the flags which say that the device/host is no longer @@ -1858,7 +1849,6 @@ Scsi_Device *SDpnt; struct Scsi_Device_Template *sdtpnt; const char *name; - unsigned long flags; int out_of_space = 0; if (tpnt->next || !tpnt->detect) @@ -1868,7 +1858,7 @@ /* If max_sectors isn't set, default to max */ if (!tpnt->max_sectors) - tpnt->max_sectors = MAX_SECTORS; + tpnt->max_sectors = 1024; pcount = next_scsi_host; @@ -1876,18 +1866,12 @@ /* The detect routine must carefully spinunlock/spinlock if it enables interrupts, since all interrupt handlers do - spinlock as well. - All lame drivers are going to fail due to the following - spinlock. For the time beeing let's use it only for drivers - using the new scsi code. NOTE: the detect routine could - redefine the value tpnt->use_new_eh_code. (DB, 13 May 1998) */ - - if (tpnt->use_new_eh_code) { - spin_lock_irqsave(&io_request_lock, flags); - tpnt->present = tpnt->detect(tpnt); - spin_unlock_irqrestore(&io_request_lock, flags); - } else - tpnt->present = tpnt->detect(tpnt); + spinlock as well. */ + + /* + * detect should do its own locking + */ + tpnt->present = tpnt->detect(tpnt); if (tpnt->present) { if (pcount == next_scsi_host) { @@ -1921,7 +1905,7 @@ * handle error correction. */ for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) { - if (shpnt->hostt == tpnt && shpnt->hostt->use_new_eh_code) { + if (shpnt->hostt == tpnt) { DECLARE_MUTEX_LOCKED(sem); shpnt->eh_notify = &sem; @@ -1983,13 +1967,6 @@ } } - /* - * Now that we have all of the devices, resize the DMA pool, - * as required. */ - if (!out_of_space) - scsi_resize_dma_pool(); - - /* This does any final handling that is required. */ for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) { if (sdtpnt->finish && sdtpnt->nr_dev) { @@ -2129,7 +2106,6 @@ */ for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) { if (shpnt->hostt == tpnt - && shpnt->hostt->use_new_eh_code && shpnt->ehandler != NULL) { DECLARE_MUTEX_LOCKED(sem); @@ -2189,14 +2165,6 @@ tpnt->present--; } - /* - * If there are absolutely no more hosts left, it is safe - * to completely nuke the DMA pool. The resize operation will - * do the right thing and free everything. - */ - if (!scsi_hosts) - scsi_resize_dma_pool(); - if (pcount0 != next_scsi_host) printk(KERN_INFO "scsi : %d host%s left.\n", next_scsi_host, (next_scsi_host == 1) ? "" : "s"); @@ -2297,8 +2265,6 @@ */ if (tpnt->finish && tpnt->nr_dev) (*tpnt->finish) (); - if (!out_of_space) - scsi_resize_dma_pool(); MOD_INC_USE_COUNT; if (out_of_space) { @@ -2564,16 +2530,81 @@ __setup("scsihosts=", scsi_setup); #endif +static void *scsi_pool_alloc(int gfp_mask, void *data) +{ + return kmem_cache_alloc(data, gfp_mask); +} + +static void scsi_pool_free(void *ptr, void *data) +{ + kmem_cache_free(data, ptr); +} + +struct scatterlist *scsi_alloc_sgtable(Scsi_Cmnd *SCpnt, int gfp_mask) +{ + struct scsi_host_sg_pool *sgp; + struct scatterlist *sgl; + + BUG_ON(!SCpnt->use_sg); + + switch (SCpnt->use_sg) { + case 1 ... 8 : SCpnt->sglist_len = 0; break; + case 9 ... 16 : SCpnt->sglist_len = 1; break; + case 17 ... 32 : SCpnt->sglist_len = 2; break; + case 33 ... 64 : SCpnt->sglist_len = 3; break; + case 65 ... MAX_PHYS_SEGMENTS : SCpnt->sglist_len = 4; break; + default: return NULL; + } + + sgp = scsi_sg_pools + SCpnt->sglist_len; + + sgl = mempool_alloc(sgp->pool, gfp_mask); + if (sgl) { + memset(sgl, 0, sgp->size); + return sgl; + } + + return sgl; +} + +void scsi_free_sgtable(struct scatterlist *sgl, int index) +{ + struct scsi_host_sg_pool *sgp = scsi_sg_pools + index; + + if (unlikely(index > SG_MEMPOOL_NR)) { + printk("scsi_free_sgtable: mempool %d\n", index); + BUG(); + } + + mempool_free(sgl, sgp->pool); +} + static int __init init_scsi(void) { struct proc_dir_entry *generic; + char name[16]; + int i; printk(KERN_INFO "SCSI subsystem driver " REVISION "\n"); - if( scsi_init_minimal_dma_pool() != 0 ) - { - return 1; - } + /* + * setup sg memory pools + */ + for (i = 0; i < SG_MEMPOOL_NR; i++) { + struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; + int size = scsi_host_sg_pool_sizes[i] * sizeof(struct scatterlist); + + snprintf(name, sizeof(name) - 1, "sgpool-%d", scsi_host_sg_pool_sizes[i]); + sgp->slab = kmem_cache_create(name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!sgp->slab) + panic("SCSI: can't init sg slab\n"); + + sgp->pool = mempool_create(SG_MEMPOOL_SIZE, scsi_pool_alloc, scsi_pool_free, sgp->slab); + if (!sgp->pool) + panic("SCSI: can't init sg mempool\n"); + + sgp->size = size; + } /* * This makes /proc/scsi and /proc/scsi/scsi visible. @@ -2609,6 +2640,7 @@ static void __exit exit_scsi(void) { Scsi_Host_Name *shn, *shn2 = NULL; + int i; remove_bh(SCSI_BH); @@ -2629,11 +2661,13 @@ remove_proc_entry ("scsi", 0); #endif - /* - * Free up the DMA pool. - */ - scsi_resize_dma_pool(); - + for (i = 0; i < SG_MEMPOOL_NR; i++) { + struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; + mempool_destroy(sgp->pool); + kmem_cache_destroy(sgp->slab); + sgp->pool = NULL; + sgp->slab = NULL; + } } module_init(init_scsi); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h --- v2.5.0/linux/drivers/scsi/scsi.h Thu Nov 22 11:49:15 2001 +++ linux/drivers/scsi/scsi.h Sun Dec 16 15:46:45 2001 @@ -386,15 +386,6 @@ #define ASKED_FOR_SENSE 0x20 #define SYNC_RESET 0x40 -#if defined(__mc68000__) || defined(CONFIG_APUS) -#include -#define CONTIGUOUS_BUFFERS(X,Y) \ - (virt_to_phys((X)->b_data+(X)->b_size-1)+1==virt_to_phys((Y)->b_data)) -#else -#define CONTIGUOUS_BUFFERS(X,Y) ((X->b_data+X->b_size) == Y->b_data) -#endif - - /* * This is the crap from the old error handling code. We have it in a special * place so that we can more easily delete it later on. @@ -448,6 +439,12 @@ unsigned int *secs); /* + * sg list allocations + */ +struct scatterlist *scsi_alloc_sgtable(Scsi_Cmnd *SCpnt, int gfp_mask); +void scsi_free_sgtable(struct scatterlist *sgl, int index); + +/* * Prototypes for functions in scsi_dma.c */ void scsi_resize_dma_pool(void); @@ -458,8 +455,8 @@ /* * Prototypes for functions in scsi_merge.c */ -extern void recount_segments(Scsi_Cmnd * SCpnt); -extern void initialize_merge_fn(Scsi_Device * SDpnt); +extern void scsi_initialize_merge_fn(Scsi_Device *SDpnt); +extern int scsi_init_io(Scsi_Cmnd *SCpnt); /* * Prototypes for functions in scsi_queue.c @@ -564,8 +561,6 @@ request_queue_t request_queue; atomic_t device_active; /* commands checked out for device */ volatile unsigned short device_busy; /* commands actually active on low-level */ - int (*scsi_init_io_fn) (Scsi_Cmnd *); /* Used to initialize - new request */ Scsi_Cmnd *device_queue; /* queue of SCSI Command structures */ /* public: */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c --- v2.5.0/linux/drivers/scsi/scsi_debug.c Fri Oct 12 15:35:54 2001 +++ linux/drivers/scsi/scsi_debug.c Sun Dec 16 12:20:20 2001 @@ -182,7 +182,6 @@ }; printk("\n"); #endif - printk("DMA free %d sectors.\n", scsi_dma_free_sectors); } int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) @@ -653,7 +652,6 @@ int scsi_debug_biosparam(Disk * disk, kdev_t dev, int *info) { - int size = disk->capacity; info[0] = N_HEAD; info[1] = N_SECTOR; info[2] = N_CYLINDER; diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_debug.h linux/drivers/scsi/scsi_debug.h --- v2.5.0/linux/drivers/scsi/scsi_debug.h Mon Dec 11 13:19:52 2000 +++ linux/drivers/scsi/scsi_debug.h Wed Nov 28 10:22:27 2001 @@ -37,6 +37,5 @@ cmd_per_lun: 3, \ unchecked_isa_dma: 0, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1, \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_dma.c linux/drivers/scsi/scsi_dma.c --- v2.5.0/linux/drivers/scsi/scsi_dma.c Tue Sep 5 14:08:55 2000 +++ linux/drivers/scsi/scsi_dma.c Wed Dec 31 16:00:00 1969 @@ -1,450 +0,0 @@ -/* - * scsi_dma.c Copyright (C) 2000 Eric Youngdale - * - * mid-level SCSI DMA bounce buffer allocator - * - */ - -#define __NO_VERSION__ -#include -#include -#include - - -#include "scsi.h" -#include "hosts.h" -#include "constants.h" - -#ifdef CONFIG_KMOD -#include -#endif - -/* - * PAGE_SIZE must be a multiple of the sector size (512). True - * for all reasonably recent architectures (even the VAX...). - */ -#define SECTOR_SIZE 512 -#define SECTORS_PER_PAGE (PAGE_SIZE/SECTOR_SIZE) - -#if SECTORS_PER_PAGE <= 8 -typedef unsigned char FreeSectorBitmap; -#elif SECTORS_PER_PAGE <= 32 -typedef unsigned int FreeSectorBitmap; -#else -#error You lose. -#endif - -/* - * Used for access to internal allocator used for DMA safe buffers. - */ -static spinlock_t allocator_request_lock = SPIN_LOCK_UNLOCKED; - -static FreeSectorBitmap *dma_malloc_freelist = NULL; -static int need_isa_bounce_buffers; -static unsigned int dma_sectors = 0; -unsigned int scsi_dma_free_sectors = 0; -unsigned int scsi_need_isa_buffer = 0; -static unsigned char **dma_malloc_pages = NULL; - -/* - * Function: scsi_malloc - * - * Purpose: Allocate memory from the DMA-safe pool. - * - * Arguments: len - amount of memory we need. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Pointer to memory block. - * - * Notes: Prior to the new queue code, this function was not SMP-safe. - * This function can only allocate in units of sectors - * (i.e. 512 bytes). - * - * We cannot use the normal system allocator becuase we need - * to be able to guarantee that we can process a complete disk - * I/O request without touching the system allocator. Think - * about it - if the system were heavily swapping, and tried to - * write out a block of memory to disk, and the SCSI code needed - * to allocate more memory in order to be able to write the - * data to disk, you would wedge the system. - */ -void *scsi_malloc(unsigned int len) -{ - unsigned int nbits, mask; - unsigned long flags; - - int i, j; - if (len % SECTOR_SIZE != 0 || len > PAGE_SIZE) - return NULL; - - nbits = len >> 9; - mask = (1 << nbits) - 1; - - spin_lock_irqsave(&allocator_request_lock, flags); - - for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) - for (j = 0; j <= SECTORS_PER_PAGE - nbits; j++) { - if ((dma_malloc_freelist[i] & (mask << j)) == 0) { - dma_malloc_freelist[i] |= (mask << j); - scsi_dma_free_sectors -= nbits; -#ifdef DEBUG - SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9))); - printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9)); -#endif - spin_unlock_irqrestore(&allocator_request_lock, flags); - return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9)); - } - } - spin_unlock_irqrestore(&allocator_request_lock, flags); - return NULL; /* Nope. No more */ -} - -/* - * Function: scsi_free - * - * Purpose: Free memory into the DMA-safe pool. - * - * Arguments: ptr - data block we are freeing. - * len - size of block we are freeing. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Nothing - * - * Notes: This function *must* only be used to free memory - * allocated from scsi_malloc(). - * - * Prior to the new queue code, this function was not SMP-safe. - * This function can only allocate in units of sectors - * (i.e. 512 bytes). - */ -int scsi_free(void *obj, unsigned int len) -{ - unsigned int page, sector, nbits, mask; - unsigned long flags; - -#ifdef DEBUG - unsigned long ret = 0; - -#ifdef __mips__ - __asm__ __volatile__("move\t%0,$31":"=r"(ret)); -#else - ret = __builtin_return_address(0); -#endif - printk("scsi_free %p %d\n", obj, len); - SCSI_LOG_MLQUEUE(3, printk("SFree: %p %d\n", obj, len)); -#endif - - spin_lock_irqsave(&allocator_request_lock, flags); - - for (page = 0; page < dma_sectors / SECTORS_PER_PAGE; page++) { - unsigned long page_addr = (unsigned long) dma_malloc_pages[page]; - if ((unsigned long) obj >= page_addr && - (unsigned long) obj < page_addr + PAGE_SIZE) { - sector = (((unsigned long) obj) - page_addr) >> 9; - - nbits = len >> 9; - mask = (1 << nbits) - 1; - - if (sector + nbits > SECTORS_PER_PAGE) - panic("scsi_free:Bad memory alignment"); - - if ((dma_malloc_freelist[page] & - (mask << sector)) != (mask << sector)) { -#ifdef DEBUG - printk("scsi_free(obj=%p, len=%d) called from %08lx\n", - obj, len, ret); -#endif - panic("scsi_free:Trying to free unused memory"); - } - scsi_dma_free_sectors += nbits; - dma_malloc_freelist[page] &= ~(mask << sector); - spin_unlock_irqrestore(&allocator_request_lock, flags); - return 0; - } - } - panic("scsi_free:Bad offset"); -} - - -/* - * Function: scsi_resize_dma_pool - * - * Purpose: Ensure that the DMA pool is sufficiently large to be - * able to guarantee that we can always process I/O requests - * without calling the system allocator. - * - * Arguments: None. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Nothing - * - * Notes: Prior to the new queue code, this function was not SMP-safe. - * Go through the device list and recompute the most appropriate - * size for the dma pool. Then grab more memory (as required). - */ -void scsi_resize_dma_pool(void) -{ - int i, k; - unsigned long size; - unsigned long flags; - struct Scsi_Host *shpnt; - struct Scsi_Host *host = NULL; - Scsi_Device *SDpnt; - FreeSectorBitmap *new_dma_malloc_freelist = NULL; - unsigned int new_dma_sectors = 0; - unsigned int new_need_isa_buffer = 0; - unsigned char **new_dma_malloc_pages = NULL; - int out_of_space = 0; - - spin_lock_irqsave(&allocator_request_lock, flags); - - if (!scsi_hostlist) { - /* - * Free up the DMA pool. - */ - if (scsi_dma_free_sectors != dma_sectors) - panic("SCSI DMA pool memory leak %d %d\n", scsi_dma_free_sectors, dma_sectors); - - for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) - free_pages((unsigned long) dma_malloc_pages[i], 0); - if (dma_malloc_pages) - kfree((char *) dma_malloc_pages); - dma_malloc_pages = NULL; - if (dma_malloc_freelist) - kfree((char *) dma_malloc_freelist); - dma_malloc_freelist = NULL; - dma_sectors = 0; - scsi_dma_free_sectors = 0; - spin_unlock_irqrestore(&allocator_request_lock, flags); - return; - } - /* Next, check to see if we need to extend the DMA buffer pool */ - - new_dma_sectors = 2 * SECTORS_PER_PAGE; /* Base value we use */ - - if (__pa(high_memory) - 1 > ISA_DMA_THRESHOLD) - need_isa_bounce_buffers = 1; - else - need_isa_bounce_buffers = 0; - - if (scsi_devicelist) - for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) - new_dma_sectors += SECTORS_PER_PAGE; /* Increment for each host */ - - for (host = scsi_hostlist; host; host = host->next) { - for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) { - /* - * sd and sr drivers allocate scatterlists. - * sr drivers may allocate for each command 1x2048 or 2x1024 extra - * buffers for 2k sector size and 1k fs. - * sg driver allocates buffers < 4k. - * st driver does not need buffers from the dma pool. - * estimate 4k buffer/command for devices of unknown type (should panic). - */ - if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM || - SDpnt->type == TYPE_DISK || SDpnt->type == TYPE_MOD) { - int nents = host->sg_tablesize; -#ifdef DMA_CHUNK_SIZE - /* If the architecture does DMA sg merging, make sure - we count with at least 64 entries even for HBAs - which handle very few sg entries. */ - if (nents < 64) nents = 64; -#endif - new_dma_sectors += ((nents * - sizeof(struct scatterlist) + 511) >> 9) * - SDpnt->queue_depth; - if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM) - new_dma_sectors += (2048 >> 9) * SDpnt->queue_depth; - } else if (SDpnt->type == TYPE_SCANNER || - SDpnt->type == TYPE_PROCESSOR || - SDpnt->type == TYPE_COMM || - SDpnt->type == TYPE_MEDIUM_CHANGER || - SDpnt->type == TYPE_ENCLOSURE) { - new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth; - } else { - if (SDpnt->type != TYPE_TAPE) { - printk("resize_dma_pool: unknown device type %d\n", SDpnt->type); - new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth; - } - } - - if (host->unchecked_isa_dma && - need_isa_bounce_buffers && - SDpnt->type != TYPE_TAPE) { - new_dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize * - SDpnt->queue_depth; - new_need_isa_buffer++; - } - } - } - -#ifdef DEBUG_INIT - printk("resize_dma_pool: needed dma sectors = %d\n", new_dma_sectors); -#endif - - /* limit DMA memory to 32MB: */ - new_dma_sectors = (new_dma_sectors + 15) & 0xfff0; - - /* - * We never shrink the buffers - this leads to - * race conditions that I would rather not even think - * about right now. - */ -#if 0 /* Why do this? No gain and risks out_of_space */ - if (new_dma_sectors < dma_sectors) - new_dma_sectors = dma_sectors; -#endif - if (new_dma_sectors <= dma_sectors) { - spin_unlock_irqrestore(&allocator_request_lock, flags); - return; /* best to quit while we are in front */ - } - - for (k = 0; k < 20; ++k) { /* just in case */ - out_of_space = 0; - size = (new_dma_sectors / SECTORS_PER_PAGE) * - sizeof(FreeSectorBitmap); - new_dma_malloc_freelist = (FreeSectorBitmap *) - kmalloc(size, GFP_ATOMIC); - if (new_dma_malloc_freelist) { - memset(new_dma_malloc_freelist, 0, size); - size = (new_dma_sectors / SECTORS_PER_PAGE) * - sizeof(*new_dma_malloc_pages); - new_dma_malloc_pages = (unsigned char **) - kmalloc(size, GFP_ATOMIC); - if (!new_dma_malloc_pages) { - size = (new_dma_sectors / SECTORS_PER_PAGE) * - sizeof(FreeSectorBitmap); - kfree((char *) new_dma_malloc_freelist); - out_of_space = 1; - } else { - memset(new_dma_malloc_pages, 0, size); - } - } else - out_of_space = 1; - - if ((!out_of_space) && (new_dma_sectors > dma_sectors)) { - for (i = dma_sectors / SECTORS_PER_PAGE; - i < new_dma_sectors / SECTORS_PER_PAGE; i++) { - new_dma_malloc_pages[i] = (unsigned char *) - __get_free_pages(GFP_ATOMIC | GFP_DMA, 0); - if (!new_dma_malloc_pages[i]) - break; - } - if (i != new_dma_sectors / SECTORS_PER_PAGE) { /* clean up */ - int k = i; - - out_of_space = 1; - for (i = 0; i < k; ++i) - free_pages((unsigned long) new_dma_malloc_pages[i], 0); - } - } - if (out_of_space) { /* try scaling down new_dma_sectors request */ - printk("scsi::resize_dma_pool: WARNING, dma_sectors=%u, " - "wanted=%u, scaling\n", dma_sectors, new_dma_sectors); - if (new_dma_sectors < (8 * SECTORS_PER_PAGE)) - break; /* pretty well hopeless ... */ - new_dma_sectors = (new_dma_sectors * 3) / 4; - new_dma_sectors = (new_dma_sectors + 15) & 0xfff0; - if (new_dma_sectors <= dma_sectors) - break; /* stick with what we have got */ - } else - break; /* found space ... */ - } /* end of for loop */ - if (out_of_space) { - spin_unlock_irqrestore(&allocator_request_lock, flags); - scsi_need_isa_buffer = new_need_isa_buffer; /* some useful info */ - printk(" WARNING, not enough memory, pool not expanded\n"); - return; - } - /* When we dick with the actual DMA list, we need to - * protect things - */ - if (dma_malloc_freelist) { - size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap); - memcpy(new_dma_malloc_freelist, dma_malloc_freelist, size); - kfree((char *) dma_malloc_freelist); - } - dma_malloc_freelist = new_dma_malloc_freelist; - - if (dma_malloc_pages) { - size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages); - memcpy(new_dma_malloc_pages, dma_malloc_pages, size); - kfree((char *) dma_malloc_pages); - } - scsi_dma_free_sectors += new_dma_sectors - dma_sectors; - dma_malloc_pages = new_dma_malloc_pages; - dma_sectors = new_dma_sectors; - scsi_need_isa_buffer = new_need_isa_buffer; - - spin_unlock_irqrestore(&allocator_request_lock, flags); - -#ifdef DEBUG_INIT - printk("resize_dma_pool: dma free sectors = %d\n", scsi_dma_free_sectors); - printk("resize_dma_pool: dma sectors = %d\n", dma_sectors); - printk("resize_dma_pool: need isa buffers = %d\n", scsi_need_isa_buffer); -#endif -} - -/* - * Function: scsi_init_minimal_dma_pool - * - * Purpose: Allocate a minimal (1-page) DMA pool. - * - * Arguments: None. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Nothing - * - * Notes: - */ -int scsi_init_minimal_dma_pool(void) -{ - unsigned long size; - unsigned long flags; - int has_space = 0; - - spin_lock_irqsave(&allocator_request_lock, flags); - - dma_sectors = PAGE_SIZE / SECTOR_SIZE; - scsi_dma_free_sectors = dma_sectors; - /* - * Set up a minimal DMA buffer list - this will be used during scan_scsis - * in some cases. - */ - - /* One bit per sector to indicate free/busy */ - size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap); - dma_malloc_freelist = (FreeSectorBitmap *) - kmalloc(size, GFP_ATOMIC); - if (dma_malloc_freelist) { - memset(dma_malloc_freelist, 0, size); - /* One pointer per page for the page list */ - dma_malloc_pages = (unsigned char **) kmalloc( - (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages), - GFP_ATOMIC); - if (dma_malloc_pages) { - memset(dma_malloc_pages, 0, size); - dma_malloc_pages[0] = (unsigned char *) - __get_free_pages(GFP_ATOMIC | GFP_DMA, 0); - if (dma_malloc_pages[0]) - has_space = 1; - } - } - if (!has_space) { - if (dma_malloc_freelist) { - kfree((char *) dma_malloc_freelist); - if (dma_malloc_pages) - kfree((char *) dma_malloc_pages); - } - spin_unlock_irqrestore(&allocator_request_lock, flags); - printk("scsi::init_module: failed, out of memory\n"); - return 1; - } - - spin_unlock_irqrestore(&allocator_request_lock, flags); - return 0; -} diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c --- v2.5.0/linux/drivers/scsi/scsi_error.c Sun Sep 9 10:52:35 2001 +++ linux/drivers/scsi/scsi_error.c Wed Dec 12 13:41:03 2001 @@ -423,8 +423,6 @@ unsigned char scsi_result0[256], *scsi_result = NULL; int saved_result; - ASSERT_LOCK(&io_request_lock, 0); - memcpy((void *) SCpnt->cmnd, (void *) generic_sense, sizeof(generic_sense)); @@ -583,16 +581,14 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout) { unsigned long flags; - struct Scsi_Host *host; - - ASSERT_LOCK(&io_request_lock, 0); + struct Scsi_Host *host = SCpnt->host; - host = SCpnt->host; + ASSERT_LOCK(&host->host_lock, 0); - retry: +retry: /* - * We will use a queued command if possible, otherwise we will emulate the - * queuing and calling of completion function ourselves. + * We will use a queued command if possible, otherwise we will + * emulate the queuing and calling of completion function ourselves. */ SCpnt->owner = SCSI_OWNER_LOWLEVEL; @@ -609,9 +605,9 @@ SCpnt->host->eh_action = &sem; SCpnt->request.rq_status = RQ_SCSI_BUSY; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); host->hostt->queuecommand(SCpnt, scsi_eh_done); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); down(&sem); @@ -634,10 +630,10 @@ * abort a timed out command or not. Not sure how * we should treat them differently anyways. */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); if (SCpnt->host->hostt->eh_abort_handler) SCpnt->host->hostt->eh_abort_handler(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); SCpnt->request.rq_status = RQ_SCSI_DONE; SCpnt->owner = SCSI_OWNER_ERROR_HANDLER; @@ -650,13 +646,13 @@ int temp; /* - * We damn well had better never use this code. There is no timeout - * protection here, since we would end up waiting in the actual low - * level driver, we don't know how to wake it up. + * We damn well had better never use this code. There is no + * timeout protection here, since we would end up waiting in + * the actual low level driver, we don't know how to wake it up. */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); temp = host->hostt->command(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); SCpnt->result = temp; /* Fall through to code below to examine status. */ @@ -664,8 +660,8 @@ } /* - * Now examine the actual status codes to see whether the command actually - * did complete normally. + * Now examine the actual status codes to see whether the command + * actually did complete normally. */ if (SCpnt->eh_state == SUCCESS) { int ret = scsi_eh_completed_normally(SCpnt); @@ -776,9 +772,9 @@ SCpnt->owner = SCSI_OWNER_LOWLEVEL; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); rtn = SCpnt->host->hostt->eh_abort_handler(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); return rtn; } @@ -808,9 +804,9 @@ } SCpnt->owner = SCSI_OWNER_LOWLEVEL; - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); rtn = SCpnt->host->hostt->eh_device_reset_handler(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); if (rtn == SUCCESS) SCpnt->eh_state = SUCCESS; @@ -841,9 +837,9 @@ return FAILED; } - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); rtn = SCpnt->host->hostt->eh_bus_reset_handler(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); if (rtn == SUCCESS) SCpnt->eh_state = SUCCESS; @@ -887,9 +883,9 @@ if (SCpnt->host->hostt->eh_host_reset_handler == NULL) { return FAILED; } - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&SCpnt->host->host_lock, flags); rtn = SCpnt->host->hostt->eh_host_reset_handler(SCpnt); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&SCpnt->host->host_lock, flags); if (rtn == SUCCESS) SCpnt->eh_state = SUCCESS; @@ -1230,7 +1226,7 @@ Scsi_Device *SDpnt; unsigned long flags; - ASSERT_LOCK(&io_request_lock, 0); + ASSERT_LOCK(&host->host_lock, 0); /* * Next free up anything directly waiting upon the host. This will be @@ -1247,19 +1243,20 @@ * now that error recovery is done, we will need to ensure that these * requests are started. */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) { - request_queue_t *q; + request_queue_t *q = &SDpnt->request_queue; + if ((host->can_queue > 0 && (host->host_busy >= host->can_queue)) || (host->host_blocked) || (host->host_self_blocked) || (SDpnt->device_blocked)) { break; } - q = &SDpnt->request_queue; + q->request_fn(q); } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); } /* @@ -1306,7 +1303,7 @@ Scsi_Cmnd *SCdone; int timed_out; - ASSERT_LOCK(&io_request_lock, 0); + ASSERT_LOCK(&host->host_lock, 0); SCdone = NULL; diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c --- v2.5.0/linux/drivers/scsi/scsi_ioctl.c Wed Aug 15 01:22:16 2001 +++ linux/drivers/scsi/scsi_ioctl.c Sun Dec 16 12:20:21 2001 @@ -78,8 +78,7 @@ * *(char *) ((int *) arg)[2] the actual command byte. * * Note that if more than MAX_BUF bytes are requested to be transferred, - * the ioctl will fail with error EINVAL. MAX_BUF can be increased in - * the future by increasing the size that scsi_malloc will accept. + * the ioctl will fail with error EINVAL. * * This size *does not* include the initial lengths that were passed. * @@ -197,10 +196,14 @@ unsigned int inlen, outlen, cmdlen; unsigned int needed, buf_needed; int timeout, retries, result; - int data_direction; + int data_direction, gfp_mask = GFP_KERNEL; if (!sic) return -EINVAL; + + if (dev->host->unchecked_isa_dma) + gfp_mask |= GFP_DMA; + /* * Verify that we can read at least this much. */ @@ -232,7 +235,7 @@ buf_needed = (buf_needed + 511) & ~511; if (buf_needed > MAX_BUF) buf_needed = MAX_BUF; - buf = (char *) scsi_malloc(buf_needed); + buf = (char *) kmalloc(buf_needed, gfp_mask); if (!buf) return -ENOMEM; memset(buf, 0, buf_needed); @@ -341,7 +344,7 @@ error: if (buf) - scsi_free(buf, buf_needed); + kfree(buf); return result; diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_lib.c linux/drivers/scsi/scsi_lib.c --- v2.5.0/linux/drivers/scsi/scsi_lib.c Fri Oct 12 15:35:54 2001 +++ linux/drivers/scsi/scsi_lib.c Sun Dec 16 12:20:21 2001 @@ -61,7 +61,7 @@ * data - private data * at_head - insert request at head or tail of queue * - * Lock status: Assumed that io_request_lock is not held upon entry. + * Lock status: Assumed that queue lock is not held upon entry. * * Returns: Nothing */ @@ -70,12 +70,19 @@ { unsigned long flags; - ASSERT_LOCK(&io_request_lock, 0); + ASSERT_LOCK(q->queue_lock, 0); + + /* + * tell I/O scheduler that this isn't a regular read/write (ie it + * must not attempt merges on this) and that it acts as a soft + * barrier + */ + rq->flags = REQ_SPECIAL | REQ_BARRIER; - rq->cmd = SPECIAL; rq->special = data; rq->q = NULL; - rq->nr_segments = 0; + rq->bio = rq->biotail = NULL; + rq->nr_phys_segments = 0; rq->elevator_sequence = 0; /* @@ -84,15 +91,10 @@ * head of the queue for things like a QUEUE_FULL message from a * device, or a host that is unable to accept a particular command. */ - spin_lock_irqsave(&io_request_lock, flags); - - if (at_head) - list_add(&rq->queue, &q->queue_head); - else - list_add_tail(&rq->queue, &q->queue_head); - + spin_lock_irqsave(q->queue_lock, flags); + __elv_add_request(q, rq, !at_head, 0); q->request_fn(q); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(q->queue_lock, flags); } @@ -167,8 +169,6 @@ */ int scsi_init_cmd_errh(Scsi_Cmnd * SCpnt) { - ASSERT_LOCK(&io_request_lock, 0); - SCpnt->owner = SCSI_OWNER_MIDLEVEL; SCpnt->reset_chain = NULL; SCpnt->serial_number = 0; @@ -250,9 +250,9 @@ Scsi_Device *SDpnt; struct Scsi_Host *SHpnt; - ASSERT_LOCK(&io_request_lock, 0); + ASSERT_LOCK(q->queue_lock, 0); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(q->queue_lock, flags); if (SCpnt != NULL) { /* @@ -262,7 +262,7 @@ * the bad sector. */ SCpnt->request.special = (void *) SCpnt; - list_add(&SCpnt->request.queue, &q->queue_head); + __elv_add_request(q, &SCpnt->request, 0, 0); } /* @@ -280,14 +280,10 @@ * with special case code, then spin off separate versions and * use function pointers to pick the right one. */ - if (SDpnt->single_lun - && list_empty(&q->queue_head) - && SDpnt->device_busy == 0) { + if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0) { request_queue_t *q; - for (SDpnt = SHpnt->host_queue; - SDpnt; - SDpnt = SDpnt->next) { + for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) { if (((SHpnt->can_queue > 0) && (SHpnt->host_busy >= SHpnt->can_queue)) || (SHpnt->host_blocked) @@ -295,6 +291,7 @@ || (SDpnt->device_blocked)) { break; } + q = &SDpnt->request_queue; q->request_fn(q); } @@ -328,7 +325,7 @@ SHpnt->some_device_starved = 0; } } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(q->queue_lock, flags); } /* @@ -360,57 +357,19 @@ int requeue, int frequeue) { - struct request *req; - struct buffer_head *bh; - Scsi_Device * SDpnt; - int nsect; - - ASSERT_LOCK(&io_request_lock, 0); - - req = &SCpnt->request; - req->errors = 0; - if (!uptodate) { - printk(" I/O error: dev %s, sector %lu\n", - kdevname(req->rq_dev), req->sector); - } - do { - if ((bh = req->bh) != NULL) { - nsect = bh->b_size >> 9; - blk_finished_io(nsect); - req->bh = bh->b_reqnext; - bh->b_reqnext = NULL; - sectors -= nsect; - bh->b_end_io(bh, uptodate); - if ((bh = req->bh) != NULL) { - req->hard_sector += nsect; - req->hard_nr_sectors -= nsect; - req->sector += nsect; - req->nr_sectors -= nsect; - - req->current_nr_sectors = bh->b_size >> 9; - if (req->nr_sectors < req->current_nr_sectors) { - req->nr_sectors = req->current_nr_sectors; - printk("scsi_end_request: buffer-list destroyed\n"); - } - } - } - } while (sectors && bh); + request_queue_t *q = &SCpnt->device->request_queue; + struct request *req = &SCpnt->request; + + ASSERT_LOCK(q->queue_lock, 0); /* * If there are blocks left over at the end, set up the command * to queue the remainder of them. */ - if (req->bh) { - request_queue_t *q; - - if( !requeue ) - { + if (end_that_request_first(req, 1, sectors)) { + if (!requeue) return SCpnt; - } - - q = &SCpnt->device->request_queue; - req->buffer = bh->b_data; /* * Bleah. Leftovers again. Stick the leftovers in * the front of the queue, and goose the queue again. @@ -418,17 +377,15 @@ scsi_queue_next_request(q, SCpnt); return SCpnt; } + /* * This request is done. If there is someone blocked waiting for this - * request, wake them up. Typically used to wake up processes trying - * to swap a page into memory. + * request, wake them up. */ - if (req->waiting != NULL) { + if (req->waiting) complete(req->waiting); - } - add_blkdev_randomness(MAJOR(req->rq_dev)); - SDpnt = SCpnt->device; + add_blkdev_randomness(MAJOR(req->rq_dev)); /* * This will goose the queue request function at the end, so we don't @@ -436,12 +393,9 @@ */ __scsi_release_command(SCpnt); - if( frequeue ) { - request_queue_t *q; + if (frequeue) + scsi_queue_next_request(q, NULL); - q = &SDpnt->request_queue; - scsi_queue_next_request(q, NULL); - } return NULL; } @@ -489,7 +443,9 @@ */ static void scsi_release_buffers(Scsi_Cmnd * SCpnt) { - ASSERT_LOCK(&io_request_lock, 0); + struct request *req = &SCpnt->request; + + ASSERT_LOCK(&SCpnt->host->host_lock, 0); /* * Free up any indirection buffers we allocated for DMA purposes. @@ -505,14 +461,13 @@ if (bbpnt) { for (i = 0; i < SCpnt->use_sg; i++) { if (bbpnt[i]) - scsi_free(sgpnt[i].address, sgpnt[i].length); + kfree(sgpnt[i].address); } } - scsi_free(SCpnt->request_buffer, SCpnt->sglist_len); + scsi_free_sgtable(SCpnt->request_buffer, SCpnt->sglist_len); } else { - if (SCpnt->request_buffer != SCpnt->request.buffer) { - scsi_free(SCpnt->request_buffer, SCpnt->request_bufflen); - } + if (SCpnt->request_buffer != req->buffer) + kfree(SCpnt->request_buffer); } /* @@ -548,6 +503,7 @@ int result = SCpnt->result; int this_count = SCpnt->bufflen >> 9; request_queue_t *q = &SCpnt->device->request_queue; + struct request *req = &SCpnt->request; /* * We must do one of several things here: @@ -562,7 +518,7 @@ * would be used if we just wanted to retry, for example. * */ - ASSERT_LOCK(&io_request_lock, 0); + ASSERT_LOCK(q->queue_lock, 0); /* * Free up any indirection buffers we allocated for DMA purposes. @@ -580,23 +536,26 @@ if (bbpnt) { for (i = 0; i < SCpnt->use_sg; i++) { if (bbpnt[i]) { - if (SCpnt->request.cmd == READ) { + if (rq_data_dir(req) == READ) { memcpy(bbpnt[i], sgpnt[i].address, sgpnt[i].length); } - scsi_free(sgpnt[i].address, sgpnt[i].length); + kfree(sgpnt[i].address); } } } - scsi_free(SCpnt->buffer, SCpnt->sglist_len); + scsi_free_sgtable(SCpnt->buffer, SCpnt->sglist_len); } else { - if (SCpnt->buffer != SCpnt->request.buffer) { - if (SCpnt->request.cmd == READ) { - memcpy(SCpnt->request.buffer, SCpnt->buffer, - SCpnt->bufflen); + if (SCpnt->buffer != req->buffer) { + if (rq_data_dir(req) == READ) { + unsigned long flags; + char *to = bio_kmap_irq(req->bio, &flags); + + memcpy(to, SCpnt->buffer, SCpnt->bufflen); + bio_kunmap_irq(to, &flags); } - scsi_free(SCpnt->buffer, SCpnt->bufflen); + kfree(SCpnt->buffer); } } @@ -615,11 +574,10 @@ */ if (good_sectors > 0) { SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, %d sectors done.\n", - SCpnt->request.nr_sectors, - good_sectors)); + req->nr_sectors, good_sectors)); SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n ", SCpnt->use_sg)); - SCpnt->request.errors = 0; + req->errors = 0; /* * If multiple sectors are requested in one buffer, then * they will have been finished off by the first command. @@ -716,7 +674,7 @@ break; case NOT_READY: printk(KERN_INFO "Device %s not ready.\n", - kdevname(SCpnt->request.rq_dev)); + kdevname(req->rq_dev)); SCpnt = scsi_end_request(SCpnt, 0, this_count); return; break; @@ -760,7 +718,7 @@ * We sometimes get this cruft in the event that a medium error * isn't properly reported. */ - SCpnt = scsi_end_request(SCpnt, 0, SCpnt->request.current_nr_sectors); + SCpnt = scsi_end_request(SCpnt, 0, req->current_nr_sectors); return; } } @@ -774,7 +732,7 @@ * Arguments: request - I/O request we are preparing to queue. * * Lock status: No locks assumed to be held, but as it happens the - * io_request_lock is held when this is called. + * q->queue_lock is held when this is called. * * Returns: Nothing * @@ -788,8 +746,6 @@ kdev_t dev = req->rq_dev; int major = MAJOR(dev); - ASSERT_LOCK(&io_request_lock, 1); - for (spnt = scsi_devicelist; spnt; spnt = spnt->next) { /* * Search for a block device driver that supports this @@ -846,7 +802,7 @@ struct Scsi_Host *SHpnt; struct Scsi_Device_Template *STpnt; - ASSERT_LOCK(&io_request_lock, 1); + ASSERT_LOCK(q->queue_lock, 1); SDpnt = (Scsi_Device *) q->queuedata; if (!SDpnt) { @@ -864,7 +820,7 @@ * released the lock and grabbed it again, so each time * we need to check to see if the queue is plugged or not. */ - if (SHpnt->in_recovery || q->plugged) + if (SHpnt->in_recovery || blk_queue_plugged(q)) return; /* @@ -913,9 +869,9 @@ */ SDpnt->was_reset = 0; if (SDpnt->removable && !in_interrupt()) { - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(q->queue_lock); scsi_ioctl(SDpnt, SCSI_IOCTL_DOORLOCK, 0); - spin_lock_irq(&io_request_lock); + spin_lock_irq(q->queue_lock); continue; } } @@ -924,14 +880,13 @@ * If we couldn't find a request that could be queued, then we * can also quit. */ - if (list_empty(&q->queue_head)) + if (blk_queue_empty(q)) break; /* - * Loop through all of the requests in this queue, and find - * one that is queueable. + * get next queueable request. */ - req = blkdev_entry_next_request(&q->queue_head); + req = elv_next_request(q); /* * Find the actual device driver associated with this command. @@ -943,7 +898,7 @@ * these two cases differently. We differentiate by looking * at request.cmd, as this tells us the real story. */ - if (req->cmd == SPECIAL) { + if (req->flags & REQ_SPECIAL) { STpnt = NULL; SCpnt = (Scsi_Cmnd *) req->special; SRpnt = (Scsi_Request *) req->special; @@ -951,13 +906,12 @@ if( SRpnt->sr_magic == SCSI_REQ_MAGIC ) { SCpnt = scsi_allocate_device(SRpnt->sr_device, FALSE, FALSE); - if( !SCpnt ) { + if (!SCpnt) break; - } scsi_init_cmd_from_req(SCpnt, SRpnt); } - } else { + } else if (req->flags & REQ_CMD) { SRpnt = NULL; STpnt = scsi_get_request_dev(req); if (!STpnt) { @@ -966,17 +920,8 @@ /* * Now try and find a command block that we can use. */ - if( req->special != NULL ) { + if (req->special) { SCpnt = (Scsi_Cmnd *) req->special; - /* - * We need to recount the number of - * scatter-gather segments here - the - * normal case code assumes this to be - * correct, as it would be a performance - * lose to always recount. Handling - * errors is always unusual, of course. - */ - recount_segments(SCpnt); } else { SCpnt = scsi_allocate_device(SDpnt, FALSE, FALSE); } @@ -985,9 +930,11 @@ * while the queue is locked and then break out of the * loop. Otherwise loop around and try another request. */ - if (!SCpnt) { + if (!SCpnt) break; - } + } else { + blk_dump_rq_flags(req, "SCSI bad req"); + break; } /* @@ -1024,9 +971,9 @@ * another. */ req = NULL; - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(q->queue_lock); - if (SCpnt->request.cmd != SPECIAL) { + if (SCpnt->request.flags & REQ_CMD) { /* * This will do a couple of things: * 1) Fill in the actual SCSI command. @@ -1039,22 +986,22 @@ * some kinds of consistency checking may cause the * request to be rejected immediately. */ - if (STpnt == NULL) { - STpnt = scsi_get_request_dev(req); - } + if (STpnt == NULL) + STpnt = scsi_get_request_dev(&SCpnt->request); + /* * This sets up the scatter-gather table (allocating if * required). Hosts that need bounce buffers will also * get those allocated here. */ - if (!SDpnt->scsi_init_io_fn(SCpnt)) { + if (!scsi_init_io(SCpnt)) { SCpnt = __scsi_end_request(SCpnt, 0, SCpnt->request.nr_sectors, 0, 0); if( SCpnt != NULL ) { panic("Should not have leftover blocks\n"); } - spin_lock_irq(&io_request_lock); + spin_lock_irq(q->queue_lock); SHpnt->host_busy--; SDpnt->device_busy--; continue; @@ -1070,7 +1017,7 @@ { panic("Should not have leftover blocks\n"); } - spin_lock_irq(&io_request_lock); + spin_lock_irq(q->queue_lock); SHpnt->host_busy--; SDpnt->device_busy--; continue; @@ -1091,7 +1038,7 @@ * Now we need to grab the lock again. We are about to mess * with the request queue and try to find another command. */ - spin_lock_irq(&io_request_lock); + spin_lock_irq(q->queue_lock); } } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_merge.c linux/drivers/scsi/scsi_merge.c --- v2.5.0/linux/drivers/scsi/scsi_merge.c Thu Oct 25 14:05:31 2001 +++ linux/drivers/scsi/scsi_merge.c Sun Dec 16 12:20:21 2001 @@ -6,30 +6,13 @@ * Based upon conversations with large numbers * of people at Linux Expo. * Support for dynamic DMA mapping: Jakub Jelinek (jakub@redhat.com). + * Support for highmem I/O: Jens Axboe */ /* * This file contains queue management functions that are used by SCSI. - * Typically this is used for several purposes. First, we need to ensure - * that commands do not grow so large that they cannot be handled all at - * once by a host adapter. The various flavors of merge functions included - * here serve this purpose. - * - * Note that it would be quite trivial to allow the low-level driver the - * flexibility to define it's own queue handling functions. For the time - * being, the hooks are not present. Right now we are just using the - * data in the host template as an indicator of how we should be handling - * queues, and we select routines that are optimized for that purpose. - * - * Some hosts do not impose any restrictions on the size of a request. - * In such cases none of the merge functions in this file are called, - * and we allow ll_rw_blk to merge requests in the default manner. - * This isn't guaranteed to be optimal, but it should be pretty darned - * good. If someone comes up with ideas of better ways of managing queues - * to improve on the default behavior, then certainly fit it into this - * scheme in whatever manner makes the most sense. Please note that - * since each device has it's own queue, we have considerable flexibility - * in queue management. + * We need to ensure that commands do not grow so large that they cannot + * be handled all at once by a host adapter. */ #define __NO_VERSION__ @@ -64,1068 +47,71 @@ #include /* - * This means that bounce buffers cannot be allocated in chunks > PAGE_SIZE. - * Ultimately we should get away from using a dedicated DMA bounce buffer - * pool, and we should instead try and use kmalloc() instead. If we can - * eliminate this pool, then this restriction would no longer be needed. - */ -#define DMA_SEGMENT_SIZE_LIMITED - -#ifdef CONFIG_SCSI_DEBUG_QUEUES -/* - * Enable a bunch of additional consistency checking. Turn this off - * if you are benchmarking. - */ -static int dump_stats(struct request *req, - int use_clustering, - int dma_host, - int segments) -{ - struct buffer_head *bh; - - /* - * Dump the information that we have. We know we have an - * inconsistency. - */ - printk("nr_segments is %x\n", req->nr_segments); - printk("counted segments is %x\n", segments); - printk("Flags %d %d\n", use_clustering, dma_host); - for (bh = req->bh; bh->b_reqnext != NULL; bh = bh->b_reqnext) - { - printk("Segment 0x%p, blocks %d, addr 0x%lx\n", - bh, - bh->b_size >> 9, - virt_to_phys(bh->b_data - 1)); - } - panic("Ththththaats all folks. Too dangerous to continue.\n"); -} - - -/* - * Simple sanity check that we will use for the first go around - * in order to ensure that we are doing the counting correctly. - * This can be removed for optimization. - */ -#define SANITY_CHECK(req, _CLUSTER, _DMA) \ - if( req->nr_segments != __count_segments(req, _CLUSTER, _DMA, NULL) ) \ - { \ - printk("Incorrect segment count at 0x%p", current_text_addr()); \ - dump_stats(req, _CLUSTER, _DMA, __count_segments(req, _CLUSTER, _DMA, NULL)); \ - } -#else -#define SANITY_CHECK(req, _CLUSTER, _DMA) -#endif - -static void dma_exhausted(Scsi_Cmnd * SCpnt, int i) -{ - int jj; - struct scatterlist *sgpnt; - void **bbpnt; - int consumed = 0; - - sgpnt = (struct scatterlist *) SCpnt->request_buffer; - bbpnt = SCpnt->bounce_buffers; - - /* - * Now print out a bunch of stats. First, start with the request - * size. - */ - printk("dma_free_sectors:%d\n", scsi_dma_free_sectors); - printk("use_sg:%d\ti:%d\n", SCpnt->use_sg, i); - printk("request_bufflen:%d\n", SCpnt->request_bufflen); - /* - * Now dump the scatter-gather table, up to the point of failure. - */ - for(jj=0; jj < SCpnt->use_sg; jj++) - { - printk("[%d]\tlen:%d\taddr:%p\tbounce:%p\n", - jj, - sgpnt[jj].length, - sgpnt[jj].address, - (bbpnt ? bbpnt[jj] : NULL)); - if (bbpnt && bbpnt[jj]) - consumed += sgpnt[jj].length; - } - printk("Total %d sectors consumed\n", consumed); - panic("DMA pool exhausted"); -} - -/* - * FIXME(eric) - the original disk code disabled clustering for MOD - * devices. I have no idea why we thought this was a good idea - my - * guess is that it was an attempt to limit the size of requests to MOD - * devices. - */ -#define CLUSTERABLE_DEVICE(SH,SD) (SH->use_clustering && \ - SD->type != TYPE_MOD) - -/* - * This entire source file deals with the new queueing code. - */ - -/* - * Function: __count_segments() - * - * Purpose: Prototype for queue merge function. - * - * Arguments: q - Queue for which we are merging request. - * req - request into which we wish to merge. - * use_clustering - 1 if this host wishes to use clustering - * dma_host - 1 if this host has ISA DMA issues (bus doesn't - * expose all of the address lines, so that DMA cannot - * be done from an arbitrary address). - * remainder - used to track the residual size of the last - * segment. Comes in handy when we want to limit the - * size of bounce buffer segments to PAGE_SIZE. - * - * Returns: Count of the number of SG segments for the request. - * - * Lock status: - * - * Notes: This is only used for diagnostic purposes. - */ -__inline static int __count_segments(struct request *req, - int use_clustering, - int dma_host, - int * remainder) -{ - int ret = 1; - int reqsize = 0; - struct buffer_head *bh; - struct buffer_head *bhnext; - - if( remainder != NULL ) { - reqsize = *remainder; - } - - /* - * Add in the size increment for the first buffer. - */ - bh = req->bh; -#ifdef DMA_SEGMENT_SIZE_LIMITED - if( reqsize + bh->b_size > PAGE_SIZE ) { - ret++; - reqsize = bh->b_size; - } else { - reqsize += bh->b_size; - } -#else - reqsize += bh->b_size; -#endif - - for (bh = req->bh, bhnext = bh->b_reqnext; - bhnext != NULL; - bh = bhnext, bhnext = bh->b_reqnext) { - if (use_clustering) { - /* - * See if we can do this without creating another - * scatter-gather segment. In the event that this is a - * DMA capable host, make sure that a segment doesn't span - * the DMA threshold boundary. - */ - if (dma_host && - virt_to_phys(bhnext->b_data) - 1 == ISA_DMA_THRESHOLD) { - ret++; - reqsize = bhnext->b_size; - } else if (CONTIGUOUS_BUFFERS(bh, bhnext)) { - /* - * This one is OK. Let it go. - */ -#ifdef DMA_SEGMENT_SIZE_LIMITED - /* Note scsi_malloc is only able to hand out - * chunks of memory in sizes of PAGE_SIZE or - * less. Thus we need to keep track of - * the size of the piece that we have - * seen so far, and if we have hit - * the limit of PAGE_SIZE, then we are - * kind of screwed and we need to start - * another segment. - */ - if( dma_host - && virt_to_phys(bh->b_data) - 1 >= ISA_DMA_THRESHOLD - && reqsize + bhnext->b_size > PAGE_SIZE ) - { - ret++; - reqsize = bhnext->b_size; - continue; - } -#endif - reqsize += bhnext->b_size; - continue; - } - ret++; - reqsize = bhnext->b_size; - } else { - ret++; - reqsize = bhnext->b_size; - } - } - if( remainder != NULL ) { - *remainder = reqsize; - } - return ret; -} - -/* - * Function: recount_segments() - * - * Purpose: Recount the number of scatter-gather segments for this request. - * - * Arguments: req - request that needs recounting. - * - * Returns: Count of the number of SG segments for the request. - * - * Lock status: Irrelevant. - * - * Notes: This is only used when we have partially completed requests - * and the bit that is leftover is of an indeterminate size. - * This can come up if you get a MEDIUM_ERROR, for example, - * as we will have "completed" all of the sectors up to and - * including the bad sector, and the leftover bit is what - * we have to do now. This tends to be a rare occurrence, so - * we aren't busting our butts to instantiate separate versions - * of this function for the 4 different flag values. We - * probably should, however. - */ -void -recount_segments(Scsi_Cmnd * SCpnt) -{ - struct request *req; - struct Scsi_Host *SHpnt; - Scsi_Device * SDpnt; - - req = &SCpnt->request; - SHpnt = SCpnt->host; - SDpnt = SCpnt->device; - - req->nr_segments = __count_segments(req, - CLUSTERABLE_DEVICE(SHpnt, SDpnt), - SHpnt->unchecked_isa_dma, NULL); -} - -#define MERGEABLE_BUFFERS(X,Y) \ -(((((long)(X)->b_data+(X)->b_size)|((long)(Y)->b_data)) & \ - (DMA_CHUNK_SIZE - 1)) == 0) - -#ifdef DMA_CHUNK_SIZE -static inline int scsi_new_mergeable(request_queue_t * q, - struct request * req, - struct Scsi_Host *SHpnt, - int max_segments) -{ - /* - * pci_map_sg will be able to merge these two - * into a single hardware sg entry, check if - * we'll have enough memory for the sg list. - * scsi.c allocates for this purpose - * min(64,sg_tablesize) entries. - */ - if (req->nr_segments >= max_segments || - req->nr_segments >= SHpnt->sg_tablesize) - return 0; - req->nr_segments++; - return 1; -} - -static inline int scsi_new_segment(request_queue_t * q, - struct request * req, - struct Scsi_Host *SHpnt, - int max_segments) -{ - /* - * pci_map_sg won't be able to map these two - * into a single hardware sg entry, so we have to - * check if things fit into sg_tablesize. - */ - if (req->nr_hw_segments >= SHpnt->sg_tablesize || - req->nr_segments >= SHpnt->sg_tablesize) - return 0; - req->nr_hw_segments++; - req->nr_segments++; - return 1; -} -#else -static inline int scsi_new_segment(request_queue_t * q, - struct request * req, - struct Scsi_Host *SHpnt, - int max_segments) -{ - if (req->nr_segments < SHpnt->sg_tablesize && - req->nr_segments < max_segments) { - /* - * This will form the start of a new segment. Bump the - * counter. - */ - req->nr_segments++; - return 1; - } else { - return 0; - } -} -#endif - -/* - * Function: __scsi_merge_fn() - * - * Purpose: Prototype for queue merge function. - * - * Arguments: q - Queue for which we are merging request. - * req - request into which we wish to merge. - * bh - Block which we may wish to merge into request - * use_clustering - 1 if this host wishes to use clustering - * dma_host - 1 if this host has ISA DMA issues (bus doesn't - * expose all of the address lines, so that DMA cannot - * be done from an arbitrary address). - * - * Returns: 1 if it is OK to merge the block into the request. 0 - * if it is not OK. - * - * Lock status: io_request_lock is assumed to be held here. - * - * Notes: Some drivers have limited scatter-gather table sizes, and - * thus they cannot queue an infinitely large command. This - * function is called from ll_rw_blk before it attempts to merge - * a new block into a request to make sure that the request will - * not become too large. - * - * This function is not designed to be directly called. Instead - * it should be referenced from other functions where the - * use_clustering and dma_host parameters should be integer - * constants. The compiler should thus be able to properly - * optimize the code, eliminating stuff that is irrelevant. - * It is more maintainable to do this way with a single function - * than to have 4 separate functions all doing roughly the - * same thing. - */ -__inline static int __scsi_back_merge_fn(request_queue_t * q, - struct request *req, - struct buffer_head *bh, - int max_segments, - int use_clustering, - int dma_host) -{ - unsigned int count; - unsigned int segment_size = 0; - Scsi_Device *SDpnt; - struct Scsi_Host *SHpnt; - - SDpnt = (Scsi_Device *) q->queuedata; - SHpnt = SDpnt->host; - -#ifdef DMA_CHUNK_SIZE - if (max_segments > 64) - max_segments = 64; -#endif - - if ((req->nr_sectors + (bh->b_size >> 9)) > SHpnt->max_sectors) - return 0; - - if (use_clustering) { - /* - * See if we can do this without creating another - * scatter-gather segment. In the event that this is a - * DMA capable host, make sure that a segment doesn't span - * the DMA threshold boundary. - */ - if (dma_host && - virt_to_phys(req->bhtail->b_data) - 1 == ISA_DMA_THRESHOLD) { - goto new_end_segment; - } - if (CONTIGUOUS_BUFFERS(req->bhtail, bh)) { -#ifdef DMA_SEGMENT_SIZE_LIMITED - if( dma_host - && virt_to_phys(bh->b_data) - 1 >= ISA_DMA_THRESHOLD ) { - segment_size = 0; - count = __count_segments(req, use_clustering, dma_host, &segment_size); - if( segment_size + bh->b_size > PAGE_SIZE ) { - goto new_end_segment; - } - } -#endif - /* - * This one is OK. Let it go. - */ - return 1; - } - } - new_end_segment: -#ifdef DMA_CHUNK_SIZE - if (MERGEABLE_BUFFERS(req->bhtail, bh)) - return scsi_new_mergeable(q, req, SHpnt, max_segments); -#endif - return scsi_new_segment(q, req, SHpnt, max_segments); -} - -__inline static int __scsi_front_merge_fn(request_queue_t * q, - struct request *req, - struct buffer_head *bh, - int max_segments, - int use_clustering, - int dma_host) -{ - unsigned int count; - unsigned int segment_size = 0; - Scsi_Device *SDpnt; - struct Scsi_Host *SHpnt; - - SDpnt = (Scsi_Device *) q->queuedata; - SHpnt = SDpnt->host; - -#ifdef DMA_CHUNK_SIZE - if (max_segments > 64) - max_segments = 64; -#endif - - if ((req->nr_sectors + (bh->b_size >> 9)) > SHpnt->max_sectors) - return 0; - - if (use_clustering) { - /* - * See if we can do this without creating another - * scatter-gather segment. In the event that this is a - * DMA capable host, make sure that a segment doesn't span - * the DMA threshold boundary. - */ - if (dma_host && - virt_to_phys(bh->b_data) - 1 == ISA_DMA_THRESHOLD) { - goto new_start_segment; - } - if (CONTIGUOUS_BUFFERS(bh, req->bh)) { -#ifdef DMA_SEGMENT_SIZE_LIMITED - if( dma_host - && virt_to_phys(bh->b_data) - 1 >= ISA_DMA_THRESHOLD ) { - segment_size = bh->b_size; - count = __count_segments(req, use_clustering, dma_host, &segment_size); - if( count != req->nr_segments ) { - goto new_start_segment; - } - } -#endif - /* - * This one is OK. Let it go. - */ - return 1; - } - } - new_start_segment: -#ifdef DMA_CHUNK_SIZE - if (MERGEABLE_BUFFERS(bh, req->bh)) - return scsi_new_mergeable(q, req, SHpnt, max_segments); -#endif - return scsi_new_segment(q, req, SHpnt, max_segments); -} - -/* - * Function: scsi_merge_fn_() - * - * Purpose: queue merge function. - * - * Arguments: q - Queue for which we are merging request. - * req - request into which we wish to merge. - * bh - Block which we may wish to merge into request - * - * Returns: 1 if it is OK to merge the block into the request. 0 - * if it is not OK. - * - * Lock status: io_request_lock is assumed to be held here. - * - * Notes: Optimized for different cases depending upon whether - * ISA DMA is in use and whether clustering should be used. - */ -#define MERGEFCT(_FUNCTION, _BACK_FRONT, _CLUSTER, _DMA) \ -static int _FUNCTION(request_queue_t * q, \ - struct request * req, \ - struct buffer_head * bh, \ - int max_segments) \ -{ \ - int ret; \ - SANITY_CHECK(req, _CLUSTER, _DMA); \ - ret = __scsi_ ## _BACK_FRONT ## _merge_fn(q, \ - req, \ - bh, \ - max_segments, \ - _CLUSTER, \ - _DMA); \ - return ret; \ -} - -/* Version with use_clustering 0 and dma_host 1 is not necessary, - * since the only use of dma_host above is protected by use_clustering. - */ -MERGEFCT(scsi_back_merge_fn_, back, 0, 0) -MERGEFCT(scsi_back_merge_fn_c, back, 1, 0) -MERGEFCT(scsi_back_merge_fn_dc, back, 1, 1) - -MERGEFCT(scsi_front_merge_fn_, front, 0, 0) -MERGEFCT(scsi_front_merge_fn_c, front, 1, 0) -MERGEFCT(scsi_front_merge_fn_dc, front, 1, 1) - -/* - * Function: __scsi_merge_requests_fn() - * - * Purpose: Prototype for queue merge function. - * - * Arguments: q - Queue for which we are merging request. - * req - request into which we wish to merge. - * next - 2nd request that we might want to combine with req - * use_clustering - 1 if this host wishes to use clustering - * dma_host - 1 if this host has ISA DMA issues (bus doesn't - * expose all of the address lines, so that DMA cannot - * be done from an arbitrary address). - * - * Returns: 1 if it is OK to merge the two requests. 0 - * if it is not OK. - * - * Lock status: io_request_lock is assumed to be held here. - * - * Notes: Some drivers have limited scatter-gather table sizes, and - * thus they cannot queue an infinitely large command. This - * function is called from ll_rw_blk before it attempts to merge - * a new block into a request to make sure that the request will - * not become too large. - * - * This function is not designed to be directly called. Instead - * it should be referenced from other functions where the - * use_clustering and dma_host parameters should be integer - * constants. The compiler should thus be able to properly - * optimize the code, eliminating stuff that is irrelevant. - * It is more maintainable to do this way with a single function - * than to have 4 separate functions all doing roughly the - * same thing. - */ -__inline static int __scsi_merge_requests_fn(request_queue_t * q, - struct request *req, - struct request *next, - int max_segments, - int use_clustering, - int dma_host) -{ - Scsi_Device *SDpnt; - struct Scsi_Host *SHpnt; - - /* - * First check if the either of the requests are re-queued - * requests. Can't merge them if they are. - */ - if (req->special || next->special) - return 0; - - SDpnt = (Scsi_Device *) q->queuedata; - SHpnt = SDpnt->host; - -#ifdef DMA_CHUNK_SIZE - if (max_segments > 64) - max_segments = 64; - - /* If it would not fit into prepared memory space for sg chain, - * then don't allow the merge. - */ - if (req->nr_segments + next->nr_segments - 1 > max_segments || - req->nr_segments + next->nr_segments - 1 > SHpnt->sg_tablesize) { - return 0; - } - if (req->nr_hw_segments + next->nr_hw_segments - 1 > SHpnt->sg_tablesize) { - return 0; - } -#else - /* - * If the two requests together are too large (even assuming that we - * can merge the boundary requests into one segment, then don't - * allow the merge. - */ - if (req->nr_segments + next->nr_segments - 1 > SHpnt->sg_tablesize) { - return 0; - } -#endif - - if ((req->nr_sectors + next->nr_sectors) > SHpnt->max_sectors) - return 0; - - /* - * The main question is whether the two segments at the boundaries - * would be considered one or two. - */ - if (use_clustering) { - /* - * See if we can do this without creating another - * scatter-gather segment. In the event that this is a - * DMA capable host, make sure that a segment doesn't span - * the DMA threshold boundary. - */ - if (dma_host && - virt_to_phys(req->bhtail->b_data) - 1 == ISA_DMA_THRESHOLD) { - goto dont_combine; - } -#ifdef DMA_SEGMENT_SIZE_LIMITED - /* - * We currently can only allocate scatter-gather bounce - * buffers in chunks of PAGE_SIZE or less. - */ - if (dma_host - && CONTIGUOUS_BUFFERS(req->bhtail, next->bh) - && virt_to_phys(req->bhtail->b_data) - 1 >= ISA_DMA_THRESHOLD ) - { - int segment_size = 0; - int count = 0; - - count = __count_segments(req, use_clustering, dma_host, &segment_size); - count += __count_segments(next, use_clustering, dma_host, &segment_size); - if( count != req->nr_segments + next->nr_segments ) { - goto dont_combine; - } - } -#endif - if (CONTIGUOUS_BUFFERS(req->bhtail, next->bh)) { - /* - * This one is OK. Let it go. - */ - req->nr_segments += next->nr_segments - 1; -#ifdef DMA_CHUNK_SIZE - req->nr_hw_segments += next->nr_hw_segments - 1; -#endif - return 1; - } - } - dont_combine: -#ifdef DMA_CHUNK_SIZE - if (req->nr_segments + next->nr_segments > max_segments || - req->nr_segments + next->nr_segments > SHpnt->sg_tablesize) { - return 0; - } - /* If dynamic DMA mapping can merge last segment in req with - * first segment in next, then the check for hw segments was - * done above already, so we can always merge. - */ - if (MERGEABLE_BUFFERS (req->bhtail, next->bh)) { - req->nr_hw_segments += next->nr_hw_segments - 1; - } else if (req->nr_hw_segments + next->nr_hw_segments > SHpnt->sg_tablesize) { - return 0; - } else { - req->nr_hw_segments += next->nr_hw_segments; - } - req->nr_segments += next->nr_segments; - return 1; -#else - /* - * We know that the two requests at the boundary should not be combined. - * Make sure we can fix something that is the sum of the two. - * A slightly stricter test than we had above. - */ - if (req->nr_segments + next->nr_segments > max_segments || - req->nr_segments + next->nr_segments > SHpnt->sg_tablesize) { - return 0; - } else { - /* - * This will form the start of a new segment. Bump the - * counter. - */ - req->nr_segments += next->nr_segments; - return 1; - } -#endif -} - -/* - * Function: scsi_merge_requests_fn_() + * Function: scsi_init_io() * - * Purpose: queue merge function. - * - * Arguments: q - Queue for which we are merging request. - * req - request into which we wish to merge. - * bh - Block which we may wish to merge into request - * - * Returns: 1 if it is OK to merge the block into the request. 0 - * if it is not OK. - * - * Lock status: io_request_lock is assumed to be held here. - * - * Notes: Optimized for different cases depending upon whether - * ISA DMA is in use and whether clustering should be used. - */ -#define MERGEREQFCT(_FUNCTION, _CLUSTER, _DMA) \ -static int _FUNCTION(request_queue_t * q, \ - struct request * req, \ - struct request * next, \ - int max_segments) \ -{ \ - int ret; \ - SANITY_CHECK(req, _CLUSTER, _DMA); \ - ret = __scsi_merge_requests_fn(q, req, next, max_segments, _CLUSTER, _DMA); \ - return ret; \ -} - -/* Version with use_clustering 0 and dma_host 1 is not necessary, - * since the only use of dma_host above is protected by use_clustering. - */ -MERGEREQFCT(scsi_merge_requests_fn_, 0, 0) -MERGEREQFCT(scsi_merge_requests_fn_c, 1, 0) -MERGEREQFCT(scsi_merge_requests_fn_dc, 1, 1) -/* - * Function: __init_io() - * - * Purpose: Prototype for io initialize function. + * Purpose: SCSI I/O initialize function. * * Arguments: SCpnt - Command descriptor we wish to initialize - * sg_count_valid - 1 if the sg count in the req is valid. - * use_clustering - 1 if this host wishes to use clustering - * dma_host - 1 if this host has ISA DMA issues (bus doesn't - * expose all of the address lines, so that DMA cannot - * be done from an arbitrary address). * * Returns: 1 on success. * * Lock status: - * - * Notes: Only the SCpnt argument should be a non-constant variable. - * This function is designed in such a way that it will be - * invoked from a series of small stubs, each of which would - * be optimized for specific circumstances. - * - * The advantage of this is that hosts that don't do DMA - * get versions of the function that essentially don't have - * any of the DMA code. Same goes for clustering - in the - * case of hosts with no need for clustering, there is no point - * in a whole bunch of overhead. - * - * Finally, in the event that a host has set can_queue to SG_ALL - * implying that there is no limit to the length of a scatter - * gather list, the sg count in the request won't be valid - * (mainly because we don't need queue management functions - * which keep the tally uptodate. */ -__inline static int __init_io(Scsi_Cmnd * SCpnt, - int sg_count_valid, - int use_clustering, - int dma_host) +int scsi_init_io(Scsi_Cmnd *SCpnt) { - struct buffer_head * bh; - struct buffer_head * bhprev; - char * buff; - int count; - int i; - struct request * req; - int sectors; - struct scatterlist * sgpnt; - int this_count; - void ** bbpnt; + struct request *req; + struct scatterlist *sgpnt; + int count, gfp_mask; - /* - * FIXME(eric) - don't inline this - it doesn't depend on the - * integer flags. Come to think of it, I don't think this is even - * needed any more. Need to play with it and see if we hit the - * panic. If not, then don't bother. - */ - if (!SCpnt->request.bh) { - /* - * Case of page request (i.e. raw device), or unlinked buffer - * Typically used for swapping, but this isn't how we do - * swapping any more. - */ - panic("I believe this is dead code. If we hit this, I was wrong"); -#if 0 - SCpnt->request_bufflen = SCpnt->request.nr_sectors << 9; - SCpnt->request_buffer = SCpnt->request.buffer; - SCpnt->use_sg = 0; - /* - * FIXME(eric) - need to handle DMA here. - */ -#endif - return 1; - } req = &SCpnt->request; + /* * First we need to know how many scatter gather segments are needed. */ - if (!sg_count_valid) { - count = __count_segments(req, use_clustering, dma_host, NULL); - } else { - count = req->nr_segments; - } + count = req->nr_phys_segments; /* - * If the dma pool is nearly empty, then queue a minimal request - * with a single segment. Typically this will satisfy a single - * buffer. + * we used to not use scatter-gather for single segment request, + * but now we do (it makes highmem I/O easier to support without + * kmapping pages) */ - if (dma_host && scsi_dma_free_sectors <= 10) { - this_count = SCpnt->request.current_nr_sectors; - goto single_segment; - } - /* - * Don't bother with scatter-gather if there is only one segment. - */ - if (count == 1) { - this_count = SCpnt->request.nr_sectors; - goto single_segment; - } SCpnt->use_sg = count; - /* - * Allocate the actual scatter-gather table itself. - */ - SCpnt->sglist_len = (SCpnt->use_sg * sizeof(struct scatterlist)); - - /* If we could potentially require ISA bounce buffers, allocate - * space for this array here. - */ - if (dma_host) - SCpnt->sglist_len += (SCpnt->use_sg * sizeof(void *)); + gfp_mask = GFP_NOIO; + if (in_interrupt()) + gfp_mask &= ~__GFP_WAIT; - /* scsi_malloc can only allocate in chunks of 512 bytes so - * round it up. - */ - SCpnt->sglist_len = (SCpnt->sglist_len + 511) & ~511; + sgpnt = scsi_alloc_sgtable(SCpnt, gfp_mask); + BUG_ON(!sgpnt); - sgpnt = (struct scatterlist *) scsi_malloc(SCpnt->sglist_len); + SCpnt->request_buffer = (char *) sgpnt; + SCpnt->request_bufflen = 0; + req->buffer = NULL; - /* - * Now fill the scatter-gather table. - */ - if (!sgpnt) { - /* - * If we cannot allocate the scatter-gather table, then - * simply write the first buffer all by itself. - */ - printk("Warning - running *really* short on DMA buffers\n"); - this_count = SCpnt->request.current_nr_sectors; - goto single_segment; - } /* * Next, walk the list, and fill in the addresses and sizes of * each segment. */ - memset(sgpnt, 0, SCpnt->sglist_len); - SCpnt->request_buffer = (char *) sgpnt; - SCpnt->request_bufflen = 0; - bhprev = NULL; - - if (dma_host) - bbpnt = (void **) ((char *)sgpnt + - (SCpnt->use_sg * sizeof(struct scatterlist))); - else - bbpnt = NULL; - - SCpnt->bounce_buffers = bbpnt; - - for (count = 0, bh = SCpnt->request.bh; - bh; bh = bh->b_reqnext) { - if (use_clustering && bhprev != NULL) { - if (dma_host && - virt_to_phys(bhprev->b_data) - 1 == ISA_DMA_THRESHOLD) { - /* Nothing - fall through */ - } else if (CONTIGUOUS_BUFFERS(bhprev, bh)) { - /* - * This one is OK. Let it go. Note that we - * do not have the ability to allocate - * bounce buffer segments > PAGE_SIZE, so - * for now we limit the thing. - */ - if( dma_host ) { -#ifdef DMA_SEGMENT_SIZE_LIMITED - if( virt_to_phys(bh->b_data) - 1 < ISA_DMA_THRESHOLD - || sgpnt[count - 1].length + bh->b_size <= PAGE_SIZE ) { - sgpnt[count - 1].length += bh->b_size; - bhprev = bh; - continue; - } -#else - sgpnt[count - 1].length += bh->b_size; - bhprev = bh; - continue; -#endif - } else { - sgpnt[count - 1].length += bh->b_size; - SCpnt->request_bufflen += bh->b_size; - bhprev = bh; - continue; - } - } - } - count++; - sgpnt[count - 1].address = bh->b_data; - sgpnt[count - 1].page = NULL; - sgpnt[count - 1].length += bh->b_size; - if (!dma_host) { - SCpnt->request_bufflen += bh->b_size; - } - bhprev = bh; - } + SCpnt->request_bufflen = req->nr_sectors << 9; + count = blk_rq_map_sg(req->q, req, SCpnt->request_buffer); /* - * Verify that the count is correct. + * mapped well, send it off */ - if (count != SCpnt->use_sg) { - printk("Incorrect number of segments after building list\n"); -#ifdef CONFIG_SCSI_DEBUG_QUEUES - dump_stats(req, use_clustering, dma_host, count); -#endif - } - if (!dma_host) { + if (count <= SCpnt->use_sg) { + SCpnt->use_sg = count; return 1; } - /* - * Now allocate bounce buffers, if needed. - */ - SCpnt->request_bufflen = 0; - for (i = 0; i < count; i++) { - sectors = (sgpnt[i].length >> 9); - SCpnt->request_bufflen += sgpnt[i].length; - if (virt_to_phys(sgpnt[i].address) + sgpnt[i].length - 1 > - ISA_DMA_THRESHOLD) { - if( scsi_dma_free_sectors - sectors <= 10 ) { - /* - * If this would nearly drain the DMA - * pool empty, then let's stop here. - * Don't make this request any larger. - * This is kind of a safety valve that - * we use - we could get screwed later - * on if we run out completely. - */ - SCpnt->request_bufflen -= sgpnt[i].length; - SCpnt->use_sg = i; - if (i == 0) { - goto big_trouble; - } - break; - } - - bbpnt[i] = sgpnt[i].address; - sgpnt[i].address = - (char *) scsi_malloc(sgpnt[i].length); - /* - * If we cannot allocate memory for this DMA bounce - * buffer, then queue just what we have done so far. - */ - if (sgpnt[i].address == NULL) { - printk("Warning - running low on DMA memory\n"); - SCpnt->request_bufflen -= sgpnt[i].length; - SCpnt->use_sg = i; - if (i == 0) { - goto big_trouble; - } - break; - } - if (SCpnt->request.cmd == WRITE) { - memcpy(sgpnt[i].address, bbpnt[i], - sgpnt[i].length); - } - } - } - return 1; - - big_trouble: - /* - * We come here in the event that we get one humongous - * request, where we need a bounce buffer, and the buffer is - * more than we can allocate in a single call to - * scsi_malloc(). In addition, we only come here when it is - * the 0th element of the scatter-gather table that gets us - * into this trouble. As a fallback, we fall back to - * non-scatter-gather, and ask for a single segment. We make - * a half-hearted attempt to pick a reasonably large request - * size mainly so that we don't thrash the thing with - * iddy-biddy requests. - */ - - /* - * The original number of sectors in the 0th element of the - * scatter-gather table. - */ - sectors = sgpnt[0].length >> 9; - - /* - * Free up the original scatter-gather table. Note that since - * it was the 0th element that got us here, we don't have to - * go in and free up memory from the other slots. - */ - SCpnt->request_bufflen = 0; - SCpnt->use_sg = 0; - scsi_free(SCpnt->request_buffer, SCpnt->sglist_len); - - /* - * Make an attempt to pick up as much as we reasonably can. - * Just keep adding sectors until the pool starts running kind of - * low. The limit of 30 is somewhat arbitrary - the point is that - * it would kind of suck if we dropped down and limited ourselves to - * single-block requests if we had hundreds of free sectors. - */ - if( scsi_dma_free_sectors > 30 ) { - for (this_count = 0, bh = SCpnt->request.bh; - bh; bh = bh->b_reqnext) { - if( scsi_dma_free_sectors - this_count < 30 - || this_count == sectors ) - { - break; - } - this_count += bh->b_size >> 9; - } - - } else { - /* - * Yow! Take the absolute minimum here. - */ - this_count = SCpnt->request.current_nr_sectors; - } - /* - * Now drop through into the single-segment case. - */ - - single_segment: - /* - * Come here if for any reason we choose to do this as a single - * segment. Possibly the entire request, or possibly a small - * chunk of the entire request. - */ - bh = SCpnt->request.bh; - buff = SCpnt->request.buffer; - - if (dma_host) { - /* - * Allocate a DMA bounce buffer. If the allocation fails, fall - * back and allocate a really small one - enough to satisfy - * the first buffer. - */ - if (virt_to_phys(SCpnt->request.bh->b_data) - + (this_count << 9) - 1 > ISA_DMA_THRESHOLD) { - buff = (char *) scsi_malloc(this_count << 9); - if (!buff) { - printk("Warning - running low on DMA memory\n"); - this_count = SCpnt->request.current_nr_sectors; - buff = (char *) scsi_malloc(this_count << 9); - if (!buff) { - dma_exhausted(SCpnt, 0); - } - } - if (SCpnt->request.cmd == WRITE) - memcpy(buff, (char *) SCpnt->request.buffer, this_count << 9); - } - } - SCpnt->request_bufflen = this_count << 9; - SCpnt->request_buffer = buff; - SCpnt->use_sg = 0; - return 1; -} - -#define INITIO(_FUNCTION, _VALID, _CLUSTER, _DMA) \ -static int _FUNCTION(Scsi_Cmnd * SCpnt) \ -{ \ - return __init_io(SCpnt, _VALID, _CLUSTER, _DMA); \ + printk("Incorrect number of segments after building list\n"); + printk("counted %d, received %d\n", count, SCpnt->use_sg); + printk("req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors, req->current_nr_sectors); + BUG(); + return 0; /* ahem */ } /* - * ll_rw_blk.c now keeps track of the number of segments in - * a request. Thus we don't have to do it any more here. - * We always force "_VALID" to 1. Eventually clean this up - * and get rid of the extra argument. - */ -INITIO(scsi_init_io_v, 1, 0, 0) -INITIO(scsi_init_io_vd, 1, 0, 1) -INITIO(scsi_init_io_vc, 1, 1, 0) -INITIO(scsi_init_io_vdc, 1, 1, 1) - -/* - * Function: initialize_merge_fn() + * Function: scsi_initialize_merge_fn() * * Purpose: Initialize merge function for a host * @@ -1137,52 +123,28 @@ * * Notes: */ -void initialize_merge_fn(Scsi_Device * SDpnt) +void scsi_initialize_merge_fn(Scsi_Device * SDpnt) { - request_queue_t *q; - struct Scsi_Host *SHpnt; - SHpnt = SDpnt->host; - - q = &SDpnt->request_queue; + struct Scsi_Host *SHpnt = SDpnt->host; + request_queue_t *q = &SDpnt->request_queue; + dma64_addr_t bounce_limit; /* - * If the host has already selected a merge manager, then don't - * pick a new one. - */ -#if 0 - if (q->back_merge_fn && q->front_merge_fn) - return; -#endif - /* - * If this host has an unlimited tablesize, then don't bother with a - * merge manager. The whole point of the operation is to make sure - * that requests don't grow too large, and this host isn't picky. - * - * Note that ll_rw_blk.c is effectively maintaining a segment - * count which is only valid if clustering is used, and it obviously - * doesn't handle the DMA case. In the end, it - * is simply easier to do it ourselves with our own functions - * rather than rely upon the default behavior of ll_rw_blk. + * The generic merging functions work just fine for us. + * Enable highmem I/O, if appropriate. */ - if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) { - q->back_merge_fn = scsi_back_merge_fn_; - q->front_merge_fn = scsi_front_merge_fn_; - q->merge_requests_fn = scsi_merge_requests_fn_; - SDpnt->scsi_init_io_fn = scsi_init_io_v; - } else if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) { - q->back_merge_fn = scsi_back_merge_fn_; - q->front_merge_fn = scsi_front_merge_fn_; - q->merge_requests_fn = scsi_merge_requests_fn_; - SDpnt->scsi_init_io_fn = scsi_init_io_vd; - } else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) { - q->back_merge_fn = scsi_back_merge_fn_c; - q->front_merge_fn = scsi_front_merge_fn_c; - q->merge_requests_fn = scsi_merge_requests_fn_c; - SDpnt->scsi_init_io_fn = scsi_init_io_vc; - } else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) { - q->back_merge_fn = scsi_back_merge_fn_dc; - q->front_merge_fn = scsi_front_merge_fn_dc; - q->merge_requests_fn = scsi_merge_requests_fn_dc; - SDpnt->scsi_init_io_fn = scsi_init_io_vdc; + bounce_limit = BLK_BOUNCE_HIGH; + if (SHpnt->highmem_io && (SDpnt->type == TYPE_DISK)) { + if (!PCI_DMA_BUS_IS_PHYS) + /* Platforms with virtual-DMA translation + * hardware have no practical limit. + */ + bounce_limit = BLK_BOUNCE_ANY; + else + bounce_limit = SHpnt->pci_dev->dma_mask; } + if (SHpnt->unchecked_isa_dma) + bounce_limit = BLK_BOUNCE_ISA; + + blk_queue_bounce_limit(q, bounce_limit); } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_obsolete.c linux/drivers/scsi/scsi_obsolete.c --- v2.5.0/linux/drivers/scsi/scsi_obsolete.c Thu Jul 5 11:28:17 2001 +++ linux/drivers/scsi/scsi_obsolete.c Wed Dec 31 16:00:00 1969 @@ -1,1119 +0,0 @@ -/* - * scsi_obsolete.c Copyright (C) 1992 Drew Eckhardt - * Copyright (C) 1993, 1994, 1995 Eric Youngdale - * - * generic mid-level SCSI driver - * Initial versions: Drew Eckhardt - * Subsequent revisions: Eric Youngdale - * - * - * - * Bug correction thanks go to : - * Rik Faith - * Tommy Thorn - * Thomas Wuensche - * - * Modified by Eric Youngdale eric@andante.org to - * add scatter-gather, multiple outstanding request, and other - * enhancements. - * - * Native multichannel, wide scsi, /proc/scsi and hot plugging - * support added by Michael Neuffer - * - * Major improvements to the timeout, abort, and reset processing, - * as well as performance modifications for large queue depths by - * Leonard N. Zubkoff - * - * Improved compatibility with 2.0 behaviour by Manfred Spraul - * - */ - -/* - *######################################################################### - *######################################################################### - *######################################################################### - *######################################################################### - * NOTE - NOTE - NOTE - NOTE - NOTE - NOTE - NOTE - * - *######################################################################### - *######################################################################### - *######################################################################### - *######################################################################### - * - * This file contains the 'old' scsi error handling. It is only present - * while the new error handling code is being debugged, and while the low - * level drivers are being converted to use the new code. Once the last - * driver uses the new code this *ENTIRE* file will be nuked. - */ - -#define __NO_VERSION__ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "scsi.h" -#include "hosts.h" -#include "constants.h" - -#undef USE_STATIC_SCSI_MEMORY - -/* - static const char RCSid[] = "$Header: /mnt/ide/home/eric/CVSROOT/linux/drivers/scsi/scsi_obsolete.c,v 1.1 1997/05/18 23:27:21 eric Exp $"; - */ - - -#define INTERNAL_ERROR (panic ("Internal error in file %s, line %d.\n", __FILE__, __LINE__)) - - -static int scsi_abort(Scsi_Cmnd *, int code); -static int scsi_reset(Scsi_Cmnd *, unsigned int); - -extern void scsi_old_done(Scsi_Cmnd * SCpnt); -int update_timeout(Scsi_Cmnd *, int); -extern void scsi_old_times_out(Scsi_Cmnd * SCpnt); - -extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt); - -#define SCSI_BLOCK(HOST) (HOST->can_queue && HOST->host_busy >= HOST->can_queue) - -static unsigned char generic_sense[6] = -{REQUEST_SENSE, 0, 0, 0, 255, 0}; - -/* - * This is the number of clock ticks we should wait before we time out - * and abort the command. This is for where the scsi.c module generates - * the command, not where it originates from a higher level, in which - * case the timeout is specified there. - * - * ABORT_TIMEOUT and RESET_TIMEOUT are the timeouts for RESET and ABORT - * respectively. - */ - -#ifdef DEBUG_TIMEOUT -static void scsi_dump_status(void); -#endif - - -#ifdef DEBUG -#define SCSI_TIMEOUT (5*HZ) -#else -#define SCSI_TIMEOUT (2*HZ) -#endif - -#ifdef DEBUG -#define SENSE_TIMEOUT SCSI_TIMEOUT -#define ABORT_TIMEOUT SCSI_TIMEOUT -#define RESET_TIMEOUT SCSI_TIMEOUT -#else -#define SENSE_TIMEOUT (5*HZ/10) -#define RESET_TIMEOUT (5*HZ/10) -#define ABORT_TIMEOUT (5*HZ/10) -#endif - - -/* Do not call reset on error if we just did a reset within 15 sec. */ -#define MIN_RESET_PERIOD (15*HZ) - - - -/* - * Flag bits for the internal_timeout array - */ -#define IN_ABORT 1 -#define IN_RESET 2 -#define IN_RESET2 4 -#define IN_RESET3 8 - -/* - * This is our time out function, called when the timer expires for a - * given host adapter. It will attempt to abort the currently executing - * command, that failing perform a kernel panic. - */ - -void scsi_old_times_out(Scsi_Cmnd * SCpnt) -{ - unsigned long flags; - - spin_lock_irqsave(&io_request_lock, flags); - - /* Set the serial_number_at_timeout to the current serial_number */ - SCpnt->serial_number_at_timeout = SCpnt->serial_number; - - switch (SCpnt->internal_timeout & (IN_ABORT | IN_RESET | IN_RESET2 | IN_RESET3)) { - case NORMAL_TIMEOUT: - { -#ifdef DEBUG_TIMEOUT - scsi_dump_status(); -#endif - } - - if (!scsi_abort(SCpnt, DID_TIME_OUT)) - break; - case IN_ABORT: - printk("SCSI host %d abort (pid %ld) timed out - resetting\n", - SCpnt->host->host_no, SCpnt->pid); - if (!scsi_reset(SCpnt, SCSI_RESET_ASYNCHRONOUS)) - break; - case IN_RESET: - case (IN_ABORT | IN_RESET): - /* This might be controversial, but if there is a bus hang, - * you might conceivably want the machine up and running - * esp if you have an ide disk. - */ - printk("SCSI host %d channel %d reset (pid %ld) timed out - " - "trying harder\n", - SCpnt->host->host_no, SCpnt->channel, SCpnt->pid); - SCpnt->internal_timeout &= ~IN_RESET; - SCpnt->internal_timeout |= IN_RESET2; - scsi_reset(SCpnt, - SCSI_RESET_ASYNCHRONOUS | SCSI_RESET_SUGGEST_BUS_RESET); - break; - case IN_RESET2: - case (IN_ABORT | IN_RESET2): - /* Obviously the bus reset didn't work. - * Let's try even harder and call for an HBA reset. - * Maybe the HBA itself crashed and this will shake it loose. - */ - printk("SCSI host %d reset (pid %ld) timed out - trying to shake it loose\n", - SCpnt->host->host_no, SCpnt->pid); - SCpnt->internal_timeout &= ~(IN_RESET | IN_RESET2); - SCpnt->internal_timeout |= IN_RESET3; - scsi_reset(SCpnt, - SCSI_RESET_ASYNCHRONOUS | SCSI_RESET_SUGGEST_HOST_RESET); - break; - - default: - printk("SCSI host %d reset (pid %ld) timed out again -\n", - SCpnt->host->host_no, SCpnt->pid); - printk("probably an unrecoverable SCSI bus or device hang.\n"); - break; - - } - spin_unlock_irqrestore(&io_request_lock, flags); - -} - -/* - * From what I can find in scsi_obsolete.c, this function is only called - * by scsi_old_done and scsi_reset. Both of these functions run with the - * io_request_lock already held, so we need do nothing here about grabbing - * any locks. - */ -static void scsi_request_sense(Scsi_Cmnd * SCpnt) -{ - SCpnt->flags |= WAS_SENSE | ASKED_FOR_SENSE; - update_timeout(SCpnt, SENSE_TIMEOUT); - - - memcpy((void *) SCpnt->cmnd, (void *) generic_sense, - sizeof(generic_sense)); - memset((void *) SCpnt->sense_buffer, 0, - sizeof(SCpnt->sense_buffer)); - - if (SCpnt->device->scsi_level <= SCSI_2) - SCpnt->cmnd[1] = SCpnt->lun << 5; - SCpnt->cmnd[4] = sizeof(SCpnt->sense_buffer); - - SCpnt->request_buffer = &SCpnt->sense_buffer; - SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer); - SCpnt->use_sg = 0; - SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]); - SCpnt->result = 0; - SCpnt->sc_data_direction = SCSI_DATA_READ; - - /* - * Ugly, ugly. The newer interfaces all assume that the lock - * isn't held. Mustn't disappoint, or we deadlock the system. - */ - spin_unlock_irq(&io_request_lock); - scsi_dispatch_cmd(SCpnt); - spin_lock_irq(&io_request_lock); -} - - - - -static int check_sense(Scsi_Cmnd * SCpnt) -{ - /* If there is no sense information, request it. If we have already - * requested it, there is no point in asking again - the firmware must - * be confused. - */ - if (((SCpnt->sense_buffer[0] & 0x70) >> 4) != 7) { - if (!(SCpnt->flags & ASKED_FOR_SENSE)) - return SUGGEST_SENSE; - else - return SUGGEST_RETRY; - } - SCpnt->flags &= ~ASKED_FOR_SENSE; - -#ifdef DEBUG_INIT - printk("scsi%d, channel%d : ", SCpnt->host->host_no, SCpnt->channel); - print_sense("", SCpnt); - printk("\n"); -#endif - if (SCpnt->sense_buffer[2] & 0xe0) - return SUGGEST_ABORT; - - switch (SCpnt->sense_buffer[2] & 0xf) { - case NO_SENSE: - return 0; - case RECOVERED_ERROR: - return SUGGEST_IS_OK; - - case ABORTED_COMMAND: - return SUGGEST_RETRY; - case NOT_READY: - case UNIT_ATTENTION: - /* - * If we are expecting a CC/UA because of a bus reset that we - * performed, treat this just as a retry. Otherwise this is - * information that we should pass up to the upper-level driver - * so that we can deal with it there. - */ - if (SCpnt->device->expecting_cc_ua) { - SCpnt->device->expecting_cc_ua = 0; - return SUGGEST_RETRY; - } - return SUGGEST_ABORT; - - /* these three are not supported */ - case COPY_ABORTED: - case VOLUME_OVERFLOW: - case MISCOMPARE: - - case MEDIUM_ERROR: - return SUGGEST_REMAP; - case BLANK_CHECK: - case DATA_PROTECT: - case HARDWARE_ERROR: - case ILLEGAL_REQUEST: - default: - return SUGGEST_ABORT; - } -} - -/* This function is the mid-level interrupt routine, which decides how - * to handle error conditions. Each invocation of this function must - * do one and *only* one of the following: - * - * (1) Call last_cmnd[host].done. This is done for fatal errors and - * normal completion, and indicates that the handling for this - * request is complete. - * (2) Call internal_cmnd to requeue the command. This will result in - * scsi_done being called again when the retry is complete. - * (3) Call scsi_request_sense. This asks the host adapter/drive for - * more information about the error condition. When the information - * is available, scsi_done will be called again. - * (4) Call reset(). This is sort of a last resort, and the idea is that - * this may kick things loose and get the drive working again. reset() - * automatically calls scsi_request_sense, and thus scsi_done will be - * called again once the reset is complete. - * - * If none of the above actions are taken, the drive in question - * will hang. If more than one of the above actions are taken by - * scsi_done, then unpredictable behavior will result. - */ -void scsi_old_done(Scsi_Cmnd * SCpnt) -{ - int status = 0; - int exit = 0; - int checked; - int oldto; - struct Scsi_Host *host = SCpnt->host; - Scsi_Device * device = SCpnt->device; - int result = SCpnt->result; - SCpnt->serial_number = 0; - SCpnt->serial_number_at_timeout = 0; - oldto = update_timeout(SCpnt, 0); - -#ifdef DEBUG_TIMEOUT - if (result) - printk("Non-zero result in scsi_done %x %d:%d\n", - result, SCpnt->target, SCpnt->lun); -#endif - - /* If we requested an abort, (and we got it) then fix up the return - * status to say why - */ - if (host_byte(result) == DID_ABORT && SCpnt->abort_reason) - SCpnt->result = result = (result & 0xff00ffff) | - (SCpnt->abort_reason << 16); - - -#define CMD_FINISHED 0 -#define MAYREDO 1 -#define REDO 3 -#define PENDING 4 - -#ifdef DEBUG - printk("In scsi_done(host = %d, result = %06x)\n", host->host_no, result); -#endif - - if (SCpnt->flags & SYNC_RESET) { - /* - * The behaviou of scsi_reset(SYNC) was changed in 2.1.? . - * The scsi mid-layer does a REDO after every sync reset, the driver - * must not do that any more. In order to prevent old drivers from - * crashing, all scsi_done() calls during sync resets are ignored. - */ - printk("scsi%d: device driver called scsi_done() " - "for a synchronous reset.\n", SCpnt->host->host_no); - return; - } - if (SCpnt->flags & WAS_SENSE) { - SCpnt->use_sg = SCpnt->old_use_sg; - SCpnt->cmd_len = SCpnt->old_cmd_len; - SCpnt->sc_data_direction = SCpnt->sc_old_data_direction; - SCpnt->underflow = SCpnt->old_underflow; - } - switch (host_byte(result)) { - case DID_OK: - if (status_byte(result) && (SCpnt->flags & WAS_SENSE)) - /* Failed to obtain sense information */ - { - SCpnt->flags &= ~WAS_SENSE; -#if 0 /* This cannot possibly be correct. */ - SCpnt->internal_timeout &= ~SENSE_TIMEOUT; -#endif - - if (!(SCpnt->flags & WAS_RESET)) { - printk("scsi%d : channel %d target %d lun %d request sense" - " failed, performing reset.\n", - SCpnt->host->host_no, SCpnt->channel, SCpnt->target, - SCpnt->lun); - scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS); - status = REDO; - break; - } else { - exit = (DRIVER_HARD | SUGGEST_ABORT); - status = CMD_FINISHED; - } - } else - switch (msg_byte(result)) { - case COMMAND_COMPLETE: - switch (status_byte(result)) { - case GOOD: - if (SCpnt->flags & WAS_SENSE) { -#ifdef DEBUG - printk("In scsi_done, GOOD status, COMMAND COMPLETE, " - "parsing sense information.\n"); -#endif - SCpnt->flags &= ~WAS_SENSE; -#if 0 /* This cannot possibly be correct. */ - SCpnt->internal_timeout &= ~SENSE_TIMEOUT; -#endif - - switch (checked = check_sense(SCpnt)) { - case SUGGEST_SENSE: - case 0: -#ifdef DEBUG - printk("NO SENSE. status = REDO\n"); -#endif - update_timeout(SCpnt, oldto); - status = REDO; - break; - case SUGGEST_IS_OK: - break; - case SUGGEST_REMAP: -#ifdef DEBUG - printk("SENSE SUGGEST REMAP - status = CMD_FINISHED\n"); -#endif - status = CMD_FINISHED; - exit = DRIVER_SENSE | SUGGEST_ABORT; - break; - case SUGGEST_RETRY: -#ifdef DEBUG - printk("SENSE SUGGEST RETRY - status = MAYREDO\n"); -#endif - status = MAYREDO; - exit = DRIVER_SENSE | SUGGEST_RETRY; - break; - case SUGGEST_ABORT: -#ifdef DEBUG - printk("SENSE SUGGEST ABORT - status = CMD_FINISHED"); -#endif - status = CMD_FINISHED; - exit = DRIVER_SENSE | SUGGEST_ABORT; - break; - default: - printk("Internal error %s %d \n", __FILE__, - __LINE__); - } - } - /* end WAS_SENSE */ - else { -#ifdef DEBUG - printk("COMMAND COMPLETE message returned, " - "status = CMD_FINISHED. \n"); -#endif - exit = DRIVER_OK; - status = CMD_FINISHED; - } - break; - - case CHECK_CONDITION: - case COMMAND_TERMINATED: - switch (check_sense(SCpnt)) { - case 0: - update_timeout(SCpnt, oldto); - status = REDO; - break; - case SUGGEST_REMAP: - status = CMD_FINISHED; - exit = DRIVER_SENSE | SUGGEST_ABORT; - break; - case SUGGEST_RETRY: - status = MAYREDO; - exit = DRIVER_SENSE | SUGGEST_RETRY; - break; - case SUGGEST_ABORT: - status = CMD_FINISHED; - exit = DRIVER_SENSE | SUGGEST_ABORT; - break; - case SUGGEST_SENSE: - scsi_request_sense(SCpnt); - status = PENDING; - break; - } - break; - - case CONDITION_GOOD: - case INTERMEDIATE_GOOD: - case INTERMEDIATE_C_GOOD: - break; - - case BUSY: - case QUEUE_FULL: - update_timeout(SCpnt, oldto); - status = REDO; - break; - - case RESERVATION_CONFLICT: - printk("scsi%d, channel %d : RESERVATION CONFLICT performing" - " reset.\n", SCpnt->host->host_no, SCpnt->channel); - scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS); - status = REDO; - break; - default: - printk("Internal error %s %d \n" - "status byte = %d \n", __FILE__, - __LINE__, status_byte(result)); - - } - break; - default: - panic("scsi: unsupported message byte %d received\n", - msg_byte(result)); - } - break; - case DID_TIME_OUT: -#ifdef DEBUG - printk("Host returned DID_TIME_OUT - "); -#endif - - if (SCpnt->flags & WAS_TIMEDOUT) { -#ifdef DEBUG - printk("Aborting\n"); -#endif - /* - Allow TEST_UNIT_READY and INQUIRY commands to timeout early - without causing resets. All other commands should be retried. - */ - if (SCpnt->cmnd[0] != TEST_UNIT_READY && - SCpnt->cmnd[0] != INQUIRY) - status = MAYREDO; - exit = (DRIVER_TIMEOUT | SUGGEST_ABORT); - } else { -#ifdef DEBUG - printk("Retrying.\n"); -#endif - SCpnt->flags |= WAS_TIMEDOUT; - SCpnt->internal_timeout &= ~IN_ABORT; - status = REDO; - } - break; - case DID_BUS_BUSY: - case DID_PARITY: - status = REDO; - break; - case DID_NO_CONNECT: -#ifdef DEBUG - printk("Couldn't connect.\n"); -#endif - exit = (DRIVER_HARD | SUGGEST_ABORT); - break; - case DID_ERROR: - status = MAYREDO; - exit = (DRIVER_HARD | SUGGEST_ABORT); - break; - case DID_BAD_TARGET: - case DID_ABORT: - exit = (DRIVER_INVALID | SUGGEST_ABORT); - break; - case DID_RESET: - if (SCpnt->flags & IS_RESETTING) { - SCpnt->flags &= ~IS_RESETTING; - status = REDO; - break; - } - if (msg_byte(result) == GOOD && - status_byte(result) == CHECK_CONDITION) { - switch (check_sense(SCpnt)) { - case 0: - update_timeout(SCpnt, oldto); - status = REDO; - break; - case SUGGEST_REMAP: - case SUGGEST_RETRY: - status = MAYREDO; - exit = DRIVER_SENSE | SUGGEST_RETRY; - break; - case SUGGEST_ABORT: - status = CMD_FINISHED; - exit = DRIVER_SENSE | SUGGEST_ABORT; - break; - case SUGGEST_SENSE: - scsi_request_sense(SCpnt); - status = PENDING; - break; - } - } else { - status = REDO; - exit = SUGGEST_RETRY; - } - break; - default: - exit = (DRIVER_ERROR | SUGGEST_DIE); - } - - switch (status) { - case CMD_FINISHED: - case PENDING: - break; - case MAYREDO: -#ifdef DEBUG - printk("In MAYREDO, allowing %d retries, have %d\n", - SCpnt->allowed, SCpnt->retries); -#endif - if ((++SCpnt->retries) < SCpnt->allowed) { - if ((SCpnt->retries >= (SCpnt->allowed >> 1)) - && !(SCpnt->host->resetting && time_before(jiffies, SCpnt->host->last_reset + MIN_RESET_PERIOD)) - && !(SCpnt->flags & WAS_RESET)) { - printk("scsi%d channel %d : resetting for second half of retries.\n", - SCpnt->host->host_no, SCpnt->channel); - scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS); - /* fall through to REDO */ - } - } else { - status = CMD_FINISHED; - break; - } - /* fall through to REDO */ - - case REDO: - - if (SCpnt->flags & WAS_SENSE) - scsi_request_sense(SCpnt); - else { - memcpy((void *) SCpnt->cmnd, - (void *) SCpnt->data_cmnd, - sizeof(SCpnt->data_cmnd)); - memset((void *) SCpnt->sense_buffer, 0, - sizeof(SCpnt->sense_buffer)); - SCpnt->request_buffer = SCpnt->buffer; - SCpnt->request_bufflen = SCpnt->bufflen; - SCpnt->use_sg = SCpnt->old_use_sg; - SCpnt->cmd_len = SCpnt->old_cmd_len; - SCpnt->sc_data_direction = SCpnt->sc_old_data_direction; - SCpnt->underflow = SCpnt->old_underflow; - SCpnt->result = 0; - /* - * Ugly, ugly. The newer interfaces all - * assume that the lock isn't held. Mustn't - * disappoint, or we deadlock the system. - */ - spin_unlock_irq(&io_request_lock); - scsi_dispatch_cmd(SCpnt); - spin_lock_irq(&io_request_lock); - } - break; - default: - INTERNAL_ERROR; - } - - if (status == CMD_FINISHED) { - Scsi_Request *SRpnt; -#ifdef DEBUG - printk("Calling done function - at address %p\n", SCpnt->done); -#endif - host->host_busy--; /* Indicate that we are free */ - device->device_busy--; /* Decrement device usage counter. */ - - SCpnt->result = result | ((exit & 0xff) << 24); - SCpnt->use_sg = SCpnt->old_use_sg; - SCpnt->cmd_len = SCpnt->old_cmd_len; - SCpnt->sc_data_direction = SCpnt->sc_old_data_direction; - SCpnt->underflow = SCpnt->old_underflow; - /* - * The upper layers assume the lock isn't held. We mustn't - * disappoint them. When the new error handling code is in - * use, the upper code is run from a bottom half handler, so - * it isn't an issue. - */ - spin_unlock_irq(&io_request_lock); - SRpnt = SCpnt->sc_request; - if( SRpnt != NULL ) { - SRpnt->sr_result = SRpnt->sr_command->result; - if( SRpnt->sr_result != 0 ) { - memcpy(SRpnt->sr_sense_buffer, - SRpnt->sr_command->sense_buffer, - sizeof(SRpnt->sr_sense_buffer)); - } - } - - SCpnt->done(SCpnt); - spin_lock_irq(&io_request_lock); - } -#undef CMD_FINISHED -#undef REDO -#undef MAYREDO -#undef PENDING -} - -/* - * The scsi_abort function interfaces with the abort() function of the host - * we are aborting, and causes the current command to not complete. The - * caller should deal with any error messages or status returned on the - * next call. - * - * This will not be called reentrantly for a given host. - */ - -/* - * Since we're nice guys and specified that abort() and reset() - * can be non-reentrant. The internal_timeout flags are used for - * this. - */ - - -static int scsi_abort(Scsi_Cmnd * SCpnt, int why) -{ - int oldto; - struct Scsi_Host *host = SCpnt->host; - - while (1) { - - /* - * Protect against races here. If the command is done, or we are - * on a different command forget it. - */ - if (SCpnt->serial_number != SCpnt->serial_number_at_timeout) { - return 0; - } - if (SCpnt->internal_timeout & IN_ABORT) { - spin_unlock_irq(&io_request_lock); - while (SCpnt->internal_timeout & IN_ABORT) - barrier(); - spin_lock_irq(&io_request_lock); - } else { - SCpnt->internal_timeout |= IN_ABORT; - oldto = update_timeout(SCpnt, ABORT_TIMEOUT); - - if ((SCpnt->flags & IS_RESETTING) && SCpnt->device->soft_reset) { - /* OK, this command must have died when we did the - * reset. The device itself must have lied. - */ - printk("Stale command on %d %d:%d appears to have died when" - " the bus was reset\n", - SCpnt->channel, SCpnt->target, SCpnt->lun); - } - if (!host->host_busy) { - SCpnt->internal_timeout &= ~IN_ABORT; - update_timeout(SCpnt, oldto); - return 0; - } - printk("scsi : aborting command due to timeout : pid %lu, scsi%d," - " channel %d, id %d, lun %d ", - SCpnt->pid, SCpnt->host->host_no, (int) SCpnt->channel, - (int) SCpnt->target, (int) SCpnt->lun); - print_command(SCpnt->cmnd); - if (SCpnt->serial_number != SCpnt->serial_number_at_timeout) - return 0; - SCpnt->abort_reason = why; - switch (host->hostt->abort(SCpnt)) { - /* We do not know how to abort. Try waiting another - * time increment and see if this helps. Set the - * WAS_TIMEDOUT flag set so we do not try this twice - */ - case SCSI_ABORT_BUSY: /* Tough call - returning 1 from - * this is too severe - */ - case SCSI_ABORT_SNOOZE: - if (why == DID_TIME_OUT) { - SCpnt->internal_timeout &= ~IN_ABORT; - if (SCpnt->flags & WAS_TIMEDOUT) { - return 1; /* Indicate we cannot handle this. - * We drop down into the reset handler - * and try again - */ - } else { - SCpnt->flags |= WAS_TIMEDOUT; - oldto = SCpnt->timeout_per_command; - update_timeout(SCpnt, oldto); - } - } - return 0; - case SCSI_ABORT_PENDING: - if (why != DID_TIME_OUT) { - update_timeout(SCpnt, oldto); - } - return 0; - case SCSI_ABORT_SUCCESS: - /* We should have already aborted this one. No - * need to adjust timeout - */ - SCpnt->internal_timeout &= ~IN_ABORT; - return 0; - case SCSI_ABORT_NOT_RUNNING: - SCpnt->internal_timeout &= ~IN_ABORT; - update_timeout(SCpnt, 0); - return 0; - case SCSI_ABORT_ERROR: - default: - SCpnt->internal_timeout &= ~IN_ABORT; - return 1; - } - } - } -} - - -/* Mark a single SCSI Device as having been reset. */ - -static inline void scsi_mark_device_reset(Scsi_Device * Device) -{ - Device->was_reset = 1; - Device->expecting_cc_ua = 1; -} - - -/* Mark all SCSI Devices on a specific Host as having been reset. */ - -void scsi_mark_host_reset(struct Scsi_Host *Host) -{ - Scsi_Cmnd *SCpnt; - Scsi_Device *SDpnt; - - for (SDpnt = Host->host_queue; SDpnt; SDpnt = SDpnt->next) { - for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) - scsi_mark_device_reset(SCpnt->device); - } -} - - -/* Mark all SCSI Devices on a specific Host Bus as having been reset. */ - -static void scsi_mark_bus_reset(struct Scsi_Host *Host, int channel) -{ - Scsi_Cmnd *SCpnt; - Scsi_Device *SDpnt; - - for (SDpnt = Host->host_queue; SDpnt; SDpnt = SDpnt->next) { - for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) - if (SCpnt->channel == channel) - scsi_mark_device_reset(SCpnt->device); - } -} - - -static int scsi_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags) -{ - int temp; - Scsi_Cmnd *SCpnt1; - Scsi_Device *SDpnt; - struct Scsi_Host *host = SCpnt->host; - - printk("SCSI bus is being reset for host %d channel %d.\n", - host->host_no, SCpnt->channel); - -#if 0 - /* - * First of all, we need to make a recommendation to the low-level - * driver as to whether a BUS_DEVICE_RESET should be performed, - * or whether we should do a full BUS_RESET. There is no simple - * algorithm here - we basically use a series of heuristics - * to determine what we should do. - */ - SCpnt->host->suggest_bus_reset = FALSE; - - /* - * First see if all of the active devices on the bus have - * been jammed up so that we are attempting resets. If so, - * then suggest a bus reset. Forcing a bus reset could - * result in some race conditions, but no more than - * you would usually get with timeouts. We will cross - * that bridge when we come to it. - * - * This is actually a pretty bad idea, since a sequence of - * commands will often timeout together and this will cause a - * Bus Device Reset followed immediately by a SCSI Bus Reset. - * If all of the active devices really are jammed up, the - * Bus Device Reset will quickly timeout and scsi_times_out - * will follow up with a SCSI Bus Reset anyway. - */ - SCpnt1 = host->host_queue; - while (SCpnt1) { - if (SCpnt1->request.rq_status != RQ_INACTIVE - && (SCpnt1->flags & (WAS_RESET | IS_RESETTING)) == 0) - break; - SCpnt1 = SCpnt1->next; - } - if (SCpnt1 == NULL) { - reset_flags |= SCSI_RESET_SUGGEST_BUS_RESET; - } - /* - * If the code that called us is suggesting a hard reset, then - * definitely request it. This usually occurs because a - * BUS_DEVICE_RESET times out. - * - * Passing reset_flags along takes care of this automatically. - */ - if (reset_flags & SCSI_RESET_SUGGEST_BUS_RESET) { - SCpnt->host->suggest_bus_reset = TRUE; - } -#endif - - while (1) { - - /* - * Protect against races here. If the command is done, or we are - * on a different command forget it. - */ - if (reset_flags & SCSI_RESET_ASYNCHRONOUS) - if (SCpnt->serial_number != SCpnt->serial_number_at_timeout) { - return 0; - } - if (SCpnt->internal_timeout & IN_RESET) { - spin_unlock_irq(&io_request_lock); - while (SCpnt->internal_timeout & IN_RESET) - barrier(); - spin_lock_irq(&io_request_lock); - } else { - SCpnt->internal_timeout |= IN_RESET; - update_timeout(SCpnt, RESET_TIMEOUT); - - if (reset_flags & SCSI_RESET_SYNCHRONOUS) - SCpnt->flags |= SYNC_RESET; - if (host->host_busy) { - for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) { - SCpnt1 = SDpnt->device_queue; - while (SCpnt1) { - if (SCpnt1->request.rq_status != RQ_INACTIVE) { -#if 0 - if (!(SCpnt1->flags & IS_RESETTING) && - !(SCpnt1->internal_timeout & IN_ABORT)) - scsi_abort(SCpnt1, DID_RESET); -#endif - SCpnt1->flags |= (WAS_RESET | IS_RESETTING); - } - SCpnt1 = SCpnt1->next; - } - } - - host->last_reset = jiffies; - host->resetting = 1; - /* - * I suppose that the host reset callback will not play - * with the resetting field. We have just set the resetting - * flag here. -arca - */ - temp = host->hostt->reset(SCpnt, reset_flags); - /* - This test allows the driver to introduce an additional bus - settle time delay by setting last_reset up to 20 seconds in - the future. In the normal case where the driver does not - modify last_reset, it must be assumed that the actual bus - reset occurred immediately prior to the return to this code, - and so last_reset must be updated to the current time, so - that the delay in internal_cmnd will guarantee at least a - MIN_RESET_DELAY bus settle time. - */ - if (host->last_reset - jiffies > 20UL * HZ) - host->last_reset = jiffies; - } else { - host->host_busy++; - host->last_reset = jiffies; - host->resetting = 1; - SCpnt->flags |= (WAS_RESET | IS_RESETTING); - /* - * I suppose that the host reset callback will not play - * with the resetting field. We have just set the resetting - * flag here. -arca - */ - temp = host->hostt->reset(SCpnt, reset_flags); - if (time_before(host->last_reset, jiffies) || - (time_after(host->last_reset, jiffies + 20 * HZ))) - host->last_reset = jiffies; - host->host_busy--; - } - if (reset_flags & SCSI_RESET_SYNCHRONOUS) - SCpnt->flags &= ~SYNC_RESET; - -#ifdef DEBUG - printk("scsi reset function returned %d\n", temp); -#endif - - /* - * Now figure out what we need to do, based upon - * what the low level driver said that it did. - * If the result is SCSI_RESET_SUCCESS, SCSI_RESET_PENDING, - * or SCSI_RESET_WAKEUP, then the low level driver did a - * bus device reset or bus reset, so we should go through - * and mark one or all of the devices on that bus - * as having been reset. - */ - switch (temp & SCSI_RESET_ACTION) { - case SCSI_RESET_SUCCESS: - if (temp & SCSI_RESET_HOST_RESET) - scsi_mark_host_reset(host); - else if (temp & SCSI_RESET_BUS_RESET) - scsi_mark_bus_reset(host, SCpnt->channel); - else - scsi_mark_device_reset(SCpnt->device); - SCpnt->internal_timeout &= ~(IN_RESET | IN_RESET2 | IN_RESET3); - return 0; - case SCSI_RESET_PENDING: - if (temp & SCSI_RESET_HOST_RESET) - scsi_mark_host_reset(host); - else if (temp & SCSI_RESET_BUS_RESET) - scsi_mark_bus_reset(host, SCpnt->channel); - else - scsi_mark_device_reset(SCpnt->device); - case SCSI_RESET_NOT_RUNNING: - return 0; - case SCSI_RESET_PUNT: - SCpnt->internal_timeout &= ~(IN_RESET | IN_RESET2 | IN_RESET3); - scsi_request_sense(SCpnt); - return 0; - case SCSI_RESET_WAKEUP: - if (temp & SCSI_RESET_HOST_RESET) - scsi_mark_host_reset(host); - else if (temp & SCSI_RESET_BUS_RESET) - scsi_mark_bus_reset(host, SCpnt->channel); - else - scsi_mark_device_reset(SCpnt->device); - SCpnt->internal_timeout &= ~(IN_RESET | IN_RESET2 | IN_RESET3); - scsi_request_sense(SCpnt); - /* - * If a bus reset was performed, we - * need to wake up each and every command - * that was active on the bus or if it was a HBA - * reset all active commands on all channels - */ - if (temp & SCSI_RESET_HOST_RESET) { - for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) { - SCpnt1 = SDpnt->device_queue; - while (SCpnt1) { - if (SCpnt1->request.rq_status != RQ_INACTIVE - && SCpnt1 != SCpnt) - scsi_request_sense(SCpnt1); - SCpnt1 = SCpnt1->next; - } - } - } else if (temp & SCSI_RESET_BUS_RESET) { - for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) { - SCpnt1 = SDpnt->device_queue; - while (SCpnt1) { - if (SCpnt1->request.rq_status != RQ_INACTIVE - && SCpnt1 != SCpnt - && SCpnt1->channel == SCpnt->channel) - scsi_request_sense(SCpnt); - SCpnt1 = SCpnt1->next; - } - } - } - return 0; - case SCSI_RESET_SNOOZE: - /* In this case, we set the timeout field to 0 - * so that this command does not time out any more, - * and we return 1 so that we get a message on the - * screen. - */ - SCpnt->internal_timeout &= ~(IN_RESET | IN_RESET2 | IN_RESET3); - update_timeout(SCpnt, 0); - /* If you snooze, you lose... */ - case SCSI_RESET_ERROR: - default: - return 1; - } - - return temp; - } - } -} - -/* - * The strategy is to cause the timer code to call scsi_times_out() - * when the soonest timeout is pending. - * The arguments are used when we are queueing a new command, because - * we do not want to subtract the time used from this time, but when we - * set the timer, we want to take this value into account. - */ - -int update_timeout(Scsi_Cmnd * SCset, int timeout) -{ - int rtn; - - /* - * We are using the new error handling code to actually register/deregister - * timers for timeout. - */ - - if (!timer_pending(&SCset->eh_timeout)) { - rtn = 0; - } else { - rtn = SCset->eh_timeout.expires - jiffies; - } - - if (timeout == 0) { - scsi_delete_timer(SCset); - } else { - scsi_add_timer(SCset, timeout, scsi_old_times_out); - } - - return rtn; -} - - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil - * tab-width: 8 - * End: - */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_queue.c linux/drivers/scsi/scsi_queue.c --- v2.5.0/linux/drivers/scsi/scsi_queue.c Fri Feb 9 11:30:23 2001 +++ linux/drivers/scsi/scsi_queue.c Wed Dec 12 13:41:09 2001 @@ -137,10 +137,10 @@ * Decrement the counters, since these commands are no longer * active on the host/device. */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&cmd->host->host_lock, flags); cmd->host->host_busy--; cmd->device->device_busy--; - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&cmd->host->host_lock, flags); /* * Insert this command at the head of the queue for it's device. diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c --- v2.5.0/linux/drivers/scsi/scsi_scan.c Tue Nov 13 17:35:16 2001 +++ linux/drivers/scsi/scsi_scan.c Sun Dec 16 12:20:21 2001 @@ -320,7 +320,7 @@ SDpnt->host = shpnt; SDpnt->online = TRUE; - initialize_merge_fn(SDpnt); + scsi_initialize_merge_fn(SDpnt); /* * Initialize the object that we will use to wait for command blocks. @@ -390,8 +390,6 @@ } } } - scsi_resize_dma_pool(); - for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) { if (sdtpnt->finish && sdtpnt->nr_dev) { (*sdtpnt->finish) (); @@ -759,7 +757,7 @@ */ scsi_initialize_queue(SDpnt, shpnt); SDpnt->host = shpnt; - initialize_merge_fn(SDpnt); + scsi_initialize_merge_fn(SDpnt); /* * Mark this device as online, or otherwise we won't be able to do much with it. diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/scsi_syms.c linux/drivers/scsi/scsi_syms.c --- v2.5.0/linux/drivers/scsi/scsi_syms.c Mon Jul 2 15:27:56 2001 +++ linux/drivers/scsi/scsi_syms.c Sun Dec 16 12:20:21 2001 @@ -33,8 +33,6 @@ */ EXPORT_SYMBOL(scsi_register_module); EXPORT_SYMBOL(scsi_unregister_module); -EXPORT_SYMBOL(scsi_free); -EXPORT_SYMBOL(scsi_malloc); EXPORT_SYMBOL(scsi_register); EXPORT_SYMBOL(scsi_unregister); EXPORT_SYMBOL(scsicam_bios_param); @@ -48,13 +46,10 @@ EXPORT_SYMBOL(print_req_sense); EXPORT_SYMBOL(print_msg); EXPORT_SYMBOL(print_status); -EXPORT_SYMBOL(scsi_dma_free_sectors); EXPORT_SYMBOL(kernel_scsi_ioctl); -EXPORT_SYMBOL(scsi_need_isa_buffer); EXPORT_SYMBOL(scsi_release_command); EXPORT_SYMBOL(print_Scsi_Cmnd); EXPORT_SYMBOL(scsi_block_when_processing_errors); -EXPORT_SYMBOL(scsi_mark_host_reset); EXPORT_SYMBOL(scsi_ioctl_send_command); #if defined(CONFIG_SCSI_LOGGING) /* { */ EXPORT_SYMBOL(scsi_logging_level); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c --- v2.5.0/linux/drivers/scsi/sd.c Fri Nov 9 14:05:06 2001 +++ linux/drivers/scsi/sd.c Sun Dec 16 12:20:21 2001 @@ -61,10 +61,6 @@ #include -/* - * static const char RCSid[] = "$Header:"; - */ - #define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i)) #define SCSI_DISKS_PER_MAJOR 16 @@ -72,8 +68,7 @@ #define SD_MINOR_NUMBER(i) ((i) & 255) #define MKDEV_SD_PARTITION(i) MKDEV(SD_MAJOR_NUMBER(i), (i) & 255) #define MKDEV_SD(index) MKDEV_SD_PARTITION((index) << 4) -#define N_USED_SCSI_DISKS (sd_template.dev_max + SCSI_DISKS_PER_MAJOR - 1) -#define N_USED_SD_MAJORS (N_USED_SCSI_DISKS / SCSI_DISKS_PER_MAJOR) +#define N_USED_SD_MAJORS (1 + ((sd_template.dev_max - 1) >> 4)) #define MAX_RETRIES 5 @@ -89,7 +84,6 @@ static Scsi_Disk *rscsi_disks; static int *sd_sizes; static int *sd_blocksizes; -static int *sd_hardsizes; /* Hardware sector size */ static int *sd_max_sectors; static int check_scsidisk_media_change(kdev_t); @@ -97,7 +91,6 @@ static int sd_init_onedisk(int); - static int sd_init(void); static void sd_finish(void); static int sd_attach(Scsi_Device *); @@ -124,7 +117,6 @@ init_command:sd_init_command, }; - static void rw_intr(Scsi_Cmnd * SCpnt); #if defined(CONFIG_PPC) @@ -191,11 +183,11 @@ &diskinfo[0]); else scsicam_bios_param(&rscsi_disks[DEVICE_NR(dev)], dev, &diskinfo[0]); - if (put_user(diskinfo[0], &loc->heads) || put_user(diskinfo[1], &loc->sectors) || put_user(diskinfo[2], &loc->cylinders) || - put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start)) + put_user((unsigned) get_start_sect(inode->i_rdev), + (unsigned long *) &loc->start)) return -EFAULT; return 0; } @@ -226,7 +218,8 @@ if (put_user(diskinfo[0], &loc->heads) || put_user(diskinfo[1], &loc->sectors) || put_user(diskinfo[2], (unsigned int *) &loc->cylinders) || - put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start)) + put_user((unsigned)get_start_sect(inode->i_rdev), + (unsigned long *)&loc->start)) return -EFAULT; return 0; } @@ -239,8 +232,8 @@ case BLKFLSBUF: case BLKSSZGET: case BLKPG: - case BLKELVGET: - case BLKELVSET: + case BLKELVGET: + case BLKELVSET: case BLKBSZGET: case BLKBSZSET: return blk_ioctl(inode->i_rdev, cmd, arg); @@ -251,7 +244,8 @@ return revalidate_scsidisk(dev, 1); default: - return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device , cmd, (void *) arg); + return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device, + cmd, (void *) arg); } } @@ -292,6 +286,12 @@ char nbuff[6]; #endif + /* + * don't support specials for nwo + */ + if (!(SCpnt->request.flags & REQ_CMD)) + return 0; + devm = SD_PARTITION(SCpnt->request.rq_dev); dev = DEVICE_NR(SCpnt->request.rq_dev); @@ -301,7 +301,7 @@ SCSI_LOG_HLQUEUE(1, printk("Doing sd request, dev = %d, block = %d\n", devm, block)); dpnt = &rscsi_disks[dev]; - if (devm >= (sd_template.dev_max << 4) || + if (devm >= (sd_template.dev_max << 4) || (devm & 0xf) || !dpnt || !dpnt->device->online || block + SCpnt->request.nr_sectors > sd[devm].nr_sects) { @@ -309,7 +309,7 @@ SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); return 0; } - block += sd[devm].start_sect; + if (dpnt->device->changed) { /* * quietly refuse to do anything to a changed disc until the changed @@ -360,21 +360,17 @@ this_count = this_count >> 3; } } - switch (SCpnt->request.cmd) { - case WRITE: + if (rq_data_dir(&SCpnt->request) == WRITE) { if (!dpnt->device->writeable) { return 0; } SCpnt->cmnd[0] = WRITE_6; SCpnt->sc_data_direction = SCSI_DATA_WRITE; - break; - case READ: + } else if (rq_data_dir(&SCpnt->request) == READ) { SCpnt->cmnd[0] = READ_6; SCpnt->sc_data_direction = SCSI_DATA_READ; - break; - default: - panic("Unknown sd command %d\n", SCpnt->request.cmd); - } + } else + panic("Unknown sd command %lx\n", SCpnt->request.flags); SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", nbuff, @@ -618,8 +614,8 @@ (SCpnt->sense_buffer[4] << 16) | (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6]; - if (SCpnt->request.bh != NULL) - block_sectors = SCpnt->request.bh->b_size >> 9; + if (SCpnt->request.bio != NULL) + block_sectors = bio_sectors(SCpnt->request.bio); switch (SCpnt->device->sector_size) { case 1024: error_sector <<= 1; @@ -642,7 +638,7 @@ default: break; } - error_sector -= sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect; + error_sector &= ~(block_sectors - 1); good_sectors = error_sector - SCpnt->request.sector; if (good_sectors < 0 || good_sectors >= this_count) @@ -769,7 +765,7 @@ return i; } - buffer = (unsigned char *) scsi_malloc(512); + buffer = kmalloc(512, GFP_DMA); if (!buffer) { printk(KERN_WARNING "(sd_init_onedisk:) Memory allocation failure.\n"); scsi_release_request(SRpnt); @@ -970,15 +966,11 @@ * So I have created this table. See ll_rw_blk.c * Jacques Gelinas (Jacques@solucorp.qc.ca) */ - int m; int hard_sector = sector_size; int sz = rscsi_disks[i].capacity * (hard_sector/256); /* There are 16 minors allocated for each major device */ - for (m = i << 4; m < ((i + 1) << 4); m++) { - sd_hardsizes[m] = hard_sector; - } - + blk_queue_hardsect_size(blk_get_queue(SD_MAJOR(i)), hard_sector); printk("SCSI device %s: " "%d %d-byte hdwr sectors (%d MB)\n", nbuff, rscsi_disks[i].capacity, @@ -1050,7 +1042,7 @@ scsi_release_request(SRpnt); SRpnt = NULL; - scsi_free(buffer, 512); + kfree(buffer); return i; } @@ -1063,7 +1055,7 @@ static int sd_init() { - int i; + int i, maxparts; if (sd_template.dev_noticed == 0) return 0; @@ -1074,10 +1066,17 @@ if (sd_template.dev_max > N_SD_MAJORS * SCSI_DISKS_PER_MAJOR) sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR; + /* At most 16 partitions on each scsi disk. */ + maxparts = (sd_template.dev_max << 4); + if (maxparts == 0) + return 0; + if (!sd_registered) { for (i = 0; i < N_USED_SD_MAJORS; i++) { - if (devfs_register_blkdev(SD_MAJOR(i), "sd", &sd_fops)) { - printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i)); + if (devfs_register_blkdev(SD_MAJOR(i), "sd", + &sd_fops)) { + printk("Unable to get major %d for SCSI disk\n", + SD_MAJOR(i)); return 1; } } @@ -1087,80 +1086,63 @@ if (rscsi_disks) return 0; - rscsi_disks = kmalloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC); - if (!rscsi_disks) - goto cleanup_devfs; - memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk)); - - /* for every (necessary) major: */ - sd_sizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); - if (!sd_sizes) - goto cleanup_disks; - memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int)); - - sd_blocksizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); - if (!sd_blocksizes) - goto cleanup_sizes; - - sd_hardsizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); - if (!sd_hardsizes) - goto cleanup_blocksizes; - - sd_max_sectors = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); - if (!sd_max_sectors) - goto cleanup_max_sectors; + /* allocate memory */ +#define init_mem_lth(x,n) x = kmalloc((n) * sizeof(*x), GFP_ATOMIC) +#define zero_mem_lth(x,n) memset(x, 0, (n) * sizeof(*x)) + + init_mem_lth(rscsi_disks, sd_template.dev_max); + init_mem_lth(sd_sizes, maxparts); + init_mem_lth(sd_blocksizes, maxparts); + init_mem_lth(sd, maxparts); + init_mem_lth(sd_gendisks, N_USED_SD_MAJORS); + init_mem_lth(sd_max_sectors, sd_template.dev_max << 4); + + if (!rscsi_disks || !sd_sizes || !sd_blocksizes || !sd || !sd_gendisks) + goto cleanup_mem; + + zero_mem_lth(rscsi_disks, sd_template.dev_max); + zero_mem_lth(sd_sizes, maxparts); + zero_mem_lth(sd, maxparts); - for (i = 0; i < sd_template.dev_max << 4; i++) { + for (i = 0; i < maxparts; i++) { sd_blocksizes[i] = 1024; - sd_hardsizes[i] = 512; /* * Allow lowlevel device drivers to generate 512k large scsi * commands if they know what they're doing and they ask for it * explicitly via the SHpnt->max_sectors API. */ - sd_max_sectors[i] = MAX_SEGMENTS*8; + sd_max_sectors[i] = MAX_PHYS_SEGMENTS*8; } for (i = 0; i < N_USED_SD_MAJORS; i++) { - blksize_size[SD_MAJOR(i)] = sd_blocksizes + i * (SCSI_DISKS_PER_MAJOR << 4); - hardsect_size[SD_MAJOR(i)] = sd_hardsizes + i * (SCSI_DISKS_PER_MAJOR << 4); - max_sectors[SD_MAJOR(i)] = sd_max_sectors + i * (SCSI_DISKS_PER_MAJOR << 4); - } - /* - * FIXME: should unregister blksize_size, hardsect_size and max_sectors when - * the module is unloaded. - */ - sd = kmalloc((sd_template.dev_max << 4) * - sizeof(struct hd_struct), - GFP_ATOMIC); - if (!sd) - goto cleanup_sd; - memset(sd, 0, (sd_template.dev_max << 4) * sizeof(struct hd_struct)); - - if (N_USED_SD_MAJORS > 1) - sd_gendisks = kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC); - if (!sd_gendisks) - goto cleanup_sd_gendisks; + request_queue_t *q = blk_get_queue(SD_MAJOR(i)); + int parts_per_major = (SCSI_DISKS_PER_MAJOR << 4); + + blksize_size[SD_MAJOR(i)] = + sd_blocksizes + i * parts_per_major; + blk_queue_hardsect_size(q, 512); + } + for (i = 0; i < N_USED_SD_MAJORS; i++) { + int N = SCSI_DISKS_PER_MAJOR; + sd_gendisks[i] = sd_gendisk; - sd_gendisks[i].de_arr = kmalloc (SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].de_arr, - GFP_ATOMIC); - if (!sd_gendisks[i].de_arr) - goto cleanup_gendisks_de_arr; - memset (sd_gendisks[i].de_arr, 0, - SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].de_arr); - sd_gendisks[i].flags = kmalloc (SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].flags, - GFP_ATOMIC); - if (!sd_gendisks[i].flags) - goto cleanup_gendisks_flags; - memset (sd_gendisks[i].flags, 0, - SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].flags); + + init_mem_lth(sd_gendisks[i].de_arr, N); + init_mem_lth(sd_gendisks[i].flags, N); + + if (!sd_gendisks[i].de_arr || !sd_gendisks[i].flags) + goto cleanup_gendisks; + + zero_mem_lth(sd_gendisks[i].de_arr, N); + zero_mem_lth(sd_gendisks[i].flags, N); + sd_gendisks[i].major = SD_MAJOR(i); sd_gendisks[i].major_name = "sd"; sd_gendisks[i].minor_shift = 4; sd_gendisks[i].max_p = 1 << 4; - sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4); - sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4); + sd_gendisks[i].part = sd + i * (N << 4); + sd_gendisks[i].sizes = sd_sizes + i * (N << 4); sd_gendisks[i].nr_real = 0; sd_gendisks[i].real_devices = (void *) (rscsi_disks + i * SCSI_DISKS_PER_MAJOR); @@ -1168,27 +1150,21 @@ return 0; -cleanup_gendisks_flags: - kfree(sd_gendisks[i].de_arr); -cleanup_gendisks_de_arr: - while (--i >= 0 ) { +#undef init_mem_lth +#undef zero_mem_lth + +cleanup_gendisks: + /* kfree can handle NULL, so no test is required here */ + for (i = 0; i < N_USED_SD_MAJORS; i++) { kfree(sd_gendisks[i].de_arr); kfree(sd_gendisks[i].flags); } +cleanup_mem: kfree(sd_gendisks); -cleanup_sd_gendisks: kfree(sd); -cleanup_sd: - kfree(sd_max_sectors); -cleanup_max_sectors: - kfree(sd_hardsizes); -cleanup_blocksizes: kfree(sd_blocksizes); -cleanup_sizes: kfree(sd_sizes); -cleanup_disks: kfree(rscsi_disks); -cleanup_devfs: for (i = 0; i < N_USED_SD_MAJORS; i++) { devfs_unregister_blkdev(SD_MAJOR(i), "sd"); } @@ -1203,7 +1179,7 @@ for (i = 0; i < N_USED_SD_MAJORS; i++) { blk_dev[SD_MAJOR(i)].queue = sd_find_queue; - add_gendisk(&sd_gendisks[i]); + add_gendisk(&(sd_gendisks[i])); } for (i = 0; i < sd_template.dev_max; ++i) @@ -1293,9 +1269,7 @@ int revalidate_scsidisk(kdev_t dev, int maxusage) { int target; - int max_p; - int start; - int i; + int res; target = DEVICE_NR(dev); @@ -1305,36 +1279,18 @@ } DEVICE_BUSY = 1; - max_p = sd_gendisks->max_p; - start = target << sd_gendisks->minor_shift; - - for (i = max_p - 1; i >= 0; i--) { - int index = start + i; - invalidate_device(MKDEV_SD_PARTITION(index), 1); - sd_gendisks->part[index].start_sect = 0; - sd_gendisks->part[index].nr_sects = 0; - /* - * Reset the blocksize for everything so that we can read - * the partition table. Technically we will determine the - * correct block size when we revalidate, but we do this just - * to make sure that everything remains consistent. - */ - sd_blocksizes[index] = 1024; - if (rscsi_disks[target].device->sector_size == 2048) - sd_blocksizes[index] = 2048; - else - sd_blocksizes[index] = 1024; - } + res = wipe_partitions(dev); + if (res) + goto leave; #ifdef MAYBE_REINIT MAYBE_REINIT; #endif - grok_partitions(&SD_GENDISK(target), target % SCSI_DISKS_PER_MAJOR, - 1<<4, CAPACITY); - + grok_partitions(dev, CAPACITY); +leave: DEVICE_BUSY = 0; - return 0; + return res; } static int fop_revalidate_scsidisk(kdev_t dev) @@ -1344,6 +1300,7 @@ static void sd_detach(Scsi_Device * SDp) { Scsi_Disk *dpnt; + kdev_t dev; int i, j; int max_p; int start; @@ -1351,18 +1308,13 @@ for (dpnt = rscsi_disks, i = 0; i < sd_template.dev_max; i++, dpnt++) if (dpnt->device == SDp) { - /* If we are disconnecting a disk driver, sync and invalidate - * everything */ max_p = sd_gendisk.max_p; start = i << sd_gendisk.minor_shift; + dev = MKDEV_SD_PARTITION(start); + wipe_partitions(dev); + for (j = max_p - 1; j >= 0; j--) + sd_sizes[start + j] = 0; - for (j = max_p - 1; j >= 0; j--) { - int index = start + j; - invalidate_device(MKDEV_SD_PARTITION(index), 1); - sd_gendisks->part[index].start_sect = 0; - sd_gendisks->part[index].nr_sects = 0; - sd_sizes[index] = 0; - } devfs_register_partitions (&SD_GENDISK (i), SD_MINOR_NUMBER (start), 1); /* unregister_disk() */ @@ -1375,7 +1327,6 @@ SD_GENDISK(i).nr_real--; return; } - return; } static int __init init_sd(void) @@ -1398,14 +1349,11 @@ kfree(rscsi_disks); kfree(sd_sizes); kfree(sd_blocksizes); - kfree(sd_hardsizes); kfree((char *) sd); } for (i = 0; i < N_USED_SD_MAJORS; i++) { - del_gendisk(&sd_gendisks[i]); - blk_size[SD_MAJOR(i)] = NULL; - hardsect_size[SD_MAJOR(i)] = NULL; - read_ahead[SD_MAJOR(i)] = 0; + del_gendisk(&(sd_gendisks[i])); + blk_clear(SD_MAJOR(i)); } sd_template.dev_max = 0; if (sd_gendisks != &sd_gendisk) diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c --- v2.5.0/linux/drivers/scsi/sg.c Sun Nov 4 09:31:57 2001 +++ linux/drivers/scsi/sg.c Sun Dec 16 12:20:21 2001 @@ -336,9 +336,7 @@ Sg_device * sdp; Sg_fd * sfp; - lock_kernel(); if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp))) { - unlock_kernel(); return -ENXIO; } SCSI_LOG_TIMEOUT(3, printk("sg_release: dev=%d\n", MINOR(sdp->i_rdev))); @@ -352,7 +350,6 @@ sdp->exclude = 0; wake_up_interruptible(&sdp->o_excl_wait); } - unlock_kernel(); return 0; } @@ -2283,9 +2280,8 @@ rqSz = num_sect * SG_SECTOR_SZ; } while (num_sect > 0) { - if ((num_sect <= sg_pool_secs_avail) && - (scsi_dma_free_sectors > (SG_LOW_POOL_THRESHHOLD + num_sect))) { - resp = scsi_malloc(rqSz); + if ((num_sect <= sg_pool_secs_avail)) { + resp = kmalloc(rqSz, page_mask); if (resp) { if (retSzp) *retSzp = rqSz; sg_pool_secs_avail -= num_sect; @@ -2377,7 +2373,7 @@ { int num_sect = size / SG_SECTOR_SZ; - scsi_free(buff, size); + kfree(buff); sg_pool_secs_avail += num_sect; } break; @@ -2684,9 +2680,8 @@ max_dev = sg_last_dev(); PRINT_PROC("dev_max(currently)=%d max_active_device=%d (origin 1)\n", sg_template.dev_max, max_dev); - PRINT_PROC(" scsi_dma_free_sectors=%u sg_pool_secs_aval=%d " - "def_reserved_size=%d\n", - scsi_dma_free_sectors, sg_pool_secs_avail, sg_big_buff); + PRINT_PROC(" sg_pool_secs_aval=%d def_reserved_size=%d\n", + sg_pool_secs_avail, sg_big_buff); for (j = 0; j < max_dev; ++j) { if ((sdp = sg_get_dev(j))) { Sg_fd * fp; diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sim710.h linux/drivers/scsi/sim710.h --- v2.5.0/linux/drivers/scsi/sim710.h Thu Jul 19 21:07:45 2001 +++ linux/drivers/scsi/sim710.h Thu Nov 29 13:55:59 2001 @@ -37,8 +37,7 @@ this_id: 7, \ sg_tablesize: 128, \ cmd_per_lun: 1, \ - use_clustering: DISABLE_CLUSTERING, \ - use_new_eh_code: 1} + use_clustering: DISABLE_CLUSTERING } #ifndef HOSTS_C diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c --- v2.5.0/linux/drivers/scsi/sr.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/scsi/sr.c Sun Dec 16 12:20:21 2001 @@ -88,7 +88,6 @@ static int *sr_sizes; static int *sr_blocksizes; -static int *sr_hardsizes; static int sr_open(struct cdrom_device_info *, int); void get_sectorsize(int); @@ -218,8 +217,8 @@ (SCpnt->sense_buffer[4] << 16) | (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6]; - if (SCpnt->request.bh != NULL) - block_sectors = SCpnt->request.bh->b_size >> 9; + if (SCpnt->request.bio != NULL) + block_sectors = bio_sectors(SCpnt->request.bio); if (block_sectors < 4) block_sectors = 4; if (scsi_CDs[device_nr].device->sector_size == 2048) @@ -259,107 +258,6 @@ return &scsi_CDs[MINOR(dev)].device->request_queue; } -static int sr_scatter_pad(Scsi_Cmnd *SCpnt, int s_size) -{ - struct scatterlist *sg, *old_sg = NULL; - int i, fsize, bsize, sg_ent, sg_count; - char *front, *back; - void **bbpnt, **old_bbpnt = NULL; - - back = front = NULL; - sg_ent = SCpnt->use_sg; - bsize = 0; /* gcc... */ - - /* - * need front pad - */ - if ((fsize = SCpnt->request.sector % (s_size >> 9))) { - fsize <<= 9; - sg_ent++; - if ((front = scsi_malloc(fsize)) == NULL) - goto no_mem; - } - /* - * need a back pad too - */ - if ((bsize = s_size - ((SCpnt->request_bufflen + fsize) % s_size))) { - sg_ent++; - if ((back = scsi_malloc(bsize)) == NULL) - goto no_mem; - } - - /* - * extend or allocate new scatter-gather table - */ - sg_count = SCpnt->use_sg; - if (sg_count) { - old_sg = (struct scatterlist *) SCpnt->request_buffer; - old_bbpnt = SCpnt->bounce_buffers; - } else { - sg_count = 1; - sg_ent++; - } - - /* Get space for scatterlist and bounce buffer array. */ - i = sg_ent * sizeof(struct scatterlist); - i += sg_ent * sizeof(void *); - i = (i + 511) & ~511; - - if ((sg = scsi_malloc(i)) == NULL) - goto no_mem; - - bbpnt = (void **) - ((char *)sg + (sg_ent * sizeof(struct scatterlist))); - - /* - * no more failing memory allocs possible, we can safely assign - * SCpnt values now - */ - SCpnt->sglist_len = i; - SCpnt->use_sg = sg_count; - memset(sg, 0, SCpnt->sglist_len); - - i = 0; - if (fsize) { - sg[0].address = bbpnt[0] = front; - sg[0].length = fsize; - i++; - } - if (old_sg) { - memcpy(sg + i, old_sg, SCpnt->use_sg * sizeof(struct scatterlist)); - memcpy(bbpnt + i, old_bbpnt, SCpnt->use_sg * sizeof(void *)); - scsi_free(old_sg, (((SCpnt->use_sg * sizeof(struct scatterlist)) + - (SCpnt->use_sg * sizeof(void *))) + 511) & ~511); - } else { - sg[i].address = SCpnt->request_buffer; - sg[i].length = SCpnt->request_bufflen; - } - - SCpnt->request_bufflen += (fsize + bsize); - SCpnt->request_buffer = sg; - SCpnt->bounce_buffers = bbpnt; - SCpnt->use_sg += i; - - if (bsize) { - sg[SCpnt->use_sg].address = back; - bbpnt[SCpnt->use_sg] = back; - sg[SCpnt->use_sg].length = bsize; - SCpnt->use_sg++; - } - - return 0; - -no_mem: - printk("sr: ran out of mem for scatter pad\n"); - if (front) - scsi_free(front, fsize); - if (back) - scsi_free(back, bsize); - - return 1; -} - - static int sr_init_command(Scsi_Cmnd * SCpnt) { int dev, devm, block=0, this_count, s_size; @@ -384,7 +282,12 @@ return 0; } - if ((SCpnt->request.cmd == WRITE) && !scsi_CDs[dev].device->writeable) + if (!(SCpnt->request.flags & REQ_CMD)) { + blk_dump_rq_flags(&SCpnt->request, "sr unsup command"); + return 0; + } + + if (rq_data_dir(&SCpnt->request) == WRITE && !scsi_CDs[dev].device->writeable) return 0; /* @@ -404,31 +307,30 @@ return 0; } - block = SCpnt->request.sector / (s_size >> 9); - - /* - * request doesn't start on hw block boundary, add scatter pads - */ - if ((SCpnt->request.sector % (s_size >> 9)) || (SCpnt->request_bufflen % s_size)) - if (sr_scatter_pad(SCpnt, s_size)) + if (rq_data_dir(&SCpnt->request) == WRITE) { + if (!scsi_CDs[dev].device->writeable) return 0; - - this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); - - switch (SCpnt->request.cmd) { - case WRITE: SCpnt->cmnd[0] = WRITE_10; SCpnt->sc_data_direction = SCSI_DATA_WRITE; - break; - case READ: + } else if (rq_data_dir(&SCpnt->request) == READ) { SCpnt->cmnd[0] = READ_10; SCpnt->sc_data_direction = SCSI_DATA_READ; - break; - default: - printk("Unknown sr command %d\n", SCpnt->request.cmd); + } else { + blk_dump_rq_flags(&SCpnt->request, "Unknown sr command"); return 0; } + /* + * request doesn't start on hw block boundary, add scatter pads + */ + if ((SCpnt->request.sector % (s_size >> 9)) || (SCpnt->request_bufflen % s_size)) { + printk("sr: unaligned transfer\n"); + return 0; + } + + this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); + + SCSI_LOG_HLQUEUE(2, printk("sr%d : %s %d/%ld 512 byte blocks.\n", devm, (SCpnt->request.cmd == WRITE) ? "writing" : "reading", @@ -437,6 +339,8 @@ SCpnt->cmnd[1] = (SCpnt->device->scsi_level <= SCSI_2) ? ((SCpnt->lun << 5) & 0xe0) : 0; + block = SCpnt->request.sector / (s_size >> 9); + if (this_count > 0xffff) this_count = 0xffff; @@ -574,7 +478,7 @@ int sector_size; Scsi_Request *SRpnt; - buffer = (unsigned char *) scsi_malloc(512); + buffer = (unsigned char *) kmalloc(512, GFP_DMA); SRpnt = scsi_allocate_request(scsi_CDs[i].device); if(buffer == NULL || SRpnt == NULL) @@ -583,7 +487,7 @@ sector_size = 2048; /* A guess, just in case */ scsi_CDs[i].needs_sector_size = 1; if(buffer) - scsi_free(buffer, 512); + kfree(buffer); if(SRpnt) scsi_release_request(SRpnt); return; @@ -663,7 +567,8 @@ scsi_CDs[i].needs_sector_size = 0; sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS - 9); }; - scsi_free(buffer, 512); + blk_queue_hardsect_size(blk_get_queue(MAJOR_NR), sector_size); + kfree(buffer); } void get_capabilities(int i) @@ -684,7 +589,7 @@ "" }; - buffer = (unsigned char *) scsi_malloc(512); + buffer = (unsigned char *) kmalloc(512, GFP_DMA); if (!buffer) { printk(KERN_ERR "sr: out of memory.\n"); @@ -704,7 +609,7 @@ scsi_CDs[i].cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | CDC_DVD | CDC_DVD_RAM | CDC_SELECT_DISC | CDC_SELECT_SPEED); - scsi_free(buffer, 512); + kfree(buffer); printk("sr%i: scsi-1 drive\n", i); return; } @@ -757,7 +662,7 @@ /*else I don't think it can close its tray scsi_CDs[i].cdi.mask |= CDC_CLOSE_TRAY; */ - scsi_free(buffer, 512); + kfree(buffer); } /* @@ -811,21 +716,14 @@ if (!sr_blocksizes) goto cleanup_sizes; - sr_hardsizes = kmalloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC); - if (!sr_hardsizes) - goto cleanup_blocksizes; /* * These are good guesses for the time being. */ - for (i = 0; i < sr_template.dev_max; i++) { + for (i = 0; i < sr_template.dev_max; i++) sr_blocksizes[i] = 2048; - sr_hardsizes[i] = 2048; - } + blksize_size[MAJOR_NR] = sr_blocksizes; - hardsect_size[MAJOR_NR] = sr_hardsizes; return 0; -cleanup_blocksizes: - kfree(sr_blocksizes); cleanup_sizes: kfree(sr_sizes); cleanup_cds: @@ -897,7 +795,6 @@ else read_ahead[MAJOR_NR] = 4; /* 4 sector read-ahead */ - return; } static void sr_detach(Scsi_Device * SDp) @@ -905,17 +802,18 @@ Scsi_CD *cpnt; int i; - for (cpnt = scsi_CDs, i = 0; i < sr_template.dev_max; i++, cpnt++) + for (cpnt = scsi_CDs, i = 0; i < sr_template.dev_max; i++, cpnt++) { if (cpnt->device == SDp) { /* - * Since the cdrom is read-only, no need to sync the device. + * Since the cdrom is read-only, no need to sync + * the device. * We should be kind to our buffer cache, however. */ invalidate_device(MKDEV(MAJOR_NR, i), 0); /* - * Reset things back to a sane state so that one can re-load a new - * driver (perhaps the same one). + * Reset things back to a sane state so that one can + * re-load a new driver (perhaps the same one). */ unregister_cdrom(&(cpnt->cdi)); cpnt->device = NULL; @@ -926,7 +824,7 @@ sr_sizes[i] = 0; return; } - return; + } } static int __init init_sr(void) @@ -948,13 +846,9 @@ kfree(sr_blocksizes); sr_blocksizes = NULL; - kfree(sr_hardsizes); - sr_hardsizes = NULL; } - blksize_size[MAJOR_NR] = NULL; - hardsect_size[MAJOR_NR] = NULL; - blk_size[MAJOR_NR] = NULL; read_ahead[MAJOR_NR] = 0; + blk_clear(MAJOR_NR); sr_template.dev_max = 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c --- v2.5.0/linux/drivers/scsi/sr_ioctl.c Mon Oct 15 13:27:42 2001 +++ linux/drivers/scsi/sr_ioctl.c Sun Dec 16 12:20:21 2001 @@ -95,7 +95,7 @@ SRpnt->sr_request.buffer = buffer; if (buffer && SRpnt->sr_host->unchecked_isa_dma && (virt_to_phys(buffer) + buflength - 1 > ISA_DMA_THRESHOLD)) { - bounce_buffer = (char *) scsi_malloc((buflength + 511) & ~511); + bounce_buffer = (char *) kmalloc(buflength, GFP_DMA); if (bounce_buffer == NULL) { printk("SCSI DMA pool exhausted."); return -ENOMEM; @@ -114,7 +114,7 @@ req = &SRpnt->sr_request; if (SRpnt->sr_buffer && req->buffer && SRpnt->sr_buffer != req->buffer) { memcpy(req->buffer, SRpnt->sr_buffer, SRpnt->sr_bufflen); - scsi_free(SRpnt->sr_buffer, (SRpnt->sr_bufflen + 511) & ~511); + kfree(SRpnt->sr_buffer); SRpnt->sr_buffer = req->buffer; } @@ -519,7 +519,7 @@ if (!xa_test) return 0; - raw_sector = (unsigned char *) scsi_malloc(2048 + 512); + raw_sector = (unsigned char *) kmalloc(2048, GFP_DMA | GFP_KERNEL); if (!raw_sector) return -ENOMEM; if (0 == sr_read_sector(minor, scsi_CDs[minor].ms_offset + 16, @@ -529,7 +529,7 @@ /* read a raw sector failed for some reason. */ is_xa = -1; } - scsi_free(raw_sector, 2048 + 512); + kfree(raw_sector); #ifdef DEBUG printk("sr%d: sr_is_xa: %d\n", minor, is_xa); #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sr_vendor.c linux/drivers/scsi/sr_vendor.c --- v2.5.0/linux/drivers/scsi/sr_vendor.c Thu Jul 5 11:28:17 2001 +++ linux/drivers/scsi/sr_vendor.c Sun Dec 16 12:20:21 2001 @@ -115,7 +115,7 @@ density = (blocklength > 2048) ? 0x81 : 0x83; #endif - buffer = (unsigned char *) scsi_malloc(512); + buffer = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA); if (!buffer) return -ENOMEM; @@ -142,7 +142,7 @@ printk("sr%d: switching blocklength to %d bytes failed\n", minor, blocklength); #endif - scsi_free(buffer, 512); + kfree(buffer); return rc; } @@ -162,7 +162,7 @@ if (scsi_CDs[minor].cdi.mask & CDC_MULTI_SESSION) return 0; - buffer = (unsigned char *) scsi_malloc(512); + buffer = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA); if (!buffer) return -ENOMEM; @@ -306,6 +306,6 @@ printk(KERN_DEBUG "sr%d: multisession offset=%lu\n", minor, sector); #endif - scsi_free(buffer, 512); + kfree(buffer); return rc; } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c --- v2.5.0/linux/drivers/scsi/sym53c8xx.c Wed Oct 17 14:16:39 2001 +++ linux/drivers/scsi/sym53c8xx.c Sun Dec 16 12:20:21 2001 @@ -1,7 +1,7 @@ /****************************************************************************** ** High Performance device driver for the Symbios 53C896 controller. ** -** Copyright (C) 1998-2000 Gerard Roudier +** Copyright (C) 1998-2001 Gerard Roudier ** ** This driver also supports all the Symbios 53C8XX controller family, ** except 53C810 revisions < 16, 53C825 revisions < 16 and all @@ -32,7 +32,7 @@ ** The Linux port of the FreeBSD ncr driver has been achieved in ** november 1995 by: ** -** Gerard Roudier +** Gerard Roudier ** ** Being given that this driver originates from the FreeBSD version, and ** in order to keep synergy on both, any suggested enhancements and corrections @@ -642,10 +642,10 @@ #define NCR_LOCK_NCB(np, flags) spin_lock_irqsave(&np->smp_lock, flags) #define NCR_UNLOCK_NCB(np, flags) spin_unlock_irqrestore(&np->smp_lock, flags) -#define NCR_LOCK_SCSI_DONE(np, flags) \ - spin_lock_irqsave(&io_request_lock, flags) -#define NCR_UNLOCK_SCSI_DONE(np, flags) \ - spin_unlock_irqrestore(&io_request_lock, flags) +#define NCR_LOCK_SCSI_DONE(host, flags) \ + spin_lock_irqsave(&((host)->host_lock), flags) +#define NCR_UNLOCK_SCSI_DONE(host, flags) \ + spin_unlock_irqrestore(&((host)->host_lock), flags) #else @@ -656,8 +656,8 @@ #define NCR_LOCK_NCB(np, flags) do { save_flags(flags); cli(); } while (0) #define NCR_UNLOCK_NCB(np, flags) do { restore_flags(flags); } while (0) -#define NCR_LOCK_SCSI_DONE(np, flags) do {;} while (0) -#define NCR_UNLOCK_SCSI_DONE(np, flags) do {;} while (0) +#define NCR_LOCK_SCSI_DONE(host, flags) do {;} while (0) +#define NCR_UNLOCK_SCSI_DONE(host, flags) do {;} while (0) #endif @@ -12126,13 +12126,16 @@ if (!use_sg) segn = ncr_scatter_no_sglist(np, cp, cmd); - else if (use_sg > MAX_SCATTER) - segn = -1; else { struct scatterlist *scatter = (struct scatterlist *)cmd->buffer; struct scr_tblmove *data; use_sg = map_scsi_sg_data(np, cmd); + if (use_sg > MAX_SCATTER) { + unmap_scsi_data(np, cmd); + return -1; + } + data = &cp->phys.data[MAX_SCATTER - use_sg]; for (segn = 0; segn < use_sg; segn++) { @@ -12165,13 +12168,15 @@ if (!use_sg) segment = ncr_scatter_no_sglist(np, cp, cmd); - else if (use_sg > MAX_SCATTER) - segment = -1; else { struct scatterlist *scatter = (struct scatterlist *)cmd->buffer; struct scr_tblmove *data; use_sg = map_scsi_sg_data(np, cmd); + if (use_sg > MAX_SCATTER) { + unmap_scsi_data(np, cmd); + return -1; + } data = &cp->phys.data[MAX_SCATTER - use_sg]; for (segment = 0; segment < use_sg; segment++) { @@ -13676,9 +13681,9 @@ if (DEBUG_FLAGS & DEBUG_TINY) printk ("]\n"); if (done_list) { - NCR_LOCK_SCSI_DONE(np, flags); + NCR_LOCK_SCSI_DONE(done_list->host, flags); ncr_flush_done_cmds(done_list); - NCR_UNLOCK_SCSI_DONE(np, flags); + NCR_UNLOCK_SCSI_DONE(done_list->host, flags); } } @@ -13699,9 +13704,9 @@ NCR_UNLOCK_NCB(np, flags); if (done_list) { - NCR_LOCK_SCSI_DONE(np, flags); + NCR_LOCK_SCSI_DONE(done_list->host, flags); ncr_flush_done_cmds(done_list); - NCR_UNLOCK_SCSI_DONE(np, flags); + NCR_UNLOCK_SCSI_DONE(done_list->host, flags); } } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx.h linux/drivers/scsi/sym53c8xx.h --- v2.5.0/linux/drivers/scsi/sym53c8xx.h Thu Nov 22 11:49:48 2001 +++ linux/drivers/scsi/sym53c8xx.h Sun Dec 16 15:47:13 2001 @@ -1,7 +1,7 @@ /****************************************************************************** ** High Performance device driver for the Symbios 53C896 controller. ** -** Copyright (C) 1998-2000 Gerard Roudier +** Copyright (C) 1998-2001 Gerard Roudier ** ** This driver also supports all the Symbios 53C8XX controller family, ** except 53C810 revisions < 16, 53C825 revisions < 16 and all @@ -32,7 +32,7 @@ ** The Linux port of the FreeBSD ncr driver has been achieved in ** november 1995 by: ** -** Gerard Roudier +** Gerard Roudier ** ** Being given that this driver originates from the FreeBSD version, and ** in order to keep synergy on both, any suggested enhancements and corrections @@ -96,8 +96,9 @@ this_id: 7, \ sg_tablesize: SCSI_NCR_SG_TABLESIZE, \ cmd_per_lun: SCSI_NCR_CMD_PER_LUN, \ - max_sectors: MAX_SEGMENTS*8, \ - use_clustering: DISABLE_CLUSTERING} + max_sectors: MAX_HW_SEGMENTS*8, \ + use_clustering: DISABLE_CLUSTERING, \ + highmem_io: 1} #else diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx_2/ChangeLog.txt linux/drivers/scsi/sym53c8xx_2/ChangeLog.txt --- v2.5.0/linux/drivers/scsi/sym53c8xx_2/ChangeLog.txt Fri Nov 9 15:22:54 2001 +++ linux/drivers/scsi/sym53c8xx_2/ChangeLog.txt Sun Dec 16 12:20:21 2001 @@ -128,3 +128,21 @@ * version sym-2.1.16-20011028 - Slightly simplify driver configuration. - Prepare a new patch against linux-2.4.13. + +Sat Nov 17 10:00 2001 Gerard Roudier + * version sym-2.1.17 + - Fix a couple of gcc/gcc3 warnings. + - Allocate separately from the HCB the array for CCBs hashed by DSA. + All driver memory allocations are now not greater than 1 PAGE + even on PPC64 / 4KB PAGE surprising setup. + +Sat Dec 01 18:00 2001 Gerard Roudier + * version sym-2.1.17a + - Use u_long instead of U32 for the IO base cookie. This is more + consistent with what archs are expecting. + - Use MMIO per default for Power PC instead of some fake normal IO, + as Paul Mackerras stated that MMIO works fine now on this arch. + + + + diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym53c8xx.h linux/drivers/scsi/sym53c8xx_2/sym53c8xx.h --- v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym53c8xx.h Fri Nov 9 15:22:54 2001 +++ linux/drivers/scsi/sym53c8xx_2/sym53c8xx.h Sun Dec 16 12:20:21 2001 @@ -109,7 +109,6 @@ release: sym53c8xx_release, \ info: sym53c8xx_info, \ queuecommand: sym53c8xx_queue_command, \ - use_new_eh_code: 1, \ eh_abort_handler: sym53c8xx_eh_abort_handler, \ eh_device_reset_handler:sym53c8xx_eh_device_reset_handler, \ eh_bus_reset_handler: sym53c8xx_eh_bus_reset_handler, \ @@ -119,7 +118,8 @@ this_id: 7, \ sg_tablesize: 0, \ cmd_per_lun: 0, \ - use_clustering: DISABLE_CLUSTERING} + use_clustering: DISABLE_CLUSTERING, \ + highmem_io: 1} #endif /* defined(HOSTS_C) || defined(MODULE) */ @@ -130,17 +130,17 @@ #if !defined(HOSTS_C) /* - * Use normal IO if configured. Forced for alpha and powerpc. - * Powerpc fails copying to on-chip RAM using memcpy_toio(). + * Use normal IO if configured. + * Normal IO forced for alpha. * Forced to MMIO for sparc. */ #if defined(__alpha__) #define SYM_CONF_IOMAPPED -#elif defined(__powerpc__) -#define SYM_CONF_IOMAPPED -#define SYM_OPT_NO_BUS_MEMORY_MAPPING #elif defined(__sparc__) #undef SYM_CONF_IOMAPPED +/* #elif defined(__powerpc__) */ +/* #define SYM_CONF_IOMAPPED */ +/* #define SYM_OPT_NO_BUS_MEMORY_MAPPING */ #elif defined(CONFIG_SCSI_SYM53C8XX_IOMAPPED) #define SYM_CONF_IOMAPPED #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym_glue.c linux/drivers/scsi/sym53c8xx_2/sym_glue.c --- v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym_glue.c Fri Nov 9 15:22:54 2001 +++ linux/drivers/scsi/sym53c8xx_2/sym_glue.c Sun Dec 16 12:20:21 2001 @@ -138,18 +138,11 @@ #define SYM_LOCK_DRIVER(flags) spin_lock_irqsave(&sym53c8xx_lock, flags) #define SYM_UNLOCK_DRIVER(flags) spin_unlock_irqrestore(&sym53c8xx_lock,flags) -#define SYM_INIT_LOCK_HCB(np) spin_lock_init(&np->s.smp_lock); -#define SYM_LOCK_HCB(np, flags) spin_lock_irqsave(&np->s.smp_lock, flags) -#define SYM_UNLOCK_HCB(np, flags) spin_unlock_irqrestore(&np->s.smp_lock, flags) - -#define SYM_LOCK_SCSI(np, flags) \ - spin_lock_irqsave(&io_request_lock, flags) -#define SYM_UNLOCK_SCSI(np, flags) \ - spin_unlock_irqrestore(&io_request_lock, flags) - -/* Ugly, but will make things easier if this locking will ever disappear */ -#define SYM_LOCK_SCSI_NOSAVE(np) spin_lock_irq(&io_request_lock) -#define SYM_UNLOCK_SCSI_NORESTORE(np) spin_unlock_irq(&io_request_lock) +#define SYM_INIT_LOCK_HCB(np) spin_lock_init(&np->s.host->host_lock); +#define SYM_LOCK_HCB(np, flags) \ + spin_lock_irqsave(&np->s.host->host_lock, flags) +#define SYM_UNLOCK_HCB(np, flags) \ + spin_unlock_irqrestore(&np->s.host->host_lock, flags) /* * These simple macros limit expression involving @@ -654,12 +647,15 @@ if (!use_sg) segment = sym_scatter_no_sglist(np, cp, cmd); - else if (use_sg > SYM_CONF_MAX_SG) - segment = -1; else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) { struct scatterlist *scatter = (struct scatterlist *)cmd->buffer; struct sym_tblmove *data; + if (use_sg > SYM_CONF_MAX_SG) { + unmap_scsi_data(np, cmd); + return -1; + } + data = &cp->phys.data[SYM_CONF_MAX_SG - use_sg]; for (segment = 0; segment < use_sg; segment++) { @@ -966,14 +962,18 @@ { hcb_p np = SYM_SOFTC_PTR(cmd); ucmd_p ucp = SYM_UCMD_PTR(cmd); - u_long flags; int sts = 0; +#if 0 + u_long flags; +#endif cmd->scsi_done = done; cmd->host_scribble = NULL; memset(ucp, 0, sizeof(*ucp)); +#if 0 SYM_LOCK_HCB(np, flags); +#endif /* * Shorten our settle_time if needed for @@ -999,7 +999,9 @@ sym_insque_tail(&ucp->link_cmdq, &np->s.wait_cmdq); } out: +#if 0 SYM_UNLOCK_HCB(np, flags); +#endif return 0; } @@ -1010,21 +1012,21 @@ static void sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs) { unsigned long flags; - unsigned long flags1; hcb_p np = (hcb_p) dev_id; if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("["); - SYM_LOCK_SCSI(np, flags1); SYM_LOCK_HCB(np, flags); sym_interrupt(np); + /* + * push queue walk-through to tasklet + */ if (!sym_que_empty(&np->s.wait_cmdq) && !np->s.settle_time_valid) sym_requeue_awaiting_cmds(np); SYM_UNLOCK_HCB(np, flags); - SYM_UNLOCK_SCSI(np, flags1); if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("]\n"); } @@ -1036,9 +1038,7 @@ { hcb_p np = (hcb_p) npref; unsigned long flags; - unsigned long flags1; - SYM_LOCK_SCSI(np, flags1); SYM_LOCK_HCB(np, flags); sym_timer(np); @@ -1047,7 +1047,6 @@ sym_requeue_awaiting_cmds(np); SYM_UNLOCK_HCB(np, flags); - SYM_UNLOCK_SCSI(np, flags1); } @@ -1209,9 +1208,7 @@ ep->timer.data = (u_long)cmd; ep->timed_out = 1; /* Be pessimistic for once :) */ add_timer(&ep->timer); - SYM_UNLOCK_SCSI_NORESTORE(np); down(&ep->sem); - SYM_LOCK_SCSI_NOSAVE(np); if (ep->timed_out) sts = -2; } @@ -1975,6 +1972,7 @@ goto attach_failed; #endif host_data->ncb = np; + np->s.host = instance; SYM_INIT_LOCK_HCB(np); @@ -2140,6 +2138,7 @@ instance->max_cmd_len = 16; #endif instance->select_queue_depths = sym53c8xx_select_queue_depths; + instance->highmem_io = 1; SYM_UNLOCK_HCB(np, flags); @@ -2456,8 +2455,8 @@ u_char pci_fix_up = SYM_SETUP_PCI_FIX_UP; u_char revision; u_int irq; - u_long base, base_2, io_port; - u_long base_c, base_2_c; + u_long base, base_2, base_io; + u_long base_c, base_2_c, io_port; int i; sym_chip *chip; @@ -2474,7 +2473,7 @@ device_id = PciDeviceId(pdev); irq = PciIrqLine(pdev); - i = pci_get_base_address(pdev, 0, &io_port); + i = pci_get_base_address(pdev, 0, &base_io); io_port = pci_get_base_cookie(pdev, 0); base_c = pci_get_base_cookie(pdev, i); @@ -2492,9 +2491,9 @@ /* * If user excluded this chip, donnot initialize it. */ - if (io_port) { + if (base_io) { for (i = 0 ; i < 8 ; i++) { - if (sym_driver_setup.excludes[i] == io_port) + if (sym_driver_setup.excludes[i] == base_io) return -1; } } diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym_glue.h linux/drivers/scsi/sym53c8xx_2/sym_glue.h --- v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym_glue.h Thu Nov 22 10:41:14 2001 +++ linux/drivers/scsi/sym53c8xx_2/sym_glue.h Sun Dec 16 12:20:21 2001 @@ -77,7 +77,6 @@ #include #include #include -#include #include #include #include @@ -456,14 +455,14 @@ char chip_name[8]; struct pci_dev *device; + struct Scsi_Host *host; + u_char bus; /* PCI BUS number */ u_char device_fn; /* PCI BUS device and function */ - spinlock_t smp_lock; /* Lock for SMP threading */ - vm_offset_t mmio_va; /* MMIO kernel virtual address */ vm_offset_t ram_va; /* RAM kernel virtual address */ - u32 io_port; /* IO port address */ + u_long io_port; /* IO port address cookie */ u_short io_ws; /* IO window size */ int irq; /* IRQ number */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym_hipd.c linux/drivers/scsi/sym53c8xx_2/sym_hipd.c --- v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym_hipd.c Fri Nov 9 15:22:54 2001 +++ linux/drivers/scsi/sym53c8xx_2/sym_hipd.c Sun Dec 16 12:20:21 2001 @@ -4691,6 +4691,7 @@ OUTL_DSP (SCRIPTA_BA (np, clrack)); return; out_stuck: + return; } /* @@ -5226,6 +5227,7 @@ return; fail: + return; } /* @@ -5788,6 +5790,13 @@ goto attach_failed; /* + * Allocate the array of lists of CCBs hashed by DSA. + */ + np->ccbh = sym_calloc(sizeof(ccb_p *)*CCB_HASH_SIZE, "CCBH"); + if (!np->ccbh) + goto attach_failed; + + /* * Initialyze the CCB free and busy queues. */ sym_que_init(&np->free_ccbq); @@ -5978,6 +5987,8 @@ sym_mfree_dma(cp, sizeof(*cp), "CCB"); } } + if (np->ccbh) + sym_mfree(np->ccbh, sizeof(ccb_p *)*CCB_HASH_SIZE, "CCBH"); if (np->badluntbl) sym_mfree_dma(np->badluntbl, 256,"BADLUNTBL"); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym_hipd.h linux/drivers/scsi/sym53c8xx_2/sym_hipd.h --- v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym_hipd.h Fri Nov 9 15:22:54 2001 +++ linux/drivers/scsi/sym53c8xx_2/sym_hipd.h Sun Dec 16 12:20:21 2001 @@ -1068,7 +1068,8 @@ /* * CCB lists and queue. */ - ccb_p ccbh[CCB_HASH_SIZE]; /* CCB hashed by DSA value */ + ccb_p *ccbh; /* CCBs hashed by DSA value */ + /* CCB_HASH_SIZE lists of CCBs */ SYM_QUEHEAD free_ccbq; /* Queue of available CCBs */ SYM_QUEHEAD busy_ccbq; /* Queue of busy CCBs */ diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym_nvram.c linux/drivers/scsi/sym53c8xx_2/sym_nvram.c --- v2.5.0/linux/drivers/scsi/sym53c8xx_2/sym_nvram.c Fri Nov 9 15:22:54 2001 +++ linux/drivers/scsi/sym53c8xx_2/sym_nvram.c Tue Nov 27 09:23:27 2001 @@ -505,10 +505,10 @@ return retv; } -#undef SET_BIT 0 -#undef CLR_BIT 1 -#undef SET_CLK 2 -#undef CLR_CLK 3 +#undef SET_BIT +#undef CLR_BIT +#undef SET_CLK +#undef CLR_CLK /* * Try reading Symbios NVRAM. diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx_comm.h linux/drivers/scsi/sym53c8xx_comm.h --- v2.5.0/linux/drivers/scsi/sym53c8xx_comm.h Fri Oct 12 15:35:54 2001 +++ linux/drivers/scsi/sym53c8xx_comm.h Sun Dec 16 12:20:21 2001 @@ -1,7 +1,7 @@ /****************************************************************************** ** High Performance device driver for the Symbios 53C896 controller. ** -** Copyright (C) 1998-2000 Gerard Roudier +** Copyright (C) 1998-2001 Gerard Roudier ** ** This driver also supports all the Symbios 53C8XX controller family, ** except 53C810 revisions < 16, 53C825 revisions < 16 and all @@ -32,7 +32,7 @@ ** The Linux port of the FreeBSD ncr driver has been achieved in ** november 1995 by: ** -** Gerard Roudier +** Gerard Roudier ** ** Being given that this driver originates from the FreeBSD version, and ** in order to keep synergy on both, any suggested enhancements and corrections diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/sym53c8xx_defs.h linux/drivers/scsi/sym53c8xx_defs.h --- v2.5.0/linux/drivers/scsi/sym53c8xx_defs.h Thu Nov 22 11:49:36 2001 +++ linux/drivers/scsi/sym53c8xx_defs.h Sun Dec 16 15:47:00 2001 @@ -1,7 +1,7 @@ /****************************************************************************** ** High Performance device driver for the Symbios 53C896 controller. ** -** Copyright (C) 1998-2000 Gerard Roudier +** Copyright (C) 1998-2001 Gerard Roudier ** ** This driver also supports all the Symbios 53C8XX controller family, ** except 53C810 revisions < 16, 53C825 revisions < 16 and all @@ -32,7 +32,7 @@ ** The Linux port of the FreeBSD ncr driver has been achieved in ** november 1995 by: ** -** Gerard Roudier +** Gerard Roudier ** ** Being given that this driver originates from the FreeBSD version, and ** in order to keep synergy on both, any suggested enhancements and corrections diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c --- v2.5.0/linux/drivers/scsi/u14-34f.c Thu Oct 25 13:53:51 2001 +++ linux/drivers/scsi/u14-34f.c Wed Dec 12 09:20:22 2001 @@ -1,6 +1,9 @@ /* * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters. * + * 11 Dec 2001 Rev. 7.00 for linux 2.5.1 + * + Use host->host_lock instead of io_request_lock. + * * 1 May 2001 Rev. 6.05 for linux 2.4.4 * + Fix data transfer direction for opcode SEND_CUE_SHEET (0x5d) * @@ -334,7 +337,6 @@ * the driver sets host->wish_block = TRUE for all ISA boards. */ -#include #include #ifndef LinuxVersionCode @@ -343,6 +345,9 @@ #define MAX_INT_PARAM 10 +#if defined(MODULE) +#include + MODULE_PARM(boot_options, "s"); MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i"); MODULE_PARM(linked_comm, "i"); @@ -352,6 +357,8 @@ MODULE_PARM(ext_tran, "i"); MODULE_AUTHOR("Dario Ballabio"); +#endif + #include #include #include @@ -374,13 +381,6 @@ #include #include -#define SPIN_FLAGS unsigned long spin_flags; -#define SPIN_LOCK spin_lock_irq(&io_request_lock); -#define SPIN_LOCK_SAVE spin_lock_irqsave(&io_request_lock, spin_flags); -#define SPIN_UNLOCK spin_unlock_irq(&io_request_lock); -#define SPIN_UNLOCK_RESTORE \ - spin_unlock_irqrestore(&io_request_lock, spin_flags); - /* Values for the PRODUCT_ID ports for the 14/34F */ #define PRODUCT_ID1 0x56 #define PRODUCT_ID2 0x40 /* NOTE: Only upper nibble is used */ @@ -672,10 +672,8 @@ /* Issue OGM interrupt */ outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR); - SPIN_UNLOCK time = jiffies; while ((jiffies - time) < HZ && limit++ < 20000) udelay(100L); - SPIN_LOCK if (cpp->adapter_status || HD(j)->cp_stat[0] != FREE) { HD(j)->cp_stat[0] = FREE; @@ -1274,10 +1272,12 @@ #endif HD(j)->in_reset = TRUE; - SPIN_UNLOCK + + spin_unlock_irq(&sh[j]->host_lock); time = jiffies; while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); - SPIN_LOCK + spin_lock_irq(&sh[j]->host_lock); + printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); for (i = 0; i < sh[j]->can_queue; i++) { @@ -1718,14 +1718,14 @@ static void do_interrupt_handler(int irq, void *shap, struct pt_regs *regs) { unsigned int j; - SPIN_FLAGS + unsigned long spin_flags; /* Check if the interrupt must be processed by this handler */ if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return; - SPIN_LOCK_SAVE + spin_lock_irqsave(&sh[j]->host_lock, spin_flags); ihdlr(irq, j); - SPIN_UNLOCK_RESTORE + spin_unlock_irqrestore(&sh[j]->host_lock, spin_flags); } int u14_34f_release(struct Scsi_Host *shpnt) { @@ -1752,7 +1752,6 @@ return FALSE; } -MODULE_LICENSE("BSD without advertisement clause"); static Scsi_Host_Template driver_template = ULTRASTOR_14_34F; #include "scsi_module.c" @@ -1760,3 +1759,4 @@ #ifndef MODULE __setup("u14-34f=", option_setup); #endif /* end MODULE */ +MODULE_LICENSE("GPL"); diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h --- v2.5.0/linux/drivers/scsi/u14-34f.h Sat May 19 17:43:06 2001 +++ linux/drivers/scsi/u14-34f.h Wed Dec 12 09:20:22 2001 @@ -13,7 +13,7 @@ int u14_34f_reset(Scsi_Cmnd *); int u14_34f_biosparam(Disk *, kdev_t, int *); -#define U14_34F_VERSION "6.05.00" +#define U14_34F_VERSION "7.00.00" #define ULTRASTOR_14_34F { \ name: "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \ @@ -30,7 +30,6 @@ this_id: 7, \ unchecked_isa_dma: 1, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 1 /* Enable new error code */ \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/scsi/wd7000.h linux/drivers/scsi/wd7000.h --- v2.5.0/linux/drivers/scsi/wd7000.h Thu Jul 19 21:08:46 2001 +++ linux/drivers/scsi/wd7000.h Wed Nov 28 10:22:27 2001 @@ -57,6 +57,5 @@ cmd_per_lun: 1, \ unchecked_isa_dma: 1, \ use_clustering: ENABLE_CLUSTERING, \ - use_new_eh_code: 0 \ } #endif diff -u --recursive --new-file v2.5.0/linux/drivers/sgi/char/graphics.c linux/drivers/sgi/char/graphics.c --- v2.5.0/linux/drivers/sgi/char/graphics.c Thu Oct 11 09:43:30 2001 +++ linux/drivers/sgi/char/graphics.c Fri Nov 30 08:26:04 2001 @@ -196,7 +196,6 @@ int board = GRAPHICS_CARD (inode->i_rdev); /* Tell the rendering manager that one client is going away */ - lock_kernel(); rrm_close (inode, file); /* Was this file handle from the board owner?, clear it */ @@ -206,7 +205,6 @@ (*cards [board].g_reset_console)(); enable_gconsole (); } - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/sgi/char/shmiq.c linux/drivers/sgi/char/shmiq.c --- v2.5.0/linux/drivers/sgi/char/shmiq.c Mon Aug 27 08:56:31 2001 +++ linux/drivers/sgi/char/shmiq.c Fri Nov 30 08:38:44 2001 @@ -79,11 +79,13 @@ /* /dev/qcntlN attached memory regions, location and size of the event queue */ static struct { - int opened; /* if this device has been opened */ - void *shmiq_vaddr; /* mapping in kernel-land */ - int tail; /* our copy of the shmiq->tail */ - int events; - int mapped; + int opened; + void *shmiq_vaddr; /* mapping in kernel-land */ + spinlock_t shmiq_lock:SPIN_LOCK_UNLOCKED; + /* protects vaddr and opened */ + int tail; /* our copy of the shmiq->tail */ + int events; + int mapped; wait_queue_head_t proc_list; struct fasync_struct *fasync; @@ -328,12 +330,11 @@ size = vma->vm_end - vma->vm_start; start = vma->vm_start; - lock_kernel(); - mem = (unsigned long) shmiqs [minor].shmiq_vaddr = vmalloc_uncached (size); - if (!mem) { - unlock_kernel(); + mem = vmalloc_uncached (size); + if (!mem) return -EINVAL; - } + spin_lock( &shmiqs [minor].shmiq_lock ); + hmiqs [minor].shmiq_vaddr = mem; /* Prevent the swapper from considering these pages for swap and touching them */ vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO); @@ -342,13 +343,12 @@ /* Uncache the pages */ vma->vm_page_prot = PAGE_USERIO; - error = vmap_page_range (vma->vm_start, size, mem); shmiqs [minor].tail = 0; /* Init the shared memory input queue */ + spin_unlock( &shmiqs [minor].shmiq_lock ); memset (shmiqs [minor].shmiq_vaddr, 0, size); - unlock_kernel(); - + error = vmap_page_range (vma->vm_start, size, mem); return error; } @@ -393,13 +393,16 @@ minor--; if (minor > MAX_SHMI_QUEUES) return -EINVAL; + spin_lock( &shmiqs [minor].shmiq_lock ); if (shmiqs [minor].opened) + { + spin_unlock( &shmiqs [minor].shmiq_lock ); return -EBUSY; + } - lock_kernel (); shmiqs [minor].opened = 1; shmiqs [minor].shmiq_vaddr = 0; - unlock_kernel (); + spin_unlock( &shmiqs [minor].shmiq_lock ); return 0; } @@ -429,18 +432,21 @@ if (minor > MAX_SHMI_QUEUES) return -EINVAL; - if (shmiqs [minor].opened == 0) + + spin_lock( &shmiqs [minor].shmiq_lock ); + if (shmiqs [minor].opened == 0) { + spin_unlock( &shmiqs [minor].shmiq_lock ); return -EINVAL; + } - lock_kernel (); shmiq_qcntl_fasync (-1, filp, 0); - shmiqs [minor].opened = 0; + shmiqs [minor].opened = 0; shmiqs [minor].mapped = 0; shmiqs [minor].events = 0; shmiqs [minor].fasync = 0; vfree (shmiqs [minor].shmiq_vaddr); shmiqs [minor].shmiq_vaddr = 0; - unlock_kernel (); + spin_unlock( &shmiqs [minor].shmiq_lock ); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/sgi/char/streamable.c linux/drivers/sgi/char/streamable.c --- v2.5.0/linux/drivers/sgi/char/streamable.c Wed Jul 12 21:58:43 2000 +++ linux/drivers/sgi/char/streamable.c Fri Nov 30 08:26:04 2001 @@ -221,9 +221,7 @@ static int sgi_mouse_close (struct inode *inode, struct file *filp) { - lock_kernel(); mouse_opened = 0; - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/sound/ad1816.c linux/drivers/sound/ad1816.c --- v2.5.0/linux/drivers/sound/ad1816.c Fri Nov 9 15:22:54 2001 +++ linux/drivers/sound/ad1816.c Sun Nov 25 09:43:42 2001 @@ -1258,7 +1258,7 @@ static int __initdata dma = -1; static int __initdata dma2 = -1; -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ struct pci_dev *ad1816_dev = NULL; static int activated = 1; @@ -1280,7 +1280,7 @@ MODULE_PARM(ad1816_clockfreq,"i"); MODULE_PARM(options,"i"); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev) { @@ -1407,7 +1407,7 @@ static int __init init_ad1816(void) { -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ if(isapnp && (ad1816_probe_isapnp(&cfg) < 0) ) { printk(KERN_NOTICE "ad1816: No ISAPnP cards found, trying standard ones...\n"); isapnp = 0; @@ -1447,7 +1447,7 @@ } nr_ad1816_devs=0; -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ if(activated) if(ad1816_dev) ad1816_dev->deactivate(ad1816_dev); diff -u --recursive --new-file v2.5.0/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c --- v2.5.0/linux/drivers/sound/ad1848.c Sun Sep 30 12:26:08 2001 +++ linux/drivers/sound/ad1848.c Tue Nov 27 16:44:37 2001 @@ -30,6 +30,12 @@ * Aki Laukkanen : added power management support * Arnaldo C. de Melo : added missing restore_flags in ad1848_resume * Miguel Freitas : added ISA PnP support + * Alan Cox : Added CS4236->4239 identification + * Daniel T. Cobra : Alernate config/mixer for later chips + * Alan Cox : Merged chip idents and config code + * + * TODO + * APM save restore assist code on IBM thinkpad * * Status: * Tested. Believed fully functional. @@ -57,7 +63,7 @@ int dual_dma; /* 1, when two DMA channels allocated */ int subtype; unsigned char MCE_bit; - unsigned char saved_regs[32]; + unsigned char saved_regs[64]; /* Includes extended register space */ int debug_flag; int audio_flags; @@ -78,6 +84,9 @@ #define MD_IWAVE 7 #define MD_4235 8 /* Crystal Audio CS4235 */ #define MD_1845_SSCAPE 9 /* Ensoniq Soundscape PNP*/ +#define MD_4236 10 /* 4236 and higher */ +#define MD_42xB 11 /* CS 42xB */ +#define MD_4239 12 /* CS4239 */ /* Mixer parameters */ int recmask; @@ -162,7 +171,7 @@ ,{CAP_F_TIMER} /* MD_1845_SSCAPE */ }; -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ static int isapnp = 1; static int isapnpjump = 0; static int reverse = 0; @@ -202,9 +211,22 @@ save_flags(flags); cli(); - outb(((unsigned char) (reg & 0xff) | devc->MCE_bit), io_Index_Addr(devc)); - x = inb(io_Indexed_Data(devc)); -/* printk("(%02x<-%02x) ", reg|devc->MCE_bit, x); */ + + if(reg < 32) + { + outb(((unsigned char) (reg & 0xff) | devc->MCE_bit), io_Index_Addr(devc)); + x = inb(io_Indexed_Data(devc)); + } + else + { + int xreg, xra; + + xreg = (reg & 0xff) - 32; + xra = (((xreg & 0x0f) << 4) & 0xf0) | 0x08 | ((xreg & 0x10) >> 2); + outb(((unsigned char) (23 & 0xff) | devc->MCE_bit), io_Index_Addr(devc)); + outb(((unsigned char) (xra & 0xff)), io_Indexed_Data(devc)); + x = inb(io_Indexed_Data(devc)); + } restore_flags(flags); return x; @@ -220,9 +242,22 @@ save_flags(flags); cli(); - outb(((unsigned char) (reg & 0xff) | devc->MCE_bit), io_Index_Addr(devc)); - outb(((unsigned char) (data & 0xff)), io_Indexed_Data(devc)); - /* printk("(%02x->%02x) ", reg|devc->MCE_bit, data); */ + + if(reg < 32) + { + outb(((unsigned char) (reg & 0xff) | devc->MCE_bit), io_Index_Addr(devc)); + outb(((unsigned char) (data & 0xff)), io_Indexed_Data(devc)); + } + else + { + int xreg, xra; + + xreg = (reg & 0xff) - 32; + xra = (((xreg & 0x0f) << 4) & 0xf0) | 0x08 | ((xreg & 0x10) >> 2); + outb(((unsigned char) (23 & 0xff) | devc->MCE_bit), io_Index_Addr(devc)); + outb(((unsigned char) (xra & 0xff)), io_Indexed_Data(devc)); + outb((unsigned char) (data & 0xff), io_Indexed_Data(devc)); + } restore_flags(flags); } @@ -591,7 +626,13 @@ devc->mix_devices = &(iwave_mix_devices[0]); break; + case MD_42xB: + case MD_4239: + devc->mix_devices = &(cs42xb_mix_devices[0]); + devc->supported_devices = MODE3_MIXER_DEVICES; + break; case MD_4232: + case MD_4236: devc->supported_devices = MODE3_MIXER_DEVICES; break; @@ -1118,7 +1159,7 @@ } old_fs = ad_read(devc, 8); - if (devc->model == MD_4232) + if (devc->model == MD_4232 || devc->model >= MD_4236) { tmp = ad_read(devc, 16); ad_write(devc, 16, tmp | 0x30); @@ -1139,7 +1180,7 @@ while (timeout < 10000 && inb(devc->base) == 0x80) timeout++; - if (devc->model == MD_4232) + if (devc->model >= MD_4232) ad_write(devc, 16, tmp & ~0x30); ad_leave_MCE(devc); /* @@ -1403,11 +1444,12 @@ static void ad1848_init_hw(ad1848_info * devc) { int i; + int *init_values; /* * Initial values for the indirect registers of CS4248/AD1848. */ - static int init_values[] = + static int init_values_a[] = { 0xa8, 0xa8, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x8a, 0x01, 0x00, 0x00, @@ -1417,6 +1459,31 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + static int init_values_b[] = + { + /* + Values for the newer chips + Some of the register initialization values were changed. In + order to get rid of the click that preceded PCM playback, + calibration was disabled on the 10th byte. On that same byte, + dual DMA was enabled; on the 11th byte, ADC dithering was + enabled, since that is theoretically desirable; on the 13th + byte, Mode 3 was selected, to enable access to extended + registers. + */ + 0xa8, 0xa8, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0xe0, 0x01, 0x00, 0x00, + 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x1f, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + /* + * Select initialisation data + */ + + init_values = init_values_a; + if(devc->model >= MD_4236) + init_values = init_values_b; for (i = 0; i < 16; i++) ad_write(devc, i, init_values[i]); @@ -1768,19 +1835,49 @@ else { switch (id & 0x1f) { - case 3: /* CS4236/CS4235 */ + case 3: /* CS4236/CS4235/CS42xB/CS4239 */ { int xid; ad_write(devc, 12, ad_read(devc, 12) | 0x60); /* switch to mode 3 */ ad_write(devc, 23, 0x9c); /* select extended register 25 */ xid = inb(io_Indexed_Data(devc)); ad_write(devc, 12, ad_read(devc, 12) & ~0x60); /* back to mode 0 */ - if ((xid & 0x1f) == 0x1d) { - devc->chip_name = "CS4235"; - devc->model = MD_4235; - } else { - devc->chip_name = "CS4236"; - devc->model = MD_4232; + switch (xid & 0x1f) + { + case 0x00: + devc->chip_name = "CS4237B(B)"; + devc->model = MD_42xB; + break; + case 0x08: + /* Seems to be a 4238 ?? */ + devc->chip_name = "CS4238"; + devc->model = MD_42xB; + break; + case 0x09: + devc->chip_name = "CS4238B"; + devc->model = MD_42xB; + break; + case 0x0b: + devc->chip_name = "CS4236B"; + devc->model = MD_4236; + break; + case 0x10: + devc->chip_name = "CS4237B"; + devc->model = MD_42xB; + break; + case 0x1d: + devc->chip_name = "CS4235"; + devc->model = MD_4235; + break; + case 0x1e: + devc->chip_name = "CS4239"; + devc->model = MD_4239; + break; + default: + printk("Chip ident is %X.\n", xid&0x1F); + devc->chip_name = "CS42xx"; + devc->model = MD_4232; + break; } } break; @@ -2747,6 +2844,10 @@ save_flags(flags); cli(); + + /* Thinkpad is a bit more of PITA than normal. The BIOS tends to + restore it in a different config to the one we use. Need to + fix this somehow */ /* store old mixer levels */ memcpy(mixer_levels, devc->levels, sizeof (mixer_levels)); @@ -2830,7 +2931,7 @@ MODULE_PARM(deskpro_m, "i"); /* Special magic for Deskpro M box */ MODULE_PARM(soundpro, "i"); /* More special magic for SoundPro chips */ -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ MODULE_PARM(isapnp, "i"); MODULE_PARM(isapnpjump, "i"); MODULE_PARM(reverse, "i"); @@ -3000,7 +3101,7 @@ { printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n"); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ if(isapnp && (ad1848_isapnp_probe(&cfg) < 0) ) { printk(KERN_NOTICE "ad1848: No ISAPnP cards found, trying standard ones...\n"); isapnp = 0; @@ -3035,7 +3136,7 @@ if(loaded) unload_ms_sound(&cfg); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ if(audio_activated) if(ad1848_dev) ad1848_dev->deactivate(ad1848_dev); diff -u --recursive --new-file v2.5.0/linux/drivers/sound/ad1848_mixer.h linux/drivers/sound/ad1848_mixer.h --- v2.5.0/linux/drivers/sound/ad1848_mixer.h Sun Mar 7 15:22:06 1999 +++ linux/drivers/sound/ad1848_mixer.h Tue Nov 27 16:44:37 2001 @@ -57,14 +57,14 @@ SOUND_MASK_OGAIN) struct mixer_def { - unsigned int regno:5; /* register number for volume */ + unsigned int regno:6; /* register number for volume */ unsigned int polarity:1; /* volume polarity: 0=normal, 1=reversed */ unsigned int bitpos:3; /* position of bits in register for volume */ unsigned int nbits:3; /* number of bits in register for volume */ - unsigned int mutereg:5; /* register number for mute bit */ + unsigned int mutereg:6; /* register number for mute bit */ unsigned int mutepol:1; /* mute polarity: 0=normal, 1=reversed */ unsigned int mutepos:4; /* position of mute bit in register */ - unsigned int recreg:5; /* register number for recording bit */ + unsigned int recreg:6; /* register number for recording bit */ unsigned int recpol:1; /* recording polarity: 0=normal, 1=reversed */ unsigned int recpos:4; /* position of recording bit in register */ }; @@ -104,43 +104,69 @@ rec_reg_r, rec_pola_r, rec_pos_r}} static mixer_ents ad1848_mix_devices[32] = { -MIX_ENT(SOUND_MIXER_VOLUME, 27, 1, 0, 4, 29, 1, 0, 4, 8), -MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7), -MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_MIC, 0, 0, 5, 1, 1, 0, 5, 1, 8), -MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_IMIX, 13, 1, 2, 6, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8), -MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5, 7) + MIX_ENT(SOUND_MIXER_VOLUME, 27, 1, 0, 4, 29, 1, 0, 4, 8), + MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7), + MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_MIC, 0, 0, 5, 1, 1, 0, 5, 1, 8), + MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_IMIX, 13, 1, 2, 6, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8), + MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5, 7) }; static mixer_ents iwave_mix_devices[32] = { -MIX_ENT(SOUND_MIXER_VOLUME, 25, 1, 0, 5, 27, 1, 0, 5, 8), -MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7), -MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_MIC, 0, 0, 5, 1, 1, 0, 5, 1, 8), -MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_IMIX, 16, 1, 0, 5, 17, 1, 0, 5, 8), -MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8), -MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5, 7) + MIX_ENT(SOUND_MIXER_VOLUME, 25, 1, 0, 5, 27, 1, 0, 5, 8), + MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7), + MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_MIC, 0, 0, 5, 1, 1, 0, 5, 1, 8), + MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_IMIX, 16, 1, 0, 5, 17, 1, 0, 5, 8), + MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8), + MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5, 7) +}; + +static mixer_ents cs42xb_mix_devices[32] = { + /* Digital master volume actually has seven bits, but we only use + six to avoid the discontinuity when the analog gain kicks in. */ + MIX_ENT(SOUND_MIXER_VOLUME, 46, 1, 0, 6, 47, 1, 0, 6, 7), + MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7), + MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_MIC, 34, 1, 0, 5, 35, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7), + /* For the IMIX entry, it was not possible to use the MIX_ENT macro + because the mute bit is in different positions for the two + channels and requires reverse polarity. */ + [SOUND_MIXER_IMIX] = {{13, 1, 2, 6, 13, 1, 0, 0, 0, 8}, + {42, 1, 0, 6, 42, 1, 7, 0, 0, 8}}, + MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8), + MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_LINE3, 38, 1, 0, 6, 39, 1, 0, 6, 7) }; /* OPTi 82C930 has somewhat different port addresses. @@ -149,68 +175,68 @@ * MIC is level of mic monitoring direct to output. Same for CD, LINE, etc. */ static mixer_ents c930_mix_devices[32] = { -MIX_ENT(SOUND_MIXER_VOLUME, 22, 1, 1, 5, 23, 1, 1, 5, 7), -MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 1, 4, 5, 1, 1, 4, 7), -MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 5, 7, 1, 0, 5, 7), -MIX_ENT(SOUND_MIXER_SPEAKER, 22, 1, 1, 5, 23, 1, 1, 5, 7), -MIX_ENT(SOUND_MIXER_LINE, 18, 1, 1, 4, 19, 1, 1, 4, 7), -MIX_ENT(SOUND_MIXER_MIC, 20, 1, 1, 4, 21, 1, 1, 4, 7), -MIX_ENT(SOUND_MIXER_CD, 2, 1, 1, 4, 3, 1, 1, 4, 7), -MIX_ENT(SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8), -MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 1, 4, 3, 1, 1, 4, 7), -MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 1, 4, 5, 1, 1, 4, 7), -MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 1, 4, 19, 1, 1, 4, 7) + MIX_ENT(SOUND_MIXER_VOLUME, 22, 1, 1, 5, 23, 1, 1, 5, 7), + MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 1, 4, 5, 1, 1, 4, 7), + MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 5, 7, 1, 0, 5, 7), + MIX_ENT(SOUND_MIXER_SPEAKER, 22, 1, 1, 5, 23, 1, 1, 5, 7), + MIX_ENT(SOUND_MIXER_LINE, 18, 1, 1, 4, 19, 1, 1, 4, 7), + MIX_ENT(SOUND_MIXER_MIC, 20, 1, 1, 4, 21, 1, 1, 4, 7), + MIX_ENT(SOUND_MIXER_CD, 2, 1, 1, 4, 3, 1, 1, 4, 7), + MIX_ENT(SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8), + MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 1, 4, 3, 1, 1, 4, 7), + MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 1, 4, 5, 1, 1, 4, 7), + MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 1, 4, 19, 1, 1, 4, 7) }; static mixer_ents spro_mix_devices[32] = { -MIX_ENT (SOUND_MIXER_VOLUME, 19, 0, 4, 4, 19, 0, 0, 4, 8), -MIX_ENT (SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT (SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT2(SOUND_MIXER_SYNTH, 4, 1, 1, 4, 23, 0, 3, 0, 0, 8, - 5, 1, 1, 4, 23, 0, 3, 0, 0, 8), -MIX_ENT (SOUND_MIXER_PCM, 6, 1, 1, 4, 7, 1, 1, 4, 8), -MIX_ENT (SOUND_MIXER_SPEAKER, 18, 0, 3, 2, 0, 0, 0, 0, 8), -MIX_ENT2(SOUND_MIXER_LINE, 20, 0, 4, 4, 17, 1, 4, 16, 0, 2, - 20, 0, 0, 4, 17, 1, 3, 16, 0, 1), -MIX_ENT2(SOUND_MIXER_MIC, 18, 0, 0, 3, 17, 1, 0, 16, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -MIX_ENT2(SOUND_MIXER_CD, 21, 0, 4, 4, 17, 1, 2, 16, 0, 4, - 21, 0, 0, 4, 17, 1, 1, 16, 0, 3), -MIX_ENT (SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT (SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT (SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT (SOUND_MIXER_IGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8), -MIX_ENT (SOUND_MIXER_OGAIN, 17, 1, 6, 1, 0, 0, 0, 0, 8), -/* This is external wavetable */ -MIX_ENT2(SOUND_MIXER_LINE1, 22, 0, 4, 4, 23, 1, 1, 23, 0, 4, - 22, 0, 0, 4, 23, 1, 0, 23, 0, 5), + MIX_ENT (SOUND_MIXER_VOLUME, 19, 0, 4, 4, 19, 0, 0, 4, 8), + MIX_ENT (SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT (SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT2(SOUND_MIXER_SYNTH, 4, 1, 1, 4, 23, 0, 3, 0, 0, 8, + 5, 1, 1, 4, 23, 0, 3, 0, 0, 8), + MIX_ENT (SOUND_MIXER_PCM, 6, 1, 1, 4, 7, 1, 1, 4, 8), + MIX_ENT (SOUND_MIXER_SPEAKER, 18, 0, 3, 2, 0, 0, 0, 0, 8), + MIX_ENT2(SOUND_MIXER_LINE, 20, 0, 4, 4, 17, 1, 4, 16, 0, 2, + 20, 0, 0, 4, 17, 1, 3, 16, 0, 1), + MIX_ENT2(SOUND_MIXER_MIC, 18, 0, 0, 3, 17, 1, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + MIX_ENT2(SOUND_MIXER_CD, 21, 0, 4, 4, 17, 1, 2, 16, 0, 4, + 21, 0, 0, 4, 17, 1, 1, 16, 0, 3), + MIX_ENT (SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT (SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT (SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT (SOUND_MIXER_IGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8), + MIX_ENT (SOUND_MIXER_OGAIN, 17, 1, 6, 1, 0, 0, 0, 0, 8), + /* This is external wavetable */ + MIX_ENT2(SOUND_MIXER_LINE1, 22, 0, 4, 4, 23, 1, 1, 23, 0, 4, + 22, 0, 0, 4, 23, 1, 0, 23, 0, 5), }; static int default_mixer_levels[32] = { - 0x3232, /* Master Volume */ - 0x3232, /* Bass */ - 0x3232, /* Treble */ - 0x4b4b, /* FM */ - 0x3232, /* PCM */ - 0x1515, /* PC Speaker */ - 0x2020, /* Ext Line */ - 0x1010, /* Mic */ - 0x4b4b, /* CD */ - 0x0000, /* Recording monitor */ - 0x4b4b, /* Second PCM */ - 0x4b4b, /* Recording level */ - 0x4b4b, /* Input gain */ - 0x4b4b, /* Output gain */ - 0x2020, /* Line1 */ - 0x2020, /* Line2 */ - 0x1515 /* Line3 (usually line in)*/ + 0x3232, /* Master Volume */ + 0x3232, /* Bass */ + 0x3232, /* Treble */ + 0x4b4b, /* FM */ + 0x3232, /* PCM */ + 0x1515, /* PC Speaker */ + 0x2020, /* Ext Line */ + 0x1010, /* Mic */ + 0x4b4b, /* CD */ + 0x0000, /* Recording monitor */ + 0x4b4b, /* Second PCM */ + 0x4b4b, /* Recording level */ + 0x4b4b, /* Input gain */ + 0x4b4b, /* Output gain */ + 0x2020, /* Line1 */ + 0x2020, /* Line2 */ + 0x1515 /* Line3 (usually line in)*/ }; #define LEFT_CHN 0 diff -u --recursive --new-file v2.5.0/linux/drivers/sound/awe_wave.c linux/drivers/sound/awe_wave.c --- v2.5.0/linux/drivers/sound/awe_wave.c Sun Sep 30 12:26:08 2001 +++ linux/drivers/sound/awe_wave.c Sun Nov 25 09:43:42 2001 @@ -26,9 +26,7 @@ #include #include #include -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE #include -#endif #include "sound_config.h" @@ -205,7 +203,7 @@ int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */ int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */ -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ static int isapnp = -1; #else static int isapnp = 0; @@ -4772,7 +4770,7 @@ return 1; } -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ static struct { unsigned short card_vendor, card_device; unsigned short vendor; @@ -4841,7 +4839,7 @@ { int base; -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ if (isapnp) { if (awe_probe_isapnp(&io) < 0) { printk(KERN_ERR "AWE32: No ISAPnP cards found\n"); @@ -6132,7 +6130,7 @@ void __exit unload_awe(void) { _unload_awe(); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ if (isapnp) awe_deactivate_isapnp(); #endif /* isapnp */ diff -u --recursive --new-file v2.5.0/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c --- v2.5.0/linux/drivers/sound/cmpci.c Fri Nov 9 14:07:41 2001 +++ linux/drivers/sound/cmpci.c Sun Nov 25 10:17:47 2001 @@ -2496,7 +2496,6 @@ spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -2694,7 +2693,6 @@ outb(1, s->iosynth+3); /* enable OPL3 */ s->open_mode |= FMODE_DMFM; up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/sound/maestro3.c linux/drivers/sound/maestro3.c --- v2.5.0/linux/drivers/sound/maestro3.c Fri Nov 9 13:41:42 2001 +++ linux/drivers/sound/maestro3.c Sun Nov 25 10:17:47 2001 @@ -2036,7 +2036,6 @@ set_fmt(s, fmtm, fmts); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - MOD_INC_USE_COUNT; up(&s->open_sem); spin_unlock_irqrestore(&s->lock, flags); return 0; @@ -2075,7 +2074,6 @@ up(&s->open_sem); wake_up(&s->open_wait); - MOD_DEC_USE_COUNT; return 0; } @@ -2142,14 +2140,12 @@ int minor = MINOR(inode->i_rdev); struct m3_card *card = devs; - MOD_INC_USE_COUNT; for (card = devs; card != NULL; card = card->next) { if((card->ac97 != NULL) && (card->ac97->dev_mixer == minor)) break; } if (!card) { - MOD_DEC_USE_COUNT; return -ENODEV; } @@ -2160,7 +2156,6 @@ static int m3_release_mixdev(struct inode *inode, struct file *file) { - MOD_DEC_USE_COUNT; return 0; } @@ -2173,6 +2168,7 @@ } static struct file_operations m3_mixer_fops = { + owner: THIS_MODULE, llseek: no_llseek, ioctl: m3_ioctl_mixdev, open: m3_open_mixdev, @@ -2546,6 +2542,7 @@ } static struct file_operations m3_audio_fops = { + owner: THIS_MODULE, llseek: &no_llseek, read: &m3_read, write: &m3_write, diff -u --recursive --new-file v2.5.0/linux/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c --- v2.5.0/linux/drivers/sound/opl3sa2.c Thu Oct 11 09:43:30 2001 +++ linux/drivers/sound/opl3sa2.c Sun Nov 25 09:43:42 2001 @@ -99,7 +99,7 @@ #define CHIPSET_OPL3SA2 0 #define CHIPSET_OPL3SA3 1 -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ #define OPL3SA2_CARDS_MAX 4 #else #define OPL3SA2_CARDS_MAX 1 @@ -147,7 +147,7 @@ static int __initdata ymode = -1; static int __initdata loopback = -1; -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ /* PnP specific parameters */ static int __initdata isapnp = 1; static int __initdata multiple = 1; @@ -191,7 +191,7 @@ MODULE_PARM(loopback, "i"); MODULE_PARM_DESC(loopback, "Set A/D input source. Useful for echo cancellation (0 = Mic Rch (default), 1 = Mono output loopback)"); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ MODULE_PARM(isapnp, "i"); MODULE_PARM_DESC(isapnp, "When set to 0, ISA PnP support will be disabled"); @@ -807,7 +807,7 @@ } -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ struct isapnp_device_id isapnp_opl3sa2_list[] __initdata = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, @@ -888,7 +888,7 @@ return 0; } -#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */ +#endif /* __ISAPNP__ */ /* End of component functions */ @@ -909,9 +909,9 @@ max = (multiple && isapnp) ? OPL3SA2_CARDS_MAX : 1; for(card = 0; card < max; card++, opl3sa2_cards_num++) { -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ /* - * Please remember that even with CONFIG_ISAPNP defined one + * Please remember that even with __ISAPNP__ defined one * should still be able to disable PNP support for this * single driver! */ @@ -1039,7 +1039,7 @@ unload_opl3sa2_mss(&cfg_mss[card]); unload_opl3sa2(&cfg[card], card); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ if(opl3sa2_activated[card] && opl3sa2_dev[card]) { opl3sa2_dev[card]->deactivate(opl3sa2_dev[card]); @@ -1058,7 +1058,7 @@ static int __init setup_opl3sa2(char *str) { /* io, irq, dma, dma2,... */ -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ int ints[11]; #else int ints[9]; @@ -1073,7 +1073,7 @@ mpu_io = ints[6]; ymode = ints[7]; loopback = ints[8]; -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ isapnp = ints[9]; multiple = ints[10]; #endif diff -u --recursive --new-file v2.5.0/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c --- v2.5.0/linux/drivers/sound/sb_card.c Thu Oct 11 09:43:30 2001 +++ linux/drivers/sound/sb_card.c Sun Nov 25 09:43:42 2001 @@ -69,7 +69,7 @@ #include "sb_mixer.h" #include "sb.h" -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ #define SB_CARDS_MAX 5 #else #define SB_CARDS_MAX 1 @@ -196,7 +196,7 @@ *opl_dev[SB_CARDS_MAX] = {NULL}; -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ static int isapnp = 1; static int isapnpjump = 0; static int multiple = 1; @@ -226,7 +226,7 @@ MODULE_PARM(esstype, "i"); MODULE_PARM(acer, "i"); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ MODULE_PARM(isapnp, "i"); MODULE_PARM(isapnpjump, "i"); MODULE_PARM(multiple, "i"); @@ -251,7 +251,7 @@ MODULE_PARM_DESC(esstype, "ESS chip type"); MODULE_PARM_DESC(acer, "Set this to detect cards in some ACER notebooks"); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ /* Please add new entries at the end of the table */ static struct { @@ -909,8 +909,8 @@ printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n"); for(card = 0; card < max; card++, sb_cards_num++) { -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE - /* Please remember that even with CONFIG_ISAPNP defined one +#ifdef __ISAPNP__ + /* Please remember that even with __ISAPNP__ defined one * should still be able to disable PNP support for this * single driver! */ if((!pnplegacy||card>0) && isapnp && (sb_isapnp_probe(&cfg[card], &cfg_mpu[card], card) < 0) ) { @@ -997,7 +997,7 @@ if (sbmpu[i]) unload_sbmpu(&cfg_mpu[i]); -#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE +#ifdef __ISAPNP__ if(!audio_activated[i] && sb_dev[i]) sb_dev[i]->deactivate(sb_dev[i]); if(!mpu_activated[i] && mpu_dev[i]) diff -u --recursive --new-file v2.5.0/linux/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c --- v2.5.0/linux/drivers/sound/sound_core.c Sun Sep 30 12:26:08 2001 +++ linux/drivers/sound/sound_core.c Sun Nov 25 10:17:47 2001 @@ -115,7 +115,6 @@ *list=s; - MOD_INC_USE_COUNT; return n; } @@ -133,7 +132,6 @@ *list=p->next; devfs_unregister (p->de); kfree(p); - MOD_DEC_USE_COUNT; return; } list=&(p->next); diff -u --recursive --new-file v2.5.0/linux/drivers/sound/via82cxxx_audio.c linux/drivers/sound/via82cxxx_audio.c --- v2.5.0/linux/drivers/sound/via82cxxx_audio.c Fri Nov 9 13:45:35 2001 +++ linux/drivers/sound/via82cxxx_audio.c Mon Dec 10 10:39:20 2001 @@ -1,6 +1,6 @@ /* * Support for VIA 82Cxxx Audio Codecs - * Copyright 1999,2000 Jeff Garzik + * Copyright 1999,2000 Jeff Garzik * * Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2. * See the "COPYING" file distributed with this software for more info. @@ -8,9 +8,6 @@ * For a list of known bugs (errata) and documentation, * see via-audio.pdf in linux/Documentation/DocBook. * If this documentation does not exist, run "make pdfdocs". - * If "make pdfdocs" fails, obtain the documentation from - * the driver's Website at - * http://gtf.org/garzik/drivers/via82cxxx/ * */ @@ -3357,7 +3354,7 @@ module_init(init_via82cxxx_audio); module_exit(cleanup_via82cxxx_audio); -MODULE_AUTHOR("Jeff Garzik "); +MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("DSP audio and mixer driver for Via 82Cxxx audio devices"); MODULE_LICENSE("GPL"); diff -u --recursive --new-file v2.5.0/linux/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c --- v2.5.0/linux/drivers/sound/ymfpci.c Mon Nov 19 14:53:19 2001 +++ linux/drivers/sound/ymfpci.c Sun Nov 25 10:17:47 2001 @@ -1872,7 +1872,6 @@ #endif up(&unit->open_sem); - MOD_INC_USE_COUNT; return 0; out_nodma: @@ -1921,7 +1920,6 @@ up(&codec->open_sem); - MOD_DEC_USE_COUNT; return 0; } @@ -1949,7 +1947,6 @@ match: file->private_data = unit->ac97_codec[i]; - MOD_INC_USE_COUNT; return 0; } @@ -1963,11 +1960,11 @@ static int ymf_release_mixdev(struct inode *inode, struct file *file) { - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations ymf_fops = { + owner: THIS_MODULE, llseek: no_llseek, read: ymf_read, write: ymf_write, @@ -1979,6 +1976,7 @@ }; static /*const*/ struct file_operations ymf_mixer_fops = { + owner: THIS_MODULE, llseek: no_llseek, ioctl: ymf_ioctl_mixdev, open: ymf_open_mixdev, @@ -2043,13 +2041,6 @@ ymfpci_aclink_reset(unit->pci); ymfpci_codec_ready(unit, 0, 1); /* prints diag if not ready. */ - for (i = 0; i < NR_AC97; i++) { - codec = unit->ac97_codec[i]; - if (!codec) - continue; - ac97_restore_state(codec); - } - #ifdef CONFIG_SOUND_YMFPCI_LEGACY /* XXX At this time the legacy registers are probably deprogrammed. */ #endif @@ -2063,6 +2054,13 @@ if (unit->start_count) { ymfpci_writel(unit, YDSXGR_MODE, 3); unit->active_bank = ymfpci_readl(unit, YDSXGR_CTRLSELECT) & 1; + } + + for (i = 0; i < NR_AC97; i++) { + codec = unit->ac97_codec[i]; + if (!codec) + continue; + ac97_restore_state(codec); } unit->suspended = 0; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/CDCEther.c linux/drivers/usb/CDCEther.c --- v2.5.0/linux/drivers/usb/CDCEther.c Fri Oct 5 12:06:08 2001 +++ linux/drivers/usb/CDCEther.c Sat Dec 8 20:28:44 2001 @@ -82,9 +82,9 @@ ether_dev->flags |= CDC_ETHER_RX_BUSY; switch ( urb->status ) { - case USB_ST_NOERROR: + case 0: break; - case USB_ST_NORESPONSE: + case -ETIMEDOUT: dbg( "no repsonse in BULK IN" ); ether_dev->flags &= ~CDC_ETHER_RX_BUSY; break; @@ -179,9 +179,9 @@ // return; // // switch ( urb->status ) { -// case USB_ST_NOERROR: +// case 0: // break; -// case USB_ST_URB_KILLED: +// case -ENOENT: // return; // default: // info("intr status %d", urb->status); @@ -337,13 +337,9 @@ ether_dev_t *ether_dev = (ether_dev_t *)net->priv; int res; - // We are finally getting used! - MOD_INC_USE_COUNT; - // Turn on the USB and let the packets flow!!! if ( (res = enable_net_traffic( ether_dev )) ) { err( __FUNCTION__ "can't enable_net_traffic() - %d", res ); - MOD_DEC_USE_COUNT; return -EIO; } @@ -391,9 +387,6 @@ usb_unlink_urb( ðer_dev->tx_urb ); usb_unlink_urb( ðer_dev->intr_urb ); - // We are not being used now. - MOD_DEC_USE_COUNT; - // That's it. I'm done. return 0; } @@ -480,6 +473,7 @@ i++, mclist = mclist->next) { memcpy(&mclist->dmi_addr, &buff[i * 6], 6); } +#if 0 usb_control_msg(ether_dev->usb, usb_sndctrlpipe(ether_dev->usb, 0), SET_ETHERNET_MULTICAST_FILTER, /* request */ @@ -489,11 +483,13 @@ buff, (6* net->mc_count), /* size */ HZ); /* timeout */ +#endif kfree(buff); } - + +#if 0 CDC_SetEthernetPacketFilter(ether_dev); - +#endif // Tell the kernel to start giving frames to us again. netif_wake_queue(net); } @@ -1210,6 +1206,7 @@ // Now that we have an ethernet device, let's set it up // (And I don't mean "set [it] up the bomb".) net->priv = ether_dev; + SET_MODULE_OWNER(net); net->open = CDCEther_open; net->stop = CDCEther_close; net->watchdog_timeo = CDC_ETHER_TX_TIMEOUT; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/Config.in linux/drivers/usb/Config.in --- v2.5.0/linux/drivers/usb/Config.in Fri Nov 2 17:18:58 2001 +++ linux/drivers/usb/Config.in Sat Dec 8 20:28:44 2001 @@ -9,7 +9,7 @@ bool ' USB verbose debug messages' CONFIG_USB_DEBUG comment 'Miscellaneous USB options' - bool ' Preliminary USB device filesystem' CONFIG_USB_DEVICEFS + bool ' USB device filesystem' CONFIG_USB_DEVICEFS if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool ' Enforce USB bandwidth allocation (EXPERIMENTAL)' CONFIG_USB_BANDWIDTH else diff -u --recursive --new-file v2.5.0/linux/drivers/usb/audio.c linux/drivers/usb/audio.c --- v2.5.0/linux/drivers/usb/audio.c Fri Oct 5 12:04:50 2001 +++ linux/drivers/usb/audio.c Sat Dec 8 20:28:44 2001 @@ -899,7 +899,7 @@ struct usbin *u = &as->usbin; unsigned long flags; unsigned int mask; - int suret = USB_ST_NOERROR; + int suret = 0; #if 0 printk(KERN_DEBUG "usbin_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); @@ -917,7 +917,7 @@ if (!usbin_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbin_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) { + (suret = usb_submit_urb(urb)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -964,7 +964,7 @@ struct usbin *u = &as->usbin; unsigned long flags; unsigned int mask; - int suret = USB_ST_NOERROR; + int suret = 0; #if 0 printk(KERN_DEBUG "usbin_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); @@ -982,7 +982,7 @@ if (!usbin_sync_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbin_sync_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) { + (suret = usb_submit_urb(urb)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -1257,7 +1257,7 @@ struct usbout *u = &as->usbout; unsigned long flags; unsigned int mask; - int suret = USB_ST_NOERROR; + int suret = 0; #if 0 printk(KERN_DEBUG "usbout_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); @@ -1275,7 +1275,7 @@ if (!usbout_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbout_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) { + (suret = usb_submit_urb(urb)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -1329,7 +1329,7 @@ struct usbout *u = &as->usbout; unsigned long flags; unsigned int mask; - int suret = USB_ST_NOERROR; + int suret = 0; #if 0 printk(KERN_DEBUG "usbout_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); @@ -1347,7 +1347,7 @@ if (!usbout_sync_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbout_sync_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) { + (suret = usb_submit_urb(urb)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -3362,28 +3362,48 @@ struct usb_device *dev = state->s->usbdev; unsigned char data[1]; #endif + unsigned char nr_logical_channels, i; usb_audio_recurseunit(state, ftr[4]); + + if (ftr[5] == 0 ) { + printk(KERN_ERR "usbaudio: wrong controls size in feature unit %u\n",ftr[3]); + return; + } + if (state->nrchannels == 0) { printk(KERN_ERR "usbaudio: feature unit %u source has no channels\n", ftr[3]); return; } if (state->nrchannels > 2) printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]); - if (state->nrchannels == 1 && ftr[0] == 7+ftr[5]) { - printk(KERN_DEBUG "usbaudio: workaround for Philips camera microphone descriptor enabled\n"); - mchftr = ftr[6]; - chftr = 0; - } else { - if (ftr[0] < 7+ftr[5]*(1+state->nrchannels)) { - printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", ftr[3]); - return; + + nr_logical_channels=(ftr[0]-7)/ftr[5]-1; + + if (nr_logical_channels != state->nrchannels) { + printk(KERN_WARNING "usbaudio: warning: found %d of %d logical channels.\n", state->nrchannels,nr_logical_channels); + + if (state->nrchannels == 1 && nr_logical_channels==0) { + printk(KERN_INFO "usbaudio: assuming the channel found is the master channel (got a Philips camera?). Should be fine.\n"); + } else if (state->nrchannels == 1 && nr_logical_channels==2) { + printk(KERN_INFO "usbaudio: assuming that a stereo channel connected directly to a mixer is missing in search (got Labtec headset?). Should be fine.\n"); + state->nrchannels=nr_logical_channels; + } else { + printk(KERN_WARNING "usbaudio: no idea what's going on..., contact linux-usb-devel@lists.sourceforge.net\n"); } - mchftr = ftr[6]; + } + + /* There is always a master channel */ + mchftr = ftr[6]; + /* Binary AND over logical channels if they exist */ + if (nr_logical_channels) { chftr = ftr[6+ftr[5]]; - if (state->nrchannels > 1) - chftr &= ftr[6+2*ftr[5]]; + for (i = 2; i <= nr_logical_channels; i++) + chftr &= ftr[6+i*ftr[5]]; + } else { + chftr = 0; } + /* volume control */ if (chftr & 2) { ch = getmixchannel(state, getvolchannel(state)); diff -u --recursive --new-file v2.5.0/linux/drivers/usb/bluetooth.c linux/drivers/usb/bluetooth.c --- v2.5.0/linux/drivers/usb/bluetooth.c Tue Nov 13 09:19:41 2001 +++ linux/drivers/usb/bluetooth.c Sat Dec 8 20:28:44 2001 @@ -1,11 +1,15 @@ /* - * bluetooth.c Version 0.12 + * bluetooth.c Version 0.13 * * Copyright (c) 2000, 2001 Greg Kroah-Hartman * Copyright (c) 2000 Mark Douglas Corner * * USB Bluetooth driver, based on the Bluetooth Spec version 1.0B * + * (2001/11/30) Version 0.13 gkh + * - added locking patch from Masoodur Rahman + * - removed active variable, as open_count will do. + * * (2001/07/09) Version 0.12 gkh * - removed in_interrupt() call, as it doesn't make sense to do * that anymore. @@ -118,7 +122,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.12" +#define DRIVER_VERSION "v0.13" #define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner" #define DRIVER_DESC "USB Bluetooth tty driver" @@ -170,8 +174,8 @@ struct tty_struct * tty; /* the coresponding tty for this port */ unsigned char minor; /* the starting minor number for this device */ - char active; /* someone has this device open */ int throttle; /* throttled by tty layer */ + int open_count; __u8 control_out_bInterfaceNum; struct urb * control_urb_pool[NUM_CONTROL_URBS]; @@ -200,6 +204,7 @@ unsigned char int_buffer[EVENT_BUFFER_SIZE]; unsigned int bulk_packet_pos; unsigned char bulk_buffer[ACL_BUFFER_SIZE]; /* 64k preallocated, fix? */ + struct semaphore lock; }; @@ -361,43 +366,46 @@ return -ENODEV; } - if (bluetooth->active) { - dbg (__FUNCTION__ " - device already open"); - return -EINVAL; - } - - /* set up our structure making the tty driver remember our object, and us it */ - tty->driver_data = bluetooth; - bluetooth->tty = tty; - - /* force low_latency on so that our tty_push actually forces the data through, - * otherwise it is scheduled, and with high data rates (like with OHCI) data - * can get lost. */ - bluetooth->tty->low_latency = 1; + down (&bluetooth->lock); + + ++bluetooth->open_count; + if (bluetooth->open_count == 1) { + /* set up our structure making the tty driver remember our object, and us it */ + tty->driver_data = bluetooth; + bluetooth->tty = tty; + + /* force low_latency on so that our tty_push actually forces the data through, + * otherwise it is scheduled, and with high data rates (like with OHCI) data + * can get lost. */ + bluetooth->tty->low_latency = 1; - bluetooth->active = 1; - - /* Reset the packet position counters */ - bluetooth->int_packet_pos = 0; - bluetooth->bulk_packet_pos = 0; + /* Reset the packet position counters */ + bluetooth->int_packet_pos = 0; + bluetooth->bulk_packet_pos = 0; #ifndef BTBUGGYHARDWARE - /* Start reading from the device */ - FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, - usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), - bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, - bluetooth_read_bulk_callback, bluetooth); - result = usb_submit_urb(bluetooth->read_urb); - if (result) - dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result); + /* Start reading from the device */ + FILL_BULK_URB (bluetooth->read_urb, bluetooth->dev, + usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), + bluetooth->bulk_in_buffer, + bluetooth->bulk_in_buffer_size, + bluetooth_read_bulk_callback, bluetooth); + result = usb_submit_urb(bluetooth->read_urb); + if (result) + dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result); #endif - FILL_INT_URB(bluetooth->interrupt_in_urb, bluetooth->dev, - usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress), - bluetooth->interrupt_in_buffer, bluetooth->interrupt_in_buffer_size, - bluetooth_int_callback, bluetooth, bluetooth->interrupt_in_interval); - result = usb_submit_urb(bluetooth->interrupt_in_urb); - if (result) - dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result); + FILL_INT_URB (bluetooth->interrupt_in_urb, bluetooth->dev, + usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress), + bluetooth->interrupt_in_buffer, + bluetooth->interrupt_in_buffer_size, + bluetooth_int_callback, bluetooth, + bluetooth->interrupt_in_interval); + result = usb_submit_urb(bluetooth->interrupt_in_urb); + if (result) + dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result); + } + + up(&bluetooth->lock); return 0; } @@ -414,18 +422,24 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not opened"); return; } - /* shutdown any bulk reads and writes that might be going on */ - for (i = 0; i < NUM_BULK_URBS; ++i) - usb_unlink_urb (bluetooth->write_urb_pool[i]); - usb_unlink_urb (bluetooth->read_urb); - usb_unlink_urb (bluetooth->interrupt_in_urb); - - bluetooth->active = 0; + down (&bluetooth->lock); + + --bluetooth->open_count; + if (bluetooth->open_count <= 0) { + bluetooth->open_count = 0; + + /* shutdown any bulk reads and writes that might be going on */ + for (i = 0; i < NUM_BULK_URBS; ++i) + usb_unlink_urb (bluetooth->write_urb_pool[i]); + usb_unlink_urb (bluetooth->read_urb); + usb_unlink_urb (bluetooth->interrupt_in_urb); + } + up(&bluetooth->lock); } @@ -447,7 +461,7 @@ dbg(__FUNCTION__ " - %d byte(s)", count); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not opened"); return -EINVAL; } @@ -572,7 +586,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return -EINVAL; } @@ -598,7 +612,7 @@ return -ENODEV; } - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return -EINVAL; } @@ -624,7 +638,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return; } @@ -645,7 +659,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return; } @@ -664,7 +678,7 @@ dbg(__FUNCTION__ " - cmd 0x%.4x", cmd); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return -ENODEV; } @@ -684,7 +698,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return; } @@ -706,7 +720,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return; } @@ -731,7 +745,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return; } @@ -961,7 +975,7 @@ } exit: - if (!bluetooth || !bluetooth->active) + if (!bluetooth || !bluetooth->open_count) return; FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, @@ -1102,6 +1116,7 @@ bluetooth->minor = minor; bluetooth->tqueue.routine = bluetooth_softint; bluetooth->tqueue.data = bluetooth; + init_MUTEX(&bluetooth->lock); /* record the interface number for the control out */ bluetooth->control_out_bInterfaceNum = control_out_endpoint; @@ -1217,10 +1232,10 @@ int i; if (bluetooth) { - if ((bluetooth->active) && (bluetooth->tty)) + if ((bluetooth->open_count) && (bluetooth->tty)) tty_hangup(bluetooth->tty); - bluetooth->active = 0; + bluetooth->open_count = 0; if (bluetooth->read_urb) { usb_unlink_urb (bluetooth->read_urb); diff -u --recursive --new-file v2.5.0/linux/drivers/usb/dabusb.c linux/drivers/usb/dabusb.c --- v2.5.0/linux/drivers/usb/dabusb.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/dabusb.c Fri Nov 30 08:26:04 2001 @@ -224,7 +224,7 @@ err("kmalloc(sizeof(buff_t))==NULL"); goto err; } - memset (b, sizeof (buff_t), 0); + memset (b, 0, sizeof (buff_t)); b->s = s; b->purb = usb_alloc_urb(packets); if (!b->purb) { @@ -622,7 +622,6 @@ dbg("dabusb_release"); - lock_kernel(); down (&s->mutex); dabusb_stop (s); dabusb_free_buffers (s); @@ -636,7 +635,6 @@ wake_up (&s->remove_ok); s->opened = 0; - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/dc2xx.c linux/drivers/usb/dc2xx.c --- v2.5.0/linux/drivers/usb/dc2xx.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/dc2xx.c Sat Dec 8 20:28:45 2001 @@ -112,12 +112,15 @@ /* These have a different application level protocol which * is part of the Flashpoint "DigitaOS". That supports some * non-camera devices, and some non-Kodak cameras. + * Use this driver to get USB and "OpenDis" to talk. */ { USB_DEVICE(0x040a, 0x0100) }, // Kodak DC-220 { USB_DEVICE(0x040a, 0x0110) }, // Kodak DC-260 { USB_DEVICE(0x040a, 0x0111) }, // Kodak DC-265 { USB_DEVICE(0x040a, 0x0112) }, // Kodak DC-290 { USB_DEVICE(0xf003, 0x6002) }, // HP PhotoSmart C500 + { USB_DEVICE(0x03f0, 0x4102) }, // HP PhotoSmart C618 + { USB_DEVICE(0x0a17, 0x1001) }, // Pentax EI-200 /* Other USB devices may well work here too, so long as they * just stick to half duplex bulk packet exchanges. That @@ -196,7 +199,7 @@ retval = count; break; } - if (retval != USB_ST_TIMEOUT) + if (retval != -ETIMEDOUT) break; interruptible_sleep_on_timeout (&camera->wait, RETRY_TIMEOUT); @@ -264,7 +267,7 @@ } else if (!result) break; - if (result == USB_ST_TIMEOUT) { /* NAK - delay a bit */ + if (result == -ETIMEDOUT) { /* NAK - delay a bit */ if (!maxretry--) { if (!bytes_written) bytes_written = -ETIME; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/devices.c linux/drivers/usb/devices.c --- v2.5.0/linux/drivers/usb/devices.c Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/devices.c Sat Dec 8 20:25:02 2001 @@ -139,9 +139,12 @@ {USB_CLASS_PHYSICAL, "PID"}, {USB_CLASS_PRINTER, "print"}, {USB_CLASS_MASS_STORAGE, "stor."}, - {USB_CLASS_DATA, "data"}, + {USB_CLASS_CDC_DATA, "data"}, {USB_CLASS_APP_SPEC, "app."}, {USB_CLASS_VENDOR_SPEC, "vend."}, + {USB_CLASS_STILL_IMAGE, "still"}, + {USB_CLASS_CSCID, "scard"}, + {USB_CLASS_CONTENT_SEC, "c-sec"}, {-1, "unk."} /* leave as last */ }; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/devio.c linux/drivers/usb/devio.c --- v2.5.0/linux/drivers/usb/devio.c Fri Nov 2 17:18:58 2001 +++ linux/drivers/usb/devio.c Sat Dec 8 20:28:44 2001 @@ -276,7 +276,7 @@ list_del(&as->asynclist); INIT_LIST_HEAD(&as->asynclist); spin_unlock_irqrestore(&ps->lock, flags); - /* usb_unlink_urb calls the completion handler with status == USB_ST_URB_KILLED */ + /* usb_unlink_urb calls the completion handler with status == -ENOENT */ usb_unlink_urb(&as->urb); spin_lock_irqsave(&ps->lock, flags); } @@ -299,11 +299,12 @@ { struct dev_state *ps = (struct dev_state *)context; - ps->ifclaimed = 0; + if (ps) + ps->ifclaimed = 0; } struct usb_driver usbdevfs_driver = { - name: "usbdevfs", + name: "usbfs", probe: driver_probe, disconnect: driver_disconnect, }; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/hid-core.c linux/drivers/usb/hid-core.c --- v2.5.0/linux/drivers/usb/hid-core.c Sun Sep 16 11:07:43 2001 +++ linux/drivers/usb/hid-core.c Sat Dec 8 20:28:45 2001 @@ -897,7 +897,7 @@ u8 data[len]; int read; - if ((read = usb_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, data, len)) != len) { + if ((read = hid_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, data, len)) != len) { dbg("reading report type %d id %d failed len %d read %d", report->type + 1, report->id, len, read); return; } @@ -1064,7 +1064,7 @@ list = report_enum->report_list.next; while (list != &report_enum->report_list) { report = (struct hid_report *) list; - usb_set_idle(hid->dev, hid->ifnum, 0, report->id); + hid_set_idle(hid->dev, hid->ifnum, 0, report->id); hid_read_report(hid, report); list = list->next; } @@ -1089,6 +1089,16 @@ { 0, 0 } }; +static int get_class_descriptor(struct usb_device *dev, int ifnum, + unsigned char type, void *buf, int size) +{ + return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, + (type << 8), ifnum, buf, size, + HZ * USB_CTRL_GET_TIMEOUT); +} + + static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum) { struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0; @@ -1102,14 +1112,14 @@ if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) && (hid_blacklist[n].idProduct == dev->descriptor.idProduct)) return NULL; - if (usb_get_extra_descriptor(interface, USB_DT_HID, &hdesc) && ((!interface->bNumEndpoints) || - usb_get_extra_descriptor(&interface->endpoint[0], USB_DT_HID, &hdesc))) { + if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->bNumEndpoints) || + usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { dbg("class descriptor not present\n"); return NULL; } for (n = 0; n < hdesc->bNumDescriptors; n++) - if (hdesc->desc[n].bDescriptorType == USB_DT_REPORT) + if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { @@ -1120,7 +1130,7 @@ { __u8 rdesc[rsize]; - if ((n = usb_get_class_descriptor(dev, interface->bInterfaceNumber, USB_DT_REPORT, 0, rdesc, rsize)) < 0) { + if ((n = get_class_descriptor(dev, interface->bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { dbg("reading report descriptor failed"); return NULL; } @@ -1170,7 +1180,7 @@ for (n = 0; n < HID_CONTROL_FIFO_SIZE; n++) { hid->out[n].dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE; - hid->out[n].dr.request = USB_REQ_SET_REPORT; + hid->out[n].dr.request = HID_REQ_SET_REPORT; hid->out[n].dr.index = cpu_to_le16(hid->ifnum); } @@ -1198,7 +1208,7 @@ #if 0 if (interface->bInterfaceSubClass == 1) - usb_set_protocol(dev, hid->ifnum, 1); + hid_set_protocol(dev, hid->ifnum, 1); #endif return hid; @@ -1236,7 +1246,7 @@ c = "Device"; for (i = 0; i < hid->maxapplication; i++) - if (IS_INPUT_APPLICATION(hid->application[i])) { + if ((hid->application[i] & 0xffff) < ARRAY_SIZE(hid_types)) { c = hid_types[hid->application[i] & 0xffff]; break; } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/hid.h linux/drivers/usb/hid.h --- v2.5.0/linux/drivers/usb/hid.h Tue Nov 13 17:45:27 2001 +++ linux/drivers/usb/hid.h Sat Dec 8 20:28:45 2001 @@ -30,6 +30,88 @@ * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic */ +/* + * HID class requests + */ +#define HID_REQ_GET_REPORT 0x01 +#define HID_REQ_GET_IDLE 0x02 +#define HID_REQ_GET_PROTOCOL 0x03 +#define HID_REQ_SET_REPORT 0x09 +#define HID_REQ_SET_IDLE 0x0A +#define HID_REQ_SET_PROTOCOL 0x0B + +/* + * HID class descriptor types + */ +#define HID_DT_HID (USB_TYPE_CLASS | 0x01) +#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02) +#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) + +/* + * Utilities for class control messaging + */ +static inline int +hid_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id) +{ + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (duration << 8) | report_id, ifnum, NULL, 0, + HZ * USB_CTRL_SET_TIMEOUT); +} + +static inline int +hid_get_protocol(struct usb_device *dev, int ifnum) +{ + unsigned char type; + int ret; + + if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + HID_REQ_GET_PROTOCOL, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, ifnum, &type, 1, + HZ * USB_CTRL_GET_TIMEOUT)) < 0) + return ret; + + return type; +} + +static inline int +hid_set_protocol(struct usb_device *dev, int ifnum, int protocol) +{ + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + HID_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + protocol, ifnum, NULL, 0, + HZ * USB_CTRL_SET_TIMEOUT); +} + +static inline int +hid_get_report(struct usb_device *dev, int ifnum, unsigned char type, + unsigned char id, void *buf, int size) +{ + return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + HID_REQ_GET_REPORT, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (type << 8) + id, ifnum, buf, size, + HZ * USB_CTRL_GET_TIMEOUT); +} + +static inline int +hid_set_report(struct usb_device *dev, int ifnum, unsigned char type, + unsigned char id, void *buf, int size) +{ + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + HID_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (type << 8) + id, ifnum, buf, size, HZ); + // FIXME USB_CTRL_SET_TIMEOUT +} + + +/* + * "Boot Protocol" keyboard/mouse drivers use don't use all of HID; + * they're a lot smaller but can't support all the device features. + */ +#ifndef _HID_BOOT_PROTOCOL + #include #include #include @@ -359,9 +441,7 @@ #else #define hid_dump_input(a,b) do { } while (0) #define hid_dump_device(c) do { } while (0) -#endif - -#endif +#endif /* DEBUG */ #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || ( a == 0x000c0001)) @@ -372,3 +452,8 @@ void hid_write_report(struct hid_device *, struct hid_report *); void hid_read_report(struct hid_device *, struct hid_report *); void hid_init_reports(struct hid_device *hid); + +#endif /* !_HID_BOOT_PROTOCOL */ + +#endif /* !__HID_H */ + diff -u --recursive --new-file v2.5.0/linux/drivers/usb/hiddev.c linux/drivers/usb/hiddev.c --- v2.5.0/linux/drivers/usb/hiddev.c Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/hiddev.c Fri Nov 30 08:26:04 2001 @@ -193,7 +193,6 @@ struct hiddev_list *list = file->private_data; struct hiddev_list **listptr; - lock_kernel(); listptr = &list->hiddev->list; hiddev_fasync(-1, file, 0); @@ -209,7 +208,6 @@ } kfree(list); - unlock_kernel(); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/hpusbscsi.h linux/drivers/usb/hpusbscsi.h --- v2.5.0/linux/drivers/usb/hpusbscsi.h Fri Oct 5 12:04:51 2001 +++ linux/drivers/usb/hpusbscsi.h Wed Nov 28 10:22:27 2001 @@ -73,7 +73,6 @@ present: 0, unchecked_isa_dma: FALSE, use_clustering: TRUE, - use_new_eh_code: TRUE, emulated: TRUE }; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/inode.c linux/drivers/usb/inode.c --- v2.5.0/linux/drivers/usb/inode.c Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/inode.c Sat Dec 8 20:28:44 2001 @@ -654,7 +654,13 @@ return NULL; } +/* + * The usbdevfs name is now depreciated (as of 2.5.1). + * It will be removed when the 2.7.x development cycle is started. + * You have been warned :) + */ static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, FS_SINGLE); +static DECLARE_FSTYPE(usb_fs_type, "usbfs", usbdevfs_read_super, FS_SINGLE); /* --------------------------------------------------------------------- */ @@ -747,7 +753,12 @@ } if ((ret = usb_register(&usbdevfs_driver))) return ret; + if ((ret = register_filesystem(&usb_fs_type))) { + usb_deregister(&usbdevfs_driver); + return ret; + } if ((ret = register_filesystem(&usbdevice_fs_type))) { + unregister_filesystem(&usb_fs_type); usb_deregister(&usbdevfs_driver); return ret; } @@ -761,6 +772,7 @@ void __exit usbdevfs_cleanup(void) { usb_deregister(&usbdevfs_driver); + unregister_filesystem(&usb_fs_type); unregister_filesystem(&usbdevice_fs_type); #ifdef CONFIG_PROC_FS if (usbdir) @@ -768,7 +780,3 @@ #endif } -#if 0 -module_init(usbdevfs_init); -module_exit(usbdevfs_cleanup); -#endif diff -u --recursive --new-file v2.5.0/linux/drivers/usb/kaweth.c linux/drivers/usb/kaweth.c --- v2.5.0/linux/drivers/usb/kaweth.c Tue Nov 13 09:19:41 2001 +++ linux/drivers/usb/kaweth.c Sat Dec 8 20:28:45 2001 @@ -944,6 +944,13 @@ } +// FIXME this completion stuff is a modified clone of +// an OLD version of some stuff in usb.c ... +struct usb_api_data { + wait_queue_head_t wqh; + int done; +}; + /*-------------------------------------------------------------------* * completion handler for compatibility wrappers (sync control/bulk) * *-------------------------------------------------------------------*/ diff -u --recursive --new-file v2.5.0/linux/drivers/usb/mdc800.c linux/drivers/usb/mdc800.c --- v2.5.0/linux/drivers/usb/mdc800.c Tue Oct 9 15:15:02 2001 +++ linux/drivers/usb/mdc800.c Sat Dec 8 20:28:44 2001 @@ -30,8 +30,14 @@ * * The driver supports only one camera. * - * (08/04/2001) gb + * Fix: mdc800 used sleep_on and slept with io_lock held. + * Converted sleep_on to waitqueues with schedule_timeout and made io_lock + * a semaphore from a spinlock. + * by Oliver Neukum <520047054719-0001@t-online.de> + * (02/12/2001) + * * Identify version on module load. + * (08/04/2001) gb * * version 0.7.5 * Fixed potential SMP races with Spinlocks. @@ -136,6 +142,7 @@ purb_t irq_urb; wait_queue_head_t irq_wait; + int irq_woken; char* irq_urb_buffer; int camera_busy; // is camera busy ? @@ -145,11 +152,13 @@ purb_t write_urb; char* write_urb_buffer; wait_queue_head_t write_wait; + int written; purb_t download_urb; char* download_urb_buffer; wait_queue_head_t download_wait; + int downloaded; int download_left; // Bytes left to download ? @@ -159,7 +168,7 @@ int out_count; // Bytes in the buffer int open; // Camera device open ? - spinlock_t io_lock; // IO -lock + struct semaphore io_lock; // IO -lock char in [8]; // Command Input Buffer int in_count; @@ -284,6 +293,7 @@ if (wake_up) { mdc800->camera_request_ready=0; + mdc800->irq_woken=1; wake_up_interruptible (&mdc800->irq_wait); } } @@ -300,9 +310,19 @@ */ static int mdc800_usb_waitForIRQ (int mode, int msec) { + DECLARE_WAITQUEUE(wait, current); + mdc800->camera_request_ready=1+mode; - interruptible_sleep_on_timeout (&mdc800->irq_wait, msec*HZ/1000); + add_wait_queue(&mdc800->irq_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + if (!mdc800->irq_woken) + { + schedule_timeout (msec*HZ/1000); + } + remove_wait_queue(&mdc800->irq_wait, &wait); + set_current_state(TASK_RUNNING); + mdc800->irq_woken = 0; if (mdc800->camera_request_ready>0) { @@ -337,6 +357,7 @@ { mdc800->state=READY; } + mdc800->written = 1; wake_up_interruptible (&mdc800->write_wait); } @@ -364,6 +385,7 @@ { err ("request bytes fails (status:%i)", urb->status); } + mdc800->downloaded = 1; wake_up_interruptible (&mdc800->download_wait); } @@ -445,7 +467,7 @@ info ("Found Mustek MDC800 on USB."); - spin_lock (&mdc800->io_lock); + down (&mdc800->io_lock); mdc800->dev=dev; mdc800->open=0; @@ -484,7 +506,7 @@ mdc800->state=READY; - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return mdc800; } @@ -558,7 +580,7 @@ int retval=0; int errn=0; - spin_lock (&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) { @@ -594,7 +616,7 @@ dbg ("Mustek MDC800 device opened."); error_out: - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return errn; } @@ -607,10 +629,9 @@ int retval=0; dbg ("Mustek MDC800 device closed."); - spin_lock (&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->open && (mdc800->state != NOT_CONNECTED)) { - spin_unlock(&mdc800->io_lock); usb_unlink_urb (mdc800->irq_urb); usb_unlink_urb (mdc800->write_urb); usb_unlink_urb (mdc800->download_urb); @@ -618,11 +639,10 @@ } else { - spin_unlock (&mdc800->io_lock); retval=-EIO; } - + up(&mdc800->io_lock); return retval; } @@ -634,22 +654,23 @@ { int left=len, sts=len; /* single transfer size */ char* ptr=buf; + DECLARE_WAITQUEUE(wait, current); - spin_lock (&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } if (mdc800->state == WORKING) { warn ("Illegal State \"working\" reached during read ?!"); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } if (!mdc800->open) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } @@ -657,7 +678,7 @@ { if (signal_pending (current)) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EINTR; } @@ -676,21 +697,29 @@ if (usb_submit_urb (mdc800->download_urb)) { err ("Can't submit download urb (status=%i)",mdc800->download_urb->status); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return len-left; } - interruptible_sleep_on_timeout (&mdc800->download_wait, TO_DOWNLOAD_GET_READY*HZ/1000); + add_wait_queue(&mdc800->download_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + if (!mdc800->downloaded) + { + schedule_timeout (TO_DOWNLOAD_GET_READY*HZ/1000); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&mdc800->download_wait, &wait); + mdc800->downloaded = 0; if (mdc800->download_urb->status != 0) { err ("request download-bytes fails (status=%i)",mdc800->download_urb->status); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return len-left; } } else { /* No more bytes -> that's an error*/ - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } } @@ -704,7 +733,7 @@ } } - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return len-left; } @@ -718,16 +747,17 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t len, loff_t *pos) { int i=0; + DECLARE_WAITQUEUE(wait, current); - spin_lock (&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->state != READY) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } if (!mdc800->open ) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } @@ -735,7 +765,7 @@ { if (signal_pending (current)) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EINTR; } @@ -757,7 +787,7 @@ else { err ("Command is to long !\n"); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -769,7 +799,7 @@ if (mdc800_usb_waitForIRQ (0,TO_GET_READY)) { err ("Camera didn't get ready.\n"); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -781,14 +811,22 @@ if (usb_submit_urb (mdc800->write_urb)) { err ("submitting write urb fails (status=%i)", mdc800->write_urb->status); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } - interruptible_sleep_on_timeout (&mdc800->write_wait, TO_WRITE_GET_READY*HZ/1000); + add_wait_queue(&mdc800->write_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + if (!mdc800->written) + { + schedule_timeout (TO_WRITE_GET_READY*HZ/1000); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&mdc800->write_wait, &wait); + mdc800->written = 0; if (mdc800->state == WORKING) { usb_unlink_urb (mdc800->write_urb); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -800,7 +838,7 @@ { err ("call 0x07 before 0x05,0x3e"); mdc800->state=READY; - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } mdc800->pic_len=-1; @@ -819,7 +857,7 @@ if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ)) { err ("requesting answer from irq fails"); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -847,7 +885,7 @@ if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND)) { err ("Command Timeout."); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } } @@ -857,7 +895,7 @@ } i++; } - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return i; } @@ -916,11 +954,15 @@ mdc800->dev=0; mdc800->open=0; mdc800->state=NOT_CONNECTED; - spin_lock_init (&mdc800->io_lock); + init_MUTEX (&mdc800->io_lock); init_waitqueue_head (&mdc800->irq_wait); init_waitqueue_head (&mdc800->write_wait); init_waitqueue_head (&mdc800->download_wait); + + mdc800->irq_woken = 0; + mdc800->downloaded = 0; + mdc800->written = 0; try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL)); try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL)); diff -u --recursive --new-file v2.5.0/linux/drivers/usb/microtek.c linux/drivers/usb/microtek.c --- v2.5.0/linux/drivers/usb/microtek.c Fri Oct 5 12:04:51 2001 +++ linux/drivers/usb/microtek.c Wed Nov 28 10:22:27 2001 @@ -760,7 +760,6 @@ present: 0, unchecked_isa_dma: FALSE, use_clustering: TRUE, - use_new_eh_code: TRUE, emulated: TRUE }; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/pegasus.c linux/drivers/usb/pegasus.c --- v2.5.0/linux/drivers/usb/pegasus.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/pegasus.c Sat Dec 8 20:25:02 2001 @@ -53,7 +53,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.4.21 (2001/08/27)" +#define DRIVER_VERSION "v0.4.22 (2001/12/07)" #define DRIVER_AUTHOR "Petko Manolov " #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" @@ -102,7 +102,7 @@ return; switch ( urb->status ) { - case USB_ST_NOERROR: + case 0: if ( pegasus->flags & ETH_REGS_CHANGE ) { pegasus->flags &= ~ETH_REGS_CHANGE; pegasus->flags |= ETH_REGS_CHANGED; @@ -110,9 +110,9 @@ return; } break; - case USB_ST_URB_PENDING: + case -EINPROGRESS: return; - case USB_ST_URB_KILLED: + case -ENOENT: break; default: warn( __FUNCTION__ " status %d", urb->status); @@ -526,9 +526,9 @@ pegasus->flags |= PEGASUS_RX_BUSY; switch ( urb->status ) { - case USB_ST_NOERROR: + case 0: break; - case USB_ST_NORESPONSE: + case -ETIMEDOUT: dbg( "reset MAC" ); pegasus->flags &= ~PEGASUS_RX_BUSY; break; @@ -607,9 +607,9 @@ return; switch ( urb->status ) { - case USB_ST_NOERROR: + case 0: break; - case USB_ST_URB_KILLED: + case -ENOENT: return; default: info("intr status %d", urb->status); @@ -713,10 +713,8 @@ pegasus_t *pegasus = (pegasus_t *)net->priv; int res; - MOD_INC_USE_COUNT; if ( (res = enable_net_traffic(net, pegasus->usb)) ) { err("can't enable_net_traffic() - %d", res); - MOD_DEC_USE_COUNT; return -EIO; } FILL_BULK_URB( &pegasus->rx_urb, pegasus->usb, @@ -755,7 +753,6 @@ #ifdef PEGASUS_USE_INTR usb_unlink_urb( &pegasus->intr_urb ); #endif - MOD_DEC_USE_COUNT; return 0; } @@ -867,6 +864,7 @@ pegasus->usb = dev; pegasus->net = net; + SET_MODULE_OWNER(net); net->priv = pegasus; net->open = pegasus_open; net->stop = pegasus_close; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/pegasus.h linux/drivers/usb/pegasus.h --- v2.5.0/linux/drivers/usb/pegasus.h Wed Oct 17 14:34:06 2001 +++ linux/drivers/usb/pegasus.h Sat Dec 8 20:25:02 2001 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@dce.bg) + * Copyright (c) 1999,2000 Petko Manolov - Petkan (pmanolov@lnxw.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -138,6 +138,7 @@ #define VENDOR_DLINK 0x2001 #define VENDOR_ELSA 0x05cc #define VENDOR_IODATA 0x04bb +#define VENDOR_KINGSTON 0x0951 #define VENDOR_LANEED 0x056e #define VENDOR_LINKSYS 0x066b #define VENDOR_MELCO 0x0411 @@ -210,6 +211,8 @@ DEFAULT_GPIO_RESET ) PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, DEFAULT_GPIO_RESET ) +PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a, + DEFAULT_GPIO_RESET) PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b, diff -u --recursive --new-file v2.5.0/linux/drivers/usb/pwc-ctrl.c linux/drivers/usb/pwc-ctrl.c --- v2.5.0/linux/drivers/usb/pwc-ctrl.c Wed Oct 17 14:34:06 2001 +++ linux/drivers/usb/pwc-ctrl.c Mon Nov 26 17:09:10 2001 @@ -782,7 +782,7 @@ { char buf; - if (pdev->type < 675 || pdev->release < 6) + if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6)) return 0; /* Not supported by Nala or Timon < release 6 */ if (power) diff -u --recursive --new-file v2.5.0/linux/drivers/usb/pwc-if.c linux/drivers/usb/pwc-if.c --- v2.5.0/linux/drivers/usb/pwc-if.c Wed Oct 17 14:34:06 2001 +++ linux/drivers/usb/pwc-if.c Mon Nov 26 17:09:10 2001 @@ -91,6 +91,8 @@ disconnect: usb_pwc_disconnect, /* disconnect() */ }; +#define MAX_DEV_HINTS 10 + static int default_size = PSZ_QCIF; static int default_fps = 10; static int default_palette = VIDEO_PALETTE_YUV420P; /* This format is understood by most tools */ @@ -99,13 +101,17 @@ int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX; static int power_save = 0; static int led_on = 1, led_off = 0; /* defaults to LED that is on while in use */ -int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */ + int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */ +static struct { + int type; + char serial_number[30]; + int device_node; + struct pwc_device *pdev; +} device_hint[MAX_DEV_HINTS]; static struct semaphore mem_lock; static void *mem_leak = NULL; /* For delayed kfree()s. See below */ -static int video_nr = -1; - /***/ static int pwc_video_open(struct video_device *vdev, int mode); @@ -647,7 +653,8 @@ errmsg = "Unknown"; switch(urb->status) { case -ENOSR: errmsg = "Buffer error (overrun)"; break; - case -EPIPE: errmsg = "Babble/stalled (bad cable?)"; break; + case -EPIPE: errmsg = "Stalled (device not responding)"; break; + case -EOVERFLOW: errmsg = "Babble (bad cable?)"; break; case -EPROTO: errmsg = "Bit-stuff error (bad cable?)"; break; case -EILSEQ: errmsg = "CRC/Timeout"; break; case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break; @@ -765,6 +772,11 @@ } /* .. flen < last_packet_size */ pdev->vlast_packet_size = flen; } /* ..status == 0 */ +#ifdef PWC_DEBUG + /* This is normally not interesting to the user, unless you are really debugging something */ + else + Trace(TRACE_FLOW, "Iso frame %d of USB has error %d\n", i, fst); +#endif } if (awake) wake_up_interruptible(&pdev->frameq); @@ -1140,7 +1152,7 @@ return -ERESTARTSYS; } schedule(); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_INTERRUPTIBLE); } remove_wait_queue(&pdev->frameq, &wait); set_current_state(TASK_RUNNING); @@ -1595,7 +1607,9 @@ struct pwc_device *pdev = NULL; struct video_device *vdev; int vendor_id, product_id, type_id; - int i; + int i, hint; + int video_nr = -1; /* default: use next available device */ + char serial_number[30]; free_mem_leak(); @@ -1698,6 +1712,10 @@ } else return NULL; /* Not Philips, Askey, Logitech or Samsung, for sure. */ + memset(serial_number, 0, 30); + usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); + Trace(TRACE_PROBE, "Device serial number is %s\n", serial_number); + if (udev->descriptor.bNumConfigurations > 1) Info("Warning: more than 1 configuration available.\n"); @@ -1734,6 +1752,21 @@ pdev->release = udev->descriptor.bcdDevice; Trace(TRACE_PROBE, "Release: %04x\n", pdev->release); + + /* Now search device_hint[] table for a match, so we can hint a node number. */ + for (hint = 0; hint < MAX_DEV_HINTS; hint++) { + if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) && + (device_hint[hint].pdev == NULL)) { + /* so far, so good... try serial number */ + if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) { + /* match! */ + video_nr = device_hint[hint].device_node; + Trace(TRACE_PROBE, "Found hint, will try to register as /dev/video%d\n", video_nr); + break; + } + } + } + i = video_register_device(vdev, VFL_TYPE_GRABBER, video_nr); if (i < 0) { Err("Failed to register as video device (%d).\n", i); @@ -1743,6 +1776,9 @@ Trace(TRACE_PROBE, "Registered video struct at 0x%p.\n", vdev); Info("Registered as /dev/video%d.\n", vdev->minor & 0x3F); } + /* occupy slot */ + if (hint < MAX_DEV_HINTS) + device_hint[hint].pdev = pdev; #if 0 /* Shut down camera now (some people like the LED off) */ @@ -1762,6 +1798,7 @@ static void usb_pwc_disconnect(struct usb_device *udev, void *ptr) { struct pwc_device *pdev; + int hint; lock_kernel(); free_mem_leak(); @@ -1815,12 +1852,31 @@ pdev->vdev = NULL; } } + + /* search device_hint[] table if we occupy a slot, by any chance */ + for (hint = 0; hint < MAX_DEV_HINTS; hint++) + if (device_hint[hint].pdev == pdev) + device_hint[hint].pdev = NULL; + pdev->udev = NULL; unlock_kernel(); kfree(pdev); } +/* *grunt* We have to do atoi ourselves :-( */ +static int pwc_atoi(char *s) +{ + int k = 0; + + k = 0; + while (*s != '\0' && *s >= '0' && *s <= '9') { + k = 10 * k + (*s - '0'); + s++; + } + return k; +} + /* * Initialization code & module stuff @@ -1833,8 +1889,8 @@ static int trace = -1; static int compression = -1; static int leds[2] = { -1, -1 }; +static char *dev_hint[10] = { }; -MODULE_PARM(video_nr, "i"); MODULE_PARM(size, "s"); MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); MODULE_PARM(fps, "i"); @@ -1851,13 +1907,16 @@ MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); MODULE_PARM(leds, "2i"); MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); +MODULE_PARM(dev_hint, "0-10s"); +MODULE_PARM_DESC(dev_hint, "Device node hints"); + MODULE_DESCRIPTION("Philips USB webcam driver"); MODULE_AUTHOR("Nemosoft Unv. "); MODULE_LICENSE("GPL"); static int __init usb_pwc_init(void) { - int s; + int i, sz; char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" }; Info("Philips PCA645/646 + PCVC675/680/690 + PCVC730/740/750 webcam module version " PWC_VERSION " loaded.\n"); @@ -1874,13 +1933,13 @@ if (size) { /* string; try matching with array */ - for (s = 0; s < PSZ_MAX; s++) { - if (!strcmp(sizenames[s], size)) { /* Found! */ - default_size = s; + for (sz = 0; sz < PSZ_MAX; sz++) { + if (!strcmp(sizenames[sz], size)) { /* Found! */ + default_size = sz; break; } } - if (s == PSZ_MAX) { + if (sz == PSZ_MAX) { Err("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n"); return -EINVAL; } @@ -1920,6 +1979,74 @@ led_on = leds[0] / 100; if (leds[1] >= 0) led_off = leds[1] / 100; + + /* Big device node whoopla. Basicly, it allows you to assign a + device node (/dev/videoX) to a camera, based on its type + & serial number. The format is [type[.serialnumber]:]node. + + Any camera that isn't matched by these rules gets the next + available free device node. + */ + for (i = 0; i < MAX_DEV_HINTS; i++) { + char *s, *colon, *dot; + + /* This loop also initializes the array */ + device_hint[i].pdev = NULL; + s = dev_hint[i]; + if (s != NULL && *s != '\0') { + device_hint[i].type = -1; /* wildcard */ + strcpy(device_hint[i].serial_number, "*"); + + /* parse string: chop at ':' & '/' */ + colon = dot = s; + while (*colon != '\0' && *colon != ':') + colon++; + while (*dot != '\0' && *dot != '.') + dot++; + /* Few sanity checks */ + if (*dot != '\0' && dot > colon) { + Err("Malformed camera hint: the colon must be after the dot.\n"); + return -EINVAL; + } + + if (*colon == '\0') { + /* No colon */ + if (*dot != '\0') { + Err("Malformed camera hint: no colon + device node given.\n"); + return -EINVAL; + } + else { + /* No type or serial number specified, just a number. */ + device_hint[i].device_node = pwc_atoi(s); + } + } + else { + /* There's a colon, so we have at least a type and a device node */ + device_hint[i].type = pwc_atoi(s); + device_hint[i].device_node = pwc_atoi(colon + 1); + if (*dot != '\0') { + /* There's a serial number as well */ + int k; + + dot++; + k = 0; + while (*dot != ':' && k < 29) { + device_hint[i].serial_number[k++] = *dot; + dot++; + } + device_hint[i].serial_number[k] = '\0'; + } + } +#ifdef PWC_DEBUG + Debug("device_hint[%d]:\n", i); + Debug(" type : %d\n", device_hint[i].type); + Debug(" serial# : %s\n", device_hint[i].serial_number); + Debug(" node : %d\n", device_hint[i].device_node); +#endif + } + else + device_hint[i].type = 0; /* not filled */ + } /* ..for MAX_DEV_HINTS */ init_MUTEX(&mem_lock); Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver); diff -u --recursive --new-file v2.5.0/linux/drivers/usb/pwc.h linux/drivers/usb/pwc.h --- v2.5.0/linux/drivers/usb/pwc.h Wed Oct 17 14:34:06 2001 +++ linux/drivers/usb/pwc.h Mon Nov 26 17:09:10 2001 @@ -60,8 +60,8 @@ /* Version block */ #define PWC_MAJOR 8 -#define PWC_MINOR 3 -#define PWC_VERSION "8.3" +#define PWC_MINOR 4 +#define PWC_VERSION "8.4" #define PWC_NAME "pwc" /* Turn certain features on/off */ diff -u --recursive --new-file v2.5.0/linux/drivers/usb/rio500.c linux/drivers/usb/rio500.c --- v2.5.0/linux/drivers/usb/rio500.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/rio500.c Sat Dec 8 20:28:45 2001 @@ -324,7 +324,7 @@ dbg("write stats: result:%d thistime:%lu partial:%u", result, thistime, partial); - if (result == USB_ST_TIMEOUT) { /* NAK - so hold for a while */ + if (result == -ETIMEDOUT) { /* NAK - so hold for a while */ if (!maxretry--) { errn = -ETIME; goto error; @@ -403,7 +403,7 @@ if (partial) { count = this_read = partial; - } else if (result == USB_ST_TIMEOUT || result == 15) { /* FIXME: 15 ??? */ + } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ if (!maxretry--) { up(&(rio->lock)); err("read_rio: maxretry timeout"); @@ -412,7 +412,7 @@ interruptible_sleep_on_timeout(&rio->wait_q, NAK_TIMEOUT); continue; - } else if (result != USB_ST_DATAUNDERRUN) { + } else if (result != -EREMOTEIO) { up(&(rio->lock)); err("Read Whoops - result:%u partial:%u this_read:%u", result, partial, this_read); diff -u --recursive --new-file v2.5.0/linux/drivers/usb/scanner.c linux/drivers/usb/scanner.c --- v2.5.0/linux/drivers/usb/scanner.c Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/scanner.c Sat Dec 8 20:28:44 2001 @@ -278,6 +278,28 @@ * - Users are now notified to consult the Documentation/usb/scanner.txt * for common error messages rather than the maintainer. * + * 0.4.7 11/28/2001 + * - Fixed typo in Documentation/scanner.txt. Thanks to + * Karel for pointing it out. + * - Added ID's for a Memorex 6136u. Thanks to =C1lvaro Gaspar de + * Valenzuela" . + * - Added ID's for Agfa e25. Thanks to Heinrich + * Rust . Also reported to work with + * Linux and SANE (?). + * - Added Canon FB620U, D646U, and 1220U ID's. Thanks to Paul + * Rensing . For more info + * on Linux support for these models, contact + * salvestrini@users.sourceforge.net. + * - Added Plustek OpticPro UT12, OpticPro U24, KYE/Genius + * ColorPage-HR6 V2 ID's in addition to many "Unknown" models + * under those vendors. Thanks to + * Jaeger, Gerhard" . These scanner are + * apparently based upon the LM983x IC's. + * - Applied Frank's patch that addressed some locking and module + * referencing counts. Thanks to both + * Frank Zago and + * Oliver Neukum <520047054719-0001@t-online.de> for reviewing/testing. + * * TODO * - Performance * - Select/poll methods @@ -324,17 +346,16 @@ struct scn_usb_data *scn; unsigned char *data; scn = urb->context; - down(&(scn->sem)); + data = &scn->button; data += 0; /* Keep gcc from complaining about unused var */ if (urb->status) { - up(&(scn->sem)); return; } dbg("irq_scanner(%d): data:%x", scn->scn_minor, *data); - up(&(scn->sem)); + return; } @@ -358,6 +379,7 @@ if (!p_scn_table[scn_minor]) { up(&scn_mutex); + MOD_DEC_USE_COUNT; err("open_scanner(%d): Unable to access minor data", scn_minor); return -ENODEV; } @@ -606,7 +628,7 @@ } ret = result; break; - } else if ((result < 0) && (result != USB_ST_DATAUNDERRUN)) { + } else if ((result < 0) && (result != -EREMOTEIO)) { warn("read_scanner(%d): funky result:%d. Consult Documentation/usb/scanner.txt.", scn_minor, (int)result); ret = -EIO; break; @@ -939,6 +961,7 @@ /* Check to make sure that the last slot isn't already taken */ if (p_scn_table[scn_minor]) { err("probe_scanner: No more minor devices remaining."); + up(&scn_mutex); return NULL; } @@ -946,6 +969,7 @@ if (!(scn = kmalloc (sizeof (struct scn_usb_data), GFP_KERNEL))) { err("probe_scanner: Out of memory."); + up(&scn_mutex); return NULL; } memset (scn, 0, sizeof(struct scn_usb_data)); @@ -1028,9 +1052,11 @@ if (scn->devfs == NULL) dbg("scanner%d: device node registration failed", scn_minor); + p_scn_table[scn_minor] = scn; + up(&scn_mutex); - return p_scn_table[scn_minor] = scn; + return scn; } static void diff -u --recursive --new-file v2.5.0/linux/drivers/usb/scanner.h linux/drivers/usb/scanner.h --- v2.5.0/linux/drivers/usb/scanner.h Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/scanner.h Sat Dec 8 20:28:44 2001 @@ -86,12 +86,23 @@ { USB_DEVICE(0x06bd, 0x2061) }, /* Another SnapScan 1212U (?)*/ { USB_DEVICE(0x06bd, 0x0100) }, /* SnapScan Touch */ { USB_DEVICE(0x06bd, 0x2091) }, /* SnapScan e20 */ + { USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */ { USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */ { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */ + /* Canon */ + { USB_DEVICE(0x04a9, 0x2202) }, /* FB620U */ + { USB_DEVICE(0x04a9, 0x220b) }, /* D646U */ + { USB_DEVICE(0x04a9, 0x2207) }, /* 1220U */ /* Colorado -- See Primax/Colorado below */ /* Epson -- See Seiko/Epson below */ /* Genius */ { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage-Vivid Pro */ + { USB_DEVICE(0x0458, 0x2007) }, /* ColorPage HR6 V2 */ + { USB_DEVICE(0x0458, 0x2008) }, /* Unknown */ + { USB_DEVICE(0x0458, 0x2009) }, /* Unknown */ + { USB_DEVICE(0x0458, 0x2013) }, /* Unknown */ + { USB_DEVICE(0x0458, 0x2015) }, /* Unknown */ + { USB_DEVICE(0x0458, 0x2016) }, /* Unknown */ /* Hewlett Packard */ { USB_DEVICE(0x03f0, 0x0205) }, /* 3300C */ { USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */ @@ -108,6 +119,8 @@ { USB_DEVICE(0x0638, 0x0268) }, /* 1200U */ /* Lifetec */ { USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */ + /* Memorex */ + { USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */ /* Microtek -- No longer supported - Enable SCSI and USB Microtek in kernel config */ // { USB_DEVICE(0x05da, 0x0099) }, /* ScanMaker X6 - X6U */ // { USB_DEVICE(0x05da, 0x0094) }, /* Phantom 336CX - C3 */ @@ -128,6 +141,19 @@ { USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */ { USB_DEVICE(0x055f, 0x0008) }, /* 1200 CU Plus */ { USB_DEVICE(0x0ff5, 0x0010) }, /* BearPaw 1200F */ + /* Plustek */ + { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12 */ + { USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro UT24 */ + { USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0010) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0015) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ /* Primax/Colorado */ { USB_DEVICE(0x0461, 0x0300) }, /* G2-300 #1 */ { USB_DEVICE(0x0461, 0x0380) }, /* G2-600 #1 */ diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/belkin_sa.c linux/drivers/usb/serial/belkin_sa.c --- v2.5.0/linux/drivers/usb/serial/belkin_sa.c Wed Oct 10 23:42:47 2001 +++ linux/drivers/usb/serial/belkin_sa.c Sat Dec 8 20:28:45 2001 @@ -1,8 +1,8 @@ /* * Belkin USB Serial Adapter Driver * - * Copyright (C) 2000 - * William Greathouse (wgreathouse@smva.com) + * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com) + * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com) * * This program is largely derived from work by the linux-usb group * and associated source files. Please see the usb/serial files for @@ -24,6 +24,9 @@ * -- Add support for flush commands * -- Add everything that is missing :) * + * 27-Nov-2001 gkh + * compressed all the differnent device entries into 1. + * * 30-May-2001 gkh * switched from using spinlock to a semaphore, which fixes lots of problems. * @@ -88,7 +91,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.1" +#define DRIVER_VERSION "v1.2" #define DRIVER_AUTHOR "William Greathouse " #define DRIVER_DESC "USB Belkin Serial converter driver" @@ -112,125 +115,12 @@ { } /* Terminating entry */ }; -static __devinitdata struct usb_device_id belkin_dockstation_table [] = { - { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) }, - { } /* Terminating entry */ -}; - -static __devinitdata struct usb_device_id belkin_sa_table [] = { - { USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) }, - { } /* Terminating entry */ -}; - -static __devinitdata struct usb_device_id belkin_old_table [] = { - { USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) }, - { } /* Terminating entry */ -}; - -static __devinitdata struct usb_device_id peracom_table [] = { - { USB_DEVICE(PERACOM_VID, PERACOM_PID) }, - { } /* Terminating entry */ -}; - -static __devinitdata struct usb_device_id gocom232_table [] = { - { USB_DEVICE(GOHUBS_VID, GOHUBS_PID) }, - { } /* Terminating entry */ -}; - MODULE_DEVICE_TABLE (usb, id_table_combined); -/* All of the device info needed for the Belkin dockstation serial converter */ -struct usb_serial_device_type belkin_dockstation_device = { - name: "Belkin F5U120-PC USB Serial Adapter", - id_table: belkin_dockstation_table, /* the Belkin F5U103 device */ - needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ - num_interrupt_in: 1, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: belkin_sa_open, - close: belkin_sa_close, - read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */ - ioctl: belkin_sa_ioctl, - set_termios: belkin_sa_set_termios, - break_ctl: belkin_sa_break_ctl, - startup: belkin_sa_startup, - shutdown: belkin_sa_shutdown, -}; - -/* All of the device info needed for the Belkin serial converter */ -struct usb_serial_device_type belkin_sa_device = { - name: "Belkin F5U103 USB Serial Adapter", - id_table: belkin_sa_table, /* the Belkin F5U103 device */ - needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ - num_interrupt_in: 1, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: belkin_sa_open, - close: belkin_sa_close, - read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */ - ioctl: belkin_sa_ioctl, - set_termios: belkin_sa_set_termios, - break_ctl: belkin_sa_break_ctl, - startup: belkin_sa_startup, - shutdown: belkin_sa_shutdown, -}; - - -/* This driver also supports the "old" school Belkin single port adaptor */ -struct usb_serial_device_type belkin_old_device = { - name: "Belkin USB Serial Adapter", - id_table: belkin_old_table, /* the old Belkin device */ - needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ - num_interrupt_in: 1, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: belkin_sa_open, - close: belkin_sa_close, - read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */ - ioctl: belkin_sa_ioctl, - set_termios: belkin_sa_set_termios, - break_ctl: belkin_sa_break_ctl, - startup: belkin_sa_startup, - shutdown: belkin_sa_shutdown, -}; - -/* this driver also works for the Peracom single port adapter */ -struct usb_serial_device_type peracom_device = { - name: "Peracom single port USB Serial Adapter", - id_table: peracom_table, /* the Peracom device */ - needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ - num_interrupt_in: 1, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: belkin_sa_open, - close: belkin_sa_close, - read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */ - ioctl: belkin_sa_ioctl, - set_termios: belkin_sa_set_termios, - break_ctl: belkin_sa_break_ctl, - startup: belkin_sa_startup, - shutdown: belkin_sa_shutdown, -}; - -/* the GoHubs Go-COM232 device is the same as the Peracom single port adapter */ -struct usb_serial_device_type gocom232_device = { - name: "GO-COM232 USB Serial Converter", - id_table: gocom232_table, /* the GO-COM232 device */ - needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ +/* All of the device info needed for the serial converters */ +static struct usb_serial_device_type belkin_device = { + name: "Belkin / Peracom / GoHubs USB Serial Adapter", + id_table: id_table_combined, num_interrupt_in: 1, num_bulk_in: 1, num_bulk_out: 1, @@ -321,9 +211,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /*Start reading from the device*/ /* TODO: Look at possibility of submitting mulitple URBs to device to * enhance buffering. Win trace shows 16 initial read URBs. @@ -372,7 +260,7 @@ usb_unlink_urb (port->read_urb); usb_unlink_urb (port->interrupt_in_urb); } - port->active = 0; + port->open_count = 0; } up (&port->sem); @@ -642,11 +530,7 @@ static int __init belkin_sa_init (void) { - usb_serial_register (&belkin_dockstation_device); - usb_serial_register (&belkin_sa_device); - usb_serial_register (&belkin_old_device); - usb_serial_register (&peracom_device); - usb_serial_register (&gocom232_device); + usb_serial_register (&belkin_device); info(DRIVER_DESC " " DRIVER_VERSION); return 0; } @@ -654,11 +538,7 @@ static void __exit belkin_sa_exit (void) { - usb_serial_deregister (&belkin_dockstation_device); - usb_serial_deregister (&belkin_sa_device); - usb_serial_deregister (&belkin_old_device); - usb_serial_deregister (&peracom_device); - usb_serial_deregister (&gocom232_device); + usb_serial_deregister (&belkin_device); } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/cyberjack.c linux/drivers/usb/serial/cyberjack.c --- v2.5.0/linux/drivers/usb/serial/cyberjack.c Wed Oct 10 23:42:47 2001 +++ linux/drivers/usb/serial/cyberjack.c Sat Dec 8 20:28:45 2001 @@ -76,12 +76,9 @@ MODULE_DEVICE_TABLE (usb, id_table); -struct usb_serial_device_type cyberjack_device = { +static struct usb_serial_device_type cyberjack_device = { name: "Reiner SCT Cyberjack USB card reader", id_table: id_table, - needs_interrupt_in: MUST_HAVE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 1, num_bulk_in: 1, num_bulk_out: 1, @@ -159,8 +156,7 @@ ++port->open_count; - if (!port->active) { - port->active = 1; + if (port->open_count == 1) { /* force low_latency on so that our tty_push actually forces * the data through, otherwise it is scheduled, and with high * data rates (like with OHCI) data can get lost. @@ -204,8 +200,6 @@ usb_unlink_urb (port->read_urb); usb_unlink_urb (port->interrupt_in_urb); } - - port->active = 0; port->open_count = 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/digi_acceleport.c linux/drivers/usb/serial/digi_acceleport.c --- v2.5.0/linux/drivers/usb/serial/digi_acceleport.c Wed Oct 10 23:42:47 2001 +++ linux/drivers/usb/serial/digi_acceleport.c Sat Dec 8 20:28:45 2001 @@ -14,6 +14,10 @@ * Peter Berger (pberger@brimson.com) * Al Borchers (borchers@steinerpoint.com) * +* (12/03/2001) gkh +* switched to using port->open_count instead of private version. +* Removed port->active +* * (04/08/2001) gb * Identify version on module load. * @@ -429,7 +433,6 @@ int dp_write_urb_in_use; unsigned int dp_modem_signals; wait_queue_head_t dp_modem_change_wait; - int dp_open_count; /* inc on open, dec on close */ int dp_transmit_idle; wait_queue_head_t dp_transmit_idle_wait; int dp_throttled; @@ -500,9 +503,6 @@ static struct usb_serial_device_type digi_acceleport_2_device = { name: "Digi USB", id_table: id_table_2, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 0, num_bulk_in: 4, num_bulk_out: 4, @@ -526,9 +526,6 @@ static struct usb_serial_device_type digi_acceleport_4_device = { name: "Digi USB", id_table: id_table_4, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 0, num_bulk_in: 5, num_bulk_out: 5, @@ -1386,7 +1383,7 @@ /* try to send any buffered data on this port, if it is open */ spin_lock( &priv->dp_port_lock ); priv->dp_write_urb_in_use = 0; - if( priv->dp_open_count && port->write_urb->status != -EINPROGRESS + if( port->open_count && port->write_urb->status != -EINPROGRESS && priv->dp_out_buf_len > 0 ) { *((unsigned char *)(port->write_urb->transfer_buffer)) @@ -1480,7 +1477,7 @@ unsigned long flags = 0; -dbg( "digi_open: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, port->active, priv->dp_open_count ); +dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); /* be sure the device is started up */ if( digi_startup_device( port->serial ) != 0 ) @@ -1495,7 +1492,7 @@ } /* inc module use count before sleeping to wait for closes */ - ++priv->dp_open_count; + ++port->open_count; MOD_INC_USE_COUNT; /* wait for a close in progress to finish */ @@ -1504,7 +1501,7 @@ &priv->dp_close_wait, DIGI_RETRY_TIMEOUT, &priv->dp_port_lock, flags ); if( signal_pending(current) ) { - --priv->dp_open_count; + --port->open_count; MOD_DEC_USE_COUNT; return( -EINTR ); } @@ -1513,13 +1510,11 @@ /* if port is already open, just return */ /* be sure exactly one open proceeds */ - if( port->active ) { + if( port->open_count != 1) { spin_unlock_irqrestore( &priv->dp_port_lock, flags ); return( 0 ); } - /* first open, mark port as active */ - port->active = 1; spin_unlock_irqrestore( &priv->dp_port_lock, flags ); /* read modem signals automatically whenever they change */ @@ -1560,17 +1555,17 @@ unsigned long flags = 0; -dbg( "digi_close: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, port->active, priv->dp_open_count ); +dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); /* do cleanup only after final close on this port */ spin_lock_irqsave( &priv->dp_port_lock, flags ); - if( priv->dp_open_count > 1 ) { - --priv->dp_open_count; + if( port->open_count > 1 ) { + --port->open_count; MOD_DEC_USE_COUNT; spin_unlock_irqrestore( &priv->dp_port_lock, flags ); return; - } else if( priv->dp_open_count <= 0 ) { + } else if( port->open_count <= 0 ) { spin_unlock_irqrestore( &priv->dp_port_lock, flags ); return; } @@ -1644,10 +1639,9 @@ tty->closing = 0; spin_lock_irqsave( &priv->dp_port_lock, flags ); - port->active = 0; priv->dp_write_urb_in_use = 0; priv->dp_in_close = 0; - --priv->dp_open_count; + --port->open_count; MOD_DEC_USE_COUNT; wake_up_interruptible( &priv->dp_close_wait ); spin_unlock_irqrestore( &priv->dp_port_lock, flags ); @@ -1716,8 +1710,6 @@ /* number of regular ports + 1 for the out-of-band port */ for( i=0; itype->num_ports+1; i++ ) { - serial->port[i].active = 0; - /* allocate port private structure */ priv = serial->port[i].private = (digi_port_t *)kmalloc( sizeof(digi_port_t), @@ -1736,7 +1728,6 @@ priv->dp_write_urb_in_use = 0; priv->dp_modem_signals = 0; init_waitqueue_head( &priv->dp_modem_change_wait ); - priv->dp_open_count = 0; priv->dp_transmit_idle = 0; init_waitqueue_head( &priv->dp_transmit_idle_wait ); priv->dp_throttled = 0; @@ -1795,9 +1786,9 @@ for( i=0; itype->num_ports; i++ ) { priv = serial->port[i].private; spin_lock_irqsave( &priv->dp_port_lock, flags ); - while( priv->dp_open_count > 0 ) { + while( serial->port[i].open_count > 0 ) { MOD_DEC_USE_COUNT; - --priv->dp_open_count; + --serial->port[i].open_count; } spin_unlock_irqrestore( &priv->dp_port_lock, flags ); } @@ -1889,7 +1880,7 @@ /* do not process callbacks on closed ports */ /* but do continue the read chain */ - if( priv->dp_open_count == 0 ) + if( port->open_count == 0 ) return( 0 ); /* short/multiple packet check */ @@ -2023,7 +2014,7 @@ if( val & DIGI_READ_INPUT_SIGNALS_CTS ) { priv->dp_modem_signals |= TIOCM_CTS; /* port must be open to use tty struct */ - if( priv->dp_open_count + if( port->open_count && port->tty->termios->c_cflag & CRTSCTS ) { port->tty->hw_stopped = 0; digi_wakeup_write( port ); @@ -2031,7 +2022,7 @@ } else { priv->dp_modem_signals &= ~TIOCM_CTS; /* port must be open to use tty struct */ - if( priv->dp_open_count + if( port->open_count && port->tty->termios->c_cflag & CRTSCTS ) { port->tty->hw_stopped = 1; } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/empeg.c linux/drivers/usb/serial/empeg.c --- v2.5.0/linux/drivers/usb/serial/empeg.c Wed Oct 10 23:42:47 2001 +++ linux/drivers/usb/serial/empeg.c Sat Dec 8 20:28:45 2001 @@ -113,12 +113,9 @@ MODULE_DEVICE_TABLE (usb, id_table); -struct usb_serial_device_type empeg_device = { +static struct usb_serial_device_type empeg_device = { name: "Empeg", id_table: id_table, - needs_interrupt_in: MUST_HAVE_NOT, /* must not have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* must have a bulk out endpoint */ num_interrupt_in: 0, num_bulk_in: 1, num_bulk_out: 1, @@ -164,12 +161,11 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { + if (port->open_count == 1) { /* Force default termio settings */ empeg_set_termios (port, NULL) ; - port->active = 1; bytes_in = 0; bytes_out = 0; @@ -221,7 +217,6 @@ /* shutdown our bulk read */ usb_unlink_urb (port->read_urb); } - port->active = 0; port->open_count = 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c --- v2.5.0/linux/drivers/usb/serial/ftdi_sio.c Tue Nov 13 09:19:41 2001 +++ linux/drivers/usb/serial/ftdi_sio.c Sat Dec 8 20:28:45 2001 @@ -173,12 +173,9 @@ /* Should rename most ftdi_sio's to ftdi_ now since there are two devices which share common code */ -struct usb_serial_device_type ftdi_sio_device = { +static struct usb_serial_device_type ftdi_sio_device = { name: "FTDI SIO", id_table: id_table_sio, - needs_interrupt_in: MUST_HAVE_NOT, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 0, num_bulk_in: 1, num_bulk_out: 1, @@ -196,12 +193,9 @@ shutdown: ftdi_sio_shutdown, }; -struct usb_serial_device_type ftdi_8U232AM_device = { +static struct usb_serial_device_type ftdi_8U232AM_device = { name: "FTDI 8U232AM", id_table: id_table_8U232AM, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 0, num_bulk_in: 1, num_bulk_out: 1, @@ -327,9 +321,7 @@ MOD_INC_USE_COUNT; ++port->open_count; - if (!port->active){ - port->active = 1; - + if (port->open_count == 1){ /* This will push the characters through immediately rather than queue a task to deliver them */ port->tty->low_latency = 1; @@ -410,7 +402,6 @@ usb_unlink_urb (port->write_urb); usb_unlink_urb (port->read_urb); } - port->active = 0; port->open_count = 0; } else { /* Send a HUP if necessary */ @@ -660,7 +651,7 @@ } /* ftdi_sio_serial_read_bulk_callback */ -__u16 translate_baudrate_to_ftdi(unsigned int cflag, ftdi_type_t ftdi_type) +static __u16 translate_baudrate_to_ftdi(unsigned int cflag, ftdi_type_t ftdi_type) { /* translate_baudrate_to_ftdi */ __u16 urb_value = ftdi_sio_b9600; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/io_edgeport.c linux/drivers/usb/serial/io_edgeport.c --- v2.5.0/linux/drivers/usb/serial/io_edgeport.c Wed Nov 21 09:59:11 2001 +++ linux/drivers/usb/serial/io_edgeport.c Sat Dec 8 20:28:45 2001 @@ -318,11 +318,6 @@ }; -/* the info for all of the devices that this driver supports */ -int EdgeportDevices[] = EDGEPORT_DEVICE_IDS; -#define NUM_EDGEPORT_DEVICES (sizeof(EdgeportDevices) / sizeof(int)) - - /* Transmit Fifo * This Transmit queue is an extension of the edgeport Rx buffer. * The maximum amount of data buffered in both the edgeport @@ -495,17 +490,15 @@ // ************************************************************************ // ************************************************************************ -// These functions should be in firmware.c - /************************************************************************ * * - * update_edgeport_E2PROM() Compare current versions of * + * update_edgeport_E2PROM() Compare current versions of * * Boot ROM and Manufacture * * Descriptors with versions * * embedded in this driver * * * ************************************************************************/ -void update_edgeport_E2PROM (struct edgeport_serial *edge_serial) +static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial) { __u32 BootCurVer; __u32 BootNewVer; @@ -994,9 +987,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /* force low_latency on so that our tty_push actually forces the data through, otherwise it is scheduled, and with high data rates (like with OHCI) data can get lost. */ @@ -1007,7 +998,6 @@ serial = port->serial; edge_serial = (struct edgeport_serial *)serial->private; if (edge_serial == NULL) { - port->active = 0; port->open_count = 0; MOD_DEC_USE_COUNT; return -ENODEV; @@ -1071,7 +1061,6 @@ if (response < 0) { err(__FUNCTION__" - error sending open port command"); edge_port->openPending = FALSE; - port->active = 0; port->open_count = 0; MOD_DEC_USE_COUNT; return -ENODEV; @@ -1087,7 +1076,6 @@ /* open timed out */ dbg(__FUNCTION__" - open timedout"); edge_port->openPending = FALSE; - port->active = 0; port->open_count = 0; MOD_DEC_USE_COUNT; return -ENODEV; @@ -1292,7 +1280,6 @@ if (edge_port->txfifo.fifo) { kfree(edge_port->txfifo.fifo); } - port->active = 0; port->open_count = 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/io_tables.h linux/drivers/usb/serial/io_tables.h --- v2.5.0/linux/drivers/usb/serial/io_tables.h Tue Nov 13 17:45:27 2001 +++ linux/drivers/usb/serial/io_tables.h Thu Nov 29 13:45:52 2001 @@ -74,9 +74,6 @@ static struct usb_serial_device_type edgeport_1port_device = { name: "Edgeport 1 port adapter", id_table: edgeport_1port_id_table, - needs_interrupt_in: MUST_HAVE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 1, num_bulk_in: 1, num_bulk_out: 1, @@ -98,9 +95,6 @@ static struct usb_serial_device_type edgeport_2port_device = { name: "Edgeport 2 port adapter", id_table: edgeport_2port_id_table, - needs_interrupt_in: MUST_HAVE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 1, num_bulk_in: 1, num_bulk_out: 1, @@ -122,9 +116,6 @@ static struct usb_serial_device_type edgeport_4port_device = { name: "Edgeport 4 port adapter", id_table: edgeport_4port_id_table, - needs_interrupt_in: MUST_HAVE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 1, num_bulk_in: 1, num_bulk_out: 1, @@ -146,9 +137,6 @@ static struct usb_serial_device_type edgeport_8port_device = { name: "Edgeport 8 port adapter", id_table: edgeport_8port_id_table, - needs_interrupt_in: MUST_HAVE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 1, num_bulk_in: 1, num_bulk_out: 1, diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/ir-usb.c linux/drivers/usb/serial/ir-usb.c --- v2.5.0/linux/drivers/usb/serial/ir-usb.c Mon Nov 12 09:53:56 2001 +++ linux/drivers/usb/serial/ir-usb.c Sat Dec 8 20:28:45 2001 @@ -93,9 +93,6 @@ struct usb_serial_device_type ir_device = { name: "IR Dongle", id_table: id_table, - needs_interrupt_in: MUST_HAVE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 1, num_bulk_in: 1, num_bulk_out: 1, @@ -209,9 +206,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { if (buffer_size) { /* override the default buffer sizes */ buffer = kmalloc (buffer_size, GFP_KERNEL); @@ -271,7 +266,6 @@ /* shutdown our bulk read */ usb_unlink_urb (port->read_urb); } - port->active = 0; port->open_count = 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/keyspan.c linux/drivers/usb/serial/keyspan.c --- v2.5.0/linux/drivers/usb/serial/keyspan.c Wed Oct 10 23:42:47 2001 +++ linux/drivers/usb/serial/keyspan.c Sat Dec 8 20:28:45 2001 @@ -176,7 +176,7 @@ /* Functions used by new usb-serial code. */ -int keyspan_init (void) +static int __init keyspan_init (void) { usb_serial_register (&keyspan_usa18x_pre_device); usb_serial_register (&keyspan_usa19_pre_device); @@ -201,7 +201,7 @@ return 0; } -void keyspan_exit (void) +static void __exit keyspan_exit (void) { usb_serial_deregister (&keyspan_usa18x_pre_device); usb_serial_deregister (&keyspan_usa19_pre_device); @@ -468,7 +468,7 @@ p_priv = (struct keyspan_port_private *)(port->private); dbg (__FUNCTION__ " urb %d\n", urb == p_priv->out_urbs[1]); - if (port->active) { + if (port->open_count) { queue_task(&port->tqueue, &tq_immediate); mark_bh(IMMEDIATE_BH); } @@ -880,9 +880,8 @@ MOD_INC_USE_COUNT; down (&port->sem); + already_active = port->open_count; ++port->open_count; - already_active = port->active; - port->active = 1; up (&port->sem); if (already_active) @@ -948,18 +947,15 @@ down (&port->sem); if (--port->open_count <= 0) { - if (port->active) { - if (serial->dev) { - /* Stop reading/writing urbs */ - stop_urb(p_priv->inack_urb); - stop_urb(p_priv->outcont_urb); - for (i = 0; i < 2; i++) { - stop_urb(p_priv->in_urbs[i]); - stop_urb(p_priv->out_urbs[i]); - } + if (serial->dev) { + /* Stop reading/writing urbs */ + stop_urb(p_priv->inack_urb); + stop_urb(p_priv->outcont_urb); + for (i = 0; i < 2; i++) { + stop_urb(p_priv->in_urbs[i]); + stop_urb(p_priv->out_urbs[i]); } } - port->active = 0; port->open_count = 0; port->tty = 0; } @@ -1089,7 +1085,7 @@ return urb; } -struct callbacks { +static struct callbacks { void (*instat_callback)(urb_t *); void (*glocont_callback)(urb_t *); void (*indat_callback)(urb_t *); diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/keyspan.h linux/drivers/usb/serial/keyspan.h --- v2.5.0/linux/drivers/usb/serial/keyspan.h Tue Oct 9 15:15:02 2001 +++ linux/drivers/usb/serial/keyspan.h Thu Nov 29 13:45:52 2001 @@ -448,12 +448,9 @@ }; /* Structs for the devices, pre and post renumeration. */ -struct usb_serial_device_type keyspan_usa18x_pre_device = { +static struct usb_serial_device_type keyspan_usa18x_pre_device = { name: "Keyspan USA18X - (without firmware)", id_table: keyspan_usa18x_pre_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -461,12 +458,9 @@ startup: keyspan_fake_startup }; -struct usb_serial_device_type keyspan_usa19_pre_device = { +static struct usb_serial_device_type keyspan_usa19_pre_device = { name: "Keyspan USA19 - (without firmware)", id_table: keyspan_usa19_pre_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -475,12 +469,9 @@ }; -struct usb_serial_device_type keyspan_usa19w_pre_device = { +static struct usb_serial_device_type keyspan_usa19w_pre_device = { name: "Keyspan USA19W - (without firmware)", id_table: keyspan_usa19w_pre_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -489,12 +480,9 @@ }; -struct usb_serial_device_type keyspan_usa28_pre_device = { +static struct usb_serial_device_type keyspan_usa28_pre_device = { name: "Keyspan USA28 - (without firmware)", id_table: keyspan_usa28_pre_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -502,12 +490,9 @@ startup: keyspan_fake_startup }; -struct usb_serial_device_type keyspan_usa28x_pre_device = { +static struct usb_serial_device_type keyspan_usa28x_pre_device = { name: "Keyspan USA28X - (without firmware)", id_table: keyspan_usa28x_pre_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -515,12 +500,9 @@ startup: keyspan_fake_startup }; -struct usb_serial_device_type keyspan_usa28xa_pre_device = { +static struct usb_serial_device_type keyspan_usa28xa_pre_device = { name: "Keyspan USA28XA - (without firmware)", id_table: keyspan_usa28xa_pre_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -528,12 +510,9 @@ startup: keyspan_fake_startup }; -struct usb_serial_device_type keyspan_usa28xb_pre_device = { +static struct usb_serial_device_type keyspan_usa28xb_pre_device = { name: "Keyspan USA28XB - (without firmware)", id_table: keyspan_usa28xb_pre_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -541,12 +520,9 @@ startup: keyspan_fake_startup }; -struct usb_serial_device_type keyspan_usa49w_pre_device = { +static struct usb_serial_device_type keyspan_usa49w_pre_device = { name: "Keyspan USA49W - (without firmware)", id_table: keyspan_usa49w_pre_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -554,12 +530,9 @@ startup: keyspan_fake_startup }; -struct usb_serial_device_type keyspan_usa18x_device = { +static struct usb_serial_device_type keyspan_usa18x_device = { name: "Keyspan USA18X", id_table: keyspan_usa18x_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: 3, num_bulk_out: 4, @@ -580,12 +553,9 @@ shutdown: keyspan_shutdown, }; -struct usb_serial_device_type keyspan_usa19_device = { +static struct usb_serial_device_type keyspan_usa19_device = { name: "Keyspan USA19", id_table: keyspan_usa19_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: 3, num_bulk_out: 4, @@ -607,12 +577,9 @@ }; -struct usb_serial_device_type keyspan_usa19w_device = { +static struct usb_serial_device_type keyspan_usa19w_device = { name: "Keyspan USA19W", id_table: keyspan_usa19w_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: 3, num_bulk_out: 4, @@ -634,12 +601,9 @@ }; -struct usb_serial_device_type keyspan_usa28_device = { +static struct usb_serial_device_type keyspan_usa28_device = { name: "Keyspan USA28", id_table: keyspan_usa28_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -652,12 +616,9 @@ }; -struct usb_serial_device_type keyspan_usa28x_device = { +static struct usb_serial_device_type keyspan_usa28x_device = { name: "Keyspan USA28X/XB", id_table: keyspan_usa28x_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -679,12 +640,9 @@ }; -struct usb_serial_device_type keyspan_usa28xa_device = { +static struct usb_serial_device_type keyspan_usa28xa_device = { name: "Keyspan USA28XA", id_table: keyspan_usa28xa_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -706,12 +664,9 @@ }; -struct usb_serial_device_type keyspan_usa49w_device = { +static struct usb_serial_device_type keyspan_usa49w_device = { name: "Keyspan USA49W", id_table: keyspan_usa49w_ids, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: 5, num_bulk_out: 5, diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/keyspan_pda.c linux/drivers/usb/serial/keyspan_pda.c --- v2.5.0/linux/drivers/usb/serial/keyspan_pda.c Wed Oct 10 23:42:47 2001 +++ linux/drivers/usb/serial/keyspan_pda.c Sat Dec 8 20:28:45 2001 @@ -172,10 +172,6 @@ #ifdef XIRCOM static __devinitdata struct usb_device_id id_table_fake_xircom [] = { { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) }, - { } -}; - -static __devinitdata struct usb_device_id id_table_fake_entregra [] = { { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) }, { } }; @@ -679,9 +675,7 @@ MOD_INC_USE_COUNT; ++port->open_count; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /* find out how much room is in the Tx ring */ rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 6, /* write_room */ @@ -727,7 +721,6 @@ return rc; error: --port->open_count; - port->active = 0; MOD_DEC_USE_COUNT; up (&port->sem); return rc; @@ -752,7 +745,6 @@ usb_unlink_urb (port->write_urb); usb_unlink_urb (port->interrupt_in_urb); } - port->active = 0; port->open_count = 0; } @@ -843,9 +835,6 @@ static struct usb_serial_device_type keyspan_pda_fake_device = { name: "Keyspan PDA - (prerenumeration)", id_table: id_table_fake, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -856,24 +845,8 @@ #ifdef XIRCOM static struct usb_serial_device_type xircom_pgs_fake_device = { - name: "Xircom PGS - (prerenumeration)", + name: "Xircom / Entregra PGS - (prerenumeration)", id_table: id_table_fake_xircom, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, - num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: NUM_DONT_CARE, - num_bulk_out: NUM_DONT_CARE, - num_ports: 1, - startup: keyspan_pda_fake_startup, -}; - -static struct usb_serial_device_type entregra_pgs_fake_device = { - name: "Entregra PGS - (prerenumeration)", - id_table: id_table_fake_entregra, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -885,9 +858,6 @@ static struct usb_serial_device_type keyspan_pda_device = { name: "Keyspan PDA", id_table: id_table_std, - needs_interrupt_in: MUST_HAVE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 1, num_bulk_in: 0, num_bulk_out: 1, @@ -917,7 +887,6 @@ #endif #ifdef XIRCOM usb_serial_register (&xircom_pgs_fake_device); - usb_serial_register (&entregra_pgs_fake_device); #endif info(DRIVER_DESC " " DRIVER_VERSION); return 0; @@ -931,7 +900,6 @@ usb_serial_deregister (&keyspan_pda_fake_device); #endif #ifdef XIRCOM - usb_serial_deregister (&entregra_pgs_fake_device); usb_serial_deregister (&xircom_pgs_fake_device); #endif } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/mct_u232.c linux/drivers/usb/serial/mct_u232.c --- v2.5.0/linux/drivers/usb/serial/mct_u232.c Mon Nov 12 09:53:56 2001 +++ linux/drivers/usb/serial/mct_u232.c Sat Dec 8 20:28:44 2001 @@ -27,6 +27,9 @@ * 10-Nov-2001 Wolfgang Grandegger * - Fixed an endianess problem with the baudrate selection for PowerPC. * + * 06-Dec-2001 Martin Hamilton + * Added support for the Belkin F5U109 DB9 adaptor + * * 30-May-2001 Greg Kroah-Hartman * switched from using spinlock to a semaphore, which fixes lots of problems. * @@ -133,57 +136,16 @@ { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) }, { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) }, { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) }, + { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) }, { } /* Terminating entry */ }; -static __devinitdata struct usb_device_id mct_u232_table [] = { - { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) }, - { } /* Terminating entry */ -}; - -static __devinitdata struct usb_device_id mct_u232_sitecom_table [] = { - { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) }, - { } /* Terminating entry */ -}; - -static __devinitdata struct usb_device_id mct_u232_du_h3sp_table [] = { - { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) }, - { } /* Terminating entry */ -}; - MODULE_DEVICE_TABLE (usb, id_table_combined); -struct usb_serial_device_type mct_u232_device = { +static struct usb_serial_device_type mct_u232_device = { name: "Magic Control Technology USB-RS232", - id_table: mct_u232_table, - needs_interrupt_in: MUST_HAVE, /* 2 interrupt-in endpoints */ - needs_bulk_in: MUST_HAVE_NOT, /* no bulk-in endpoint */ - needs_bulk_out: MUST_HAVE, /* 1 bulk-out endpoint */ - num_interrupt_in: 2, - num_bulk_in: 0, - num_bulk_out: 1, - num_ports: 1, - open: mct_u232_open, - close: mct_u232_close, -#ifdef FIX_WRITE_RETURN_CODE_PROBLEM - write: mct_u232_write, - write_bulk_callback: mct_u232_write_bulk_callback, -#endif - read_int_callback: mct_u232_read_int_callback, - ioctl: mct_u232_ioctl, - set_termios: mct_u232_set_termios, - break_ctl: mct_u232_break_ctl, - startup: mct_u232_startup, - shutdown: mct_u232_shutdown, -}; - -struct usb_serial_device_type mct_u232_sitecom_device = { - name: "MCT/Sitecom USB-RS232", - id_table: mct_u232_sitecom_table, - needs_interrupt_in: MUST_HAVE, /* 2 interrupt-in endpoints */ - needs_bulk_in: MUST_HAVE_NOT, /* no bulk-in endpoint */ - needs_bulk_out: MUST_HAVE, /* 1 bulk-out endpoint */ + id_table: id_table_combined, num_interrupt_in: 2, num_bulk_in: 0, num_bulk_out: 1, @@ -202,32 +164,6 @@ shutdown: mct_u232_shutdown, }; -struct usb_serial_device_type mct_u232_du_h3sp_device = { - name: "MCT/D-Link DU-H3SP USB BAY", - id_table: mct_u232_du_h3sp_table, - needs_interrupt_in: MUST_HAVE, /* 2 interrupt-in endpoints */ - needs_bulk_in: MUST_HAVE_NOT, /* no bulk-in endpoint */ - needs_bulk_out: MUST_HAVE, /* 1 bulk-out endpoint */ - num_interrupt_in: 2, - num_bulk_in: 0, - num_bulk_out: 1, - num_ports: 1, - open: mct_u232_open, - close: mct_u232_close, -#ifdef FIX_WRITE_RETURN_CODE_PROBLEM - write: mct_u232_write, - write_bulk_callback: mct_u232_write_bulk_callback, -#endif - read_int_callback: mct_u232_read_int_callback, - ioctl: mct_u232_ioctl, - set_termios: mct_u232_set_termios, - break_ctl: mct_u232_break_ctl, - startup: mct_u232_startup, - shutdown: mct_u232_shutdown, -}; - - - struct mct_u232_private { unsigned long control_state; /* Modem Line Setting (TIOCM) */ @@ -243,7 +179,8 @@ #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) { - if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID) { + if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID + || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) { switch (value) { case 300: return 0x01; case 600: return 0x02; /* this one not tested */ @@ -408,9 +345,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /* Compensate for a hardware bug: although the Sitecom U232-P25 * device reports a maximum output packet size of 32 bytes, * it seems to be able to accept only 16 bytes (and that's what @@ -484,7 +419,7 @@ usb_unlink_urb (port->read_urb); usb_unlink_urb (port->interrupt_in_urb); } - port->active = 0; + port->open_count = 0; } up (&port->sem); @@ -880,9 +815,7 @@ static int __init mct_u232_init (void) { usb_serial_register (&mct_u232_device); - usb_serial_register (&mct_u232_sitecom_device); - usb_serial_register (&mct_u232_du_h3sp_device); - info(DRIVER_VERSION ":" DRIVER_DESC); + info(DRIVER_DESC " " DRIVER_VERSION); return 0; } @@ -890,8 +823,6 @@ static void __exit mct_u232_exit (void) { usb_serial_deregister (&mct_u232_device); - usb_serial_deregister (&mct_u232_sitecom_device); - usb_serial_deregister (&mct_u232_du_h3sp_device); } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/mct_u232.h linux/drivers/usb/serial/mct_u232.h --- v2.5.0/linux/drivers/usb/serial/mct_u232.h Thu Feb 8 16:30:40 2001 +++ linux/drivers/usb/serial/mct_u232.h Sat Dec 8 20:28:45 2001 @@ -30,9 +30,12 @@ #define MCT_U232_SITECOM_PID 0x0230 /* Sitecom Product Id */ /* DU-H3SP USB BAY hub */ - #define MCT_U232_DU_H3SP_PID 0x0200 /* D-Link DU-H3SP USB BAY */ +/* Belkin badge the MCT U232-P9 as the F5U109 */ +#define MCT_U232_BELKIN_F5U109_VID 0x050d /* Vendor Id */ +#define MCT_U232_BELKIN_F5U109_PID 0x0109 /* Product Id */ + /* * Vendor Request Interface */ @@ -363,6 +366,25 @@ * bmAttributes = 03 (Interrupt) * wMaxPacketSize = 0002 * bInterval = 02 + * + * + * Hardware details (added by Martin Hamilton, 2001/12/06) + * ----------------------------------------------------------------- + * + * This info was gleaned from opening a Belkin F5U109 DB9 USB serial + * adaptor, which turns out to simply be a re-badged U232-P9. We + * know this because there is a sticky label on the circuit board + * which says "U232-P9" ;-) + * + * The circuit board inside the adaptor contains a Philips PDIUSBD12 + * USB endpoint chip and a Phillips P87C52UBAA microcontroller with + * embedded UART. Exhaustive documentation for these is available at: + * + * http://www.semiconductors.philips.com/pip/p87c52ubaa + * http://www.semiconductors.philips.com/pip/pdiusbd12 + * + * Thanks to Julian Highfield for the pointer to the Philips database. + * */ #endif /* __LINUX_USB_SERIAL_MCT_U232_H */ diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/omninet.c linux/drivers/usb/serial/omninet.c --- v2.5.0/linux/drivers/usb/serial/omninet.c Wed Oct 10 23:42:47 2001 +++ linux/drivers/usb/serial/omninet.c Sat Dec 8 20:28:45 2001 @@ -87,12 +87,9 @@ MODULE_DEVICE_TABLE (usb, id_table); -struct usb_serial_device_type zyxel_omninet_device = { +static struct usb_serial_device_type zyxel_omninet_device = { name: "ZyXEL - omni.net lcd plus usb", id_table: id_table, - needs_interrupt_in: MUST_HAVE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, num_interrupt_in: 1, num_bulk_in: 1, num_bulk_out: 2, @@ -164,14 +161,11 @@ MOD_INC_USE_COUNT; ++port->open_count; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); if( !od ) { err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct omninet_data)); - --port->open_count; - port->active = 0; + port->open_count = 0; up (&port->sem); MOD_DEC_USE_COUNT; return -ENOMEM; @@ -222,7 +216,6 @@ usb_unlink_urb (port->read_urb); } - port->active = 0; port->open_count = 0; od = (struct omninet_data *)port->private; if (od) diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/pl2303.c linux/drivers/usb/serial/pl2303.c --- v2.5.0/linux/drivers/usb/serial/pl2303.c Wed Oct 10 23:42:47 2001 +++ linux/drivers/usb/serial/pl2303.c Sat Dec 8 20:28:45 2001 @@ -118,9 +118,6 @@ static struct usb_serial_device_type pl2303_device = { name: "PL-2303", id_table: id_table, - needs_interrupt_in: DONT_CARE, /* this device must have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ num_interrupt_in: NUM_DONT_CARE, num_bulk_in: 1, num_bulk_out: 1, @@ -374,9 +371,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { #define FISH(a,b,c,d) \ result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \ b, a, c, d, buf, 1, 100); \ @@ -481,8 +476,6 @@ "(interrupt_in_urb) failed with reason: %d", result); } - - port->active = 0; port->open_count = 0; } @@ -651,7 +644,7 @@ if (urb->status) { dbg (__FUNCTION__ " - urb->status = %d", urb->status); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port is closed, exiting."); return; } @@ -683,7 +676,7 @@ } /* Schedule the next read _if_ we are still open */ - if (port->active) { + if (port->open_count) { urb->dev = serial->dev; result = usb_submit_urb(urb); if (result) diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/usb-serial.h linux/drivers/usb/serial/usb-serial.h --- v2.5.0/linux/drivers/usb/serial/usb-serial.h Wed Oct 10 23:42:47 2001 +++ linux/drivers/usb/serial/usb-serial.h Sat Dec 8 20:28:45 2001 @@ -11,6 +11,10 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (12/03/2001) gkh + * removed active from the port structure. + * added documentation to the usb_serial_device_type structure + * * (10/10/2001) gkh * added vendor and product to serial structure. Needed to determine device * owner when the device is disconnected. @@ -65,7 +69,6 @@ struct usb_serial *serial; /* pointer back to the owner of this port */ struct tty_struct * tty; /* the coresponding tty for this port */ unsigned char number; - char active; /* someone has this device open */ unsigned char * interrupt_in_buffer; struct urb * interrupt_in_urb; @@ -108,34 +111,43 @@ }; -#define MUST_HAVE_NOT 0x01 -#define MUST_HAVE 0x02 -#define DONT_CARE 0x03 - -#define HAS 0x02 -#define HAS_NOT 0x01 - #define NUM_DONT_CARE (-1) -/* This structure defines the individual serial converter. */ +/** + * usb_serial_device_type - a structure that defines a usb serial device + * @name: pointer to a string that describes this device. This string used + * in the syslog messages when a device is inserted or removed. + * @id_table: pointer to a list of usb_device_id structures that define all + * of the devices this structure can support. + * @num_interrupt_in: the number of interrupt in endpoints this device will + * have. + * @num_bulk_in: the number of bulk in endpoints this device will have. + * @num_bulk_out: the number of bulk out endpoints this device will have. + * @num_ports: the number of different ports this device will have. + * @startup: pointer to the driver's startup function. This will be called + * when the driver is inserted into the system. Return 0 to continue + * on with the initialization sequence. Anything else will abort it. + * @shutdown: pointer to the driver's shutdown function. This will be + * called when the device is removed from the system. + * + * This structure is defines a USB Serial device. It provides all of + * the information that the USB serial core code needs. If the function + * pointers are defined, then the USB serial core code will call them when + * the corresponding tty port functions are called. If they are not + * called, the generic serial function will be used instead. + */ struct usb_serial_device_type { char *name; const struct usb_device_id *id_table; - char needs_interrupt_in; - char needs_bulk_in; - char needs_bulk_out; char num_interrupt_in; char num_bulk_in; char num_bulk_out; - char num_ports; /* number of serial ports this device has */ + char num_ports; struct list_head driver_list; - /* function call to make before accepting driver */ - /* return 0 to continue initialization, anything else to abort */ int (*startup) (struct usb_serial *serial); - void (*shutdown) (struct usb_serial *serial); /* serial function calls */ diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c --- v2.5.0/linux/drivers/usb/serial/usbserial.c Wed Oct 10 23:42:47 2001 +++ linux/drivers/usb/serial/usbserial.c Sat Dec 8 20:28:45 2001 @@ -339,9 +339,6 @@ static struct usb_serial_device_type generic_device = { name: "Generic", id_table: generic_device_ids, - needs_interrupt_in: DONT_CARE, /* don't have to have an interrupt in endpoint */ - needs_bulk_in: DONT_CARE, /* don't have to have a bulk in endpoint */ - needs_bulk_out: DONT_CARE, /* don't have to have a bulk out endpoint */ num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -397,7 +394,7 @@ static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ -LIST_HEAD(usb_serial_driver_list); +static LIST_HEAD(usb_serial_driver_list); static struct usb_serial *get_serial_by_minor (int minor) @@ -548,7 +545,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not opened"); return; } @@ -573,7 +570,7 @@ dbg(__FUNCTION__ " - port %d, %d byte(s)", port->number, count); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not opened"); return -EINVAL; } @@ -598,7 +595,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return -EINVAL; } @@ -621,7 +618,7 @@ return -ENODEV; } - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return -EINVAL; } @@ -646,7 +643,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return; } @@ -671,7 +668,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return; } @@ -696,7 +693,7 @@ dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return -ENODEV; } @@ -721,7 +718,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return; } @@ -746,7 +743,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return; } @@ -790,9 +787,7 @@ ++port->open_count; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /* force low_latency on so that our tty_push actually forces the data through, otherwise it is scheduled, and with high data rates (like with OHCI) data can get lost. */ @@ -801,13 +796,14 @@ /* if we have a bulk interrupt, start reading from it */ if (serial->num_bulk_in) { /* Start reading from the device */ - FILL_BULK_URB(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, - ((serial->type->read_bulk_callback) ? - serial->type->read_bulk_callback : - generic_read_bulk_callback), - port); + usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + ((serial->type->read_bulk_callback) ? + serial->type->read_bulk_callback : + generic_read_bulk_callback), + port); result = usb_submit_urb(port->read_urb); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); @@ -838,8 +834,6 @@ if (serial->num_bulk_in) usb_unlink_urb (port->read_urb); } - - port->active = 0; port->open_count = 0; } @@ -882,13 +876,13 @@ usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer); /* set up our urb */ - FILL_BULK_URB(port->write_urb, serial->dev, - usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, count, - ((serial->type->write_bulk_callback) ? - serial->type->write_bulk_callback : - generic_write_bulk_callback), - port); + usb_fill_bulk_urb (port->write_urb, serial->dev, + usb_sndbulkpipe (serial->dev, + port->bulk_out_endpointAddress), + port->write_urb->transfer_buffer, count, + ((serial->type->write_bulk_callback) ? + serial->type->write_bulk_callback : + generic_write_bulk_callback), port); /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb); @@ -976,13 +970,14 @@ } /* Continue trying to always read */ - FILL_BULK_URB(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, - ((serial->type->read_bulk_callback) ? - serial->type->read_bulk_callback : - generic_read_bulk_callback), - port); + usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_rcvbulkpipe (serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + ((serial->type->read_bulk_callback) ? + serial->type->read_bulk_callback : + generic_read_bulk_callback), port); result = usb_submit_urb(port->read_urb); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); @@ -1068,9 +1063,6 @@ int minor; int buffer_size; int i; - char interrupt_pipe; - char bulk_in_pipe; - char bulk_out_pipe; int num_interrupt_in = 0; int num_bulk_in = 0; int num_bulk_out = 0; @@ -1097,10 +1089,8 @@ dbg("none matched"); return(NULL); } - + /* descriptor matches, let's find the endpoints needed */ - interrupt_pipe = bulk_in_pipe = bulk_out_pipe = HAS_NOT; - /* check out the endpoints */ iface_desc = &interface->altsetting[0]; for (i = 0; i < iface_desc->bNumEndpoints; ++i) { @@ -1110,7 +1100,6 @@ ((endpoint->bmAttributes & 3) == 0x02)) { /* we found a bulk in endpoint */ dbg("found bulk in"); - bulk_in_pipe = HAS; bulk_in_endpoint[num_bulk_in] = endpoint; ++num_bulk_in; } @@ -1119,7 +1108,6 @@ ((endpoint->bmAttributes & 3) == 0x02)) { /* we found a bulk out endpoint */ dbg("found bulk out"); - bulk_out_pipe = HAS; bulk_out_endpoint[num_bulk_out] = endpoint; ++num_bulk_out; } @@ -1128,7 +1116,6 @@ ((endpoint->bmAttributes & 3) == 0x03)) { /* we found a interrupt in endpoint */ dbg("found interrupt in"); - interrupt_pipe = HAS; interrupt_in_endpoint[num_interrupt_in] = endpoint; ++num_interrupt_in; } @@ -1151,7 +1138,6 @@ ((endpoint->bmAttributes & 3) == 0x03)) { /* we found a interrupt in endpoint */ dbg("found interrupt in for Prolific device on separate interface"); - interrupt_pipe = HAS; interrupt_in_endpoint[num_interrupt_in] = endpoint; ++num_interrupt_in; } @@ -1161,15 +1147,6 @@ /* END HORRIBLE HACK FOR PL2303 */ #endif - /* verify that we found all of the endpoints that we need */ - if (!((interrupt_pipe & type->needs_interrupt_in) && - (bulk_in_pipe & type->needs_bulk_in) && - (bulk_out_pipe & type->needs_bulk_out))) { - /* nope, they don't match what we expected */ - info("descriptors matched, but endpoints did not"); - return NULL; - } - /* found all that we need */ info("%s converter detected", type->name); @@ -1224,13 +1201,14 @@ err("Couldn't allocate bulk_in_buffer"); goto probe_error; } - FILL_BULK_URB(port->read_urb, dev, - usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), - port->bulk_in_buffer, buffer_size, - ((serial->type->read_bulk_callback) ? - serial->type->read_bulk_callback : - generic_read_bulk_callback), - port); + usb_fill_bulk_urb (port->read_urb, dev, + usb_rcvbulkpipe (dev, + endpoint->bEndpointAddress), + port->bulk_in_buffer, buffer_size, + ((serial->type->read_bulk_callback) ? + serial->type->read_bulk_callback : + generic_read_bulk_callback), + port); } for (i = 0; i < num_bulk_out; ++i) { @@ -1249,13 +1227,14 @@ err("Couldn't allocate bulk_out_buffer"); goto probe_error; } - FILL_BULK_URB(port->write_urb, dev, - usb_sndbulkpipe(dev, endpoint->bEndpointAddress), - port->bulk_out_buffer, buffer_size, - ((serial->type->write_bulk_callback) ? - serial->type->write_bulk_callback : - generic_write_bulk_callback), - port); + usb_fill_bulk_urb (port->write_urb, dev, + usb_sndbulkpipe (dev, + endpoint->bEndpointAddress), + port->bulk_out_buffer, buffer_size, + ((serial->type->write_bulk_callback) ? + serial->type->write_bulk_callback : + generic_write_bulk_callback), + port); } for (i = 0; i < num_interrupt_in; ++i) { @@ -1273,12 +1252,12 @@ err("Couldn't allocate interrupt_in_buffer"); goto probe_error; } - FILL_INT_URB(port->interrupt_in_urb, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - port->interrupt_in_buffer, buffer_size, - serial->type->read_int_callback, - port, - endpoint->bInterval); + usb_fill_int_urb (port->interrupt_in_urb, dev, + usb_rcvintpipe (dev, + endpoint->bEndpointAddress), + port->interrupt_in_buffer, buffer_size, + serial->type->read_int_callback, port, + endpoint->bInterval); } /* initialize some parts of the port structures */ @@ -1356,7 +1335,7 @@ serial_shutdown (serial); for (i = 0; i < serial->num_ports; ++i) - serial->port[i].active = 0; + serial->port[i].open_count = 0; for (i = 0; i < serial->num_bulk_in; ++i) { port = &serial->port[i]; @@ -1433,7 +1412,7 @@ }; -int usb_serial_init(void) +static int __init usb_serial_init(void) { int i; int result; @@ -1473,7 +1452,7 @@ } -void usb_serial_exit(void) +static void __exit usb_serial_exit(void) { #ifdef CONFIG_USB_SERIAL_GENERIC diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c --- v2.5.0/linux/drivers/usb/serial/visor.c Mon Nov 12 09:53:56 2001 +++ linux/drivers/usb/serial/visor.c Sat Dec 8 20:28:45 2001 @@ -127,7 +127,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.5" +#define DRIVER_VERSION "v1.7" #define DRIVER_AUTHOR "Greg Kroah-Hartman " #define DRIVER_DESC "USB HandSpring Visor, Palm m50x, Sony Clié driver" @@ -147,15 +147,12 @@ static void visor_read_bulk_callback (struct urb *urb); -static __devinitdata struct usb_device_id visor_id_table [] = { - { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, - { } /* Terminating entry */ -}; - -static __devinitdata struct usb_device_id palm_4_0_id_table [] = { +static __devinitdata struct usb_device_id combined_id_table [] = { { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) }, + { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, + { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, { } /* Terminating entry */ }; @@ -164,11 +161,6 @@ { } /* Terminating entry */ }; -static __devinitdata struct usb_device_id clie_id_4_0_table [] = { - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, - { } /* Terminating entry */ -}; - static __devinitdata struct usb_device_id id_table [] = { { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) }, @@ -183,39 +175,10 @@ -/* All of the device info needed for the Handspring Visor */ -struct usb_serial_device_type handspring_device = { - name: "Handspring Visor", - id_table: visor_id_table, - needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ - num_interrupt_in: 0, - num_bulk_in: 2, - num_bulk_out: 2, - num_ports: 2, - open: visor_open, - close: visor_close, - throttle: visor_throttle, - unthrottle: visor_unthrottle, - startup: visor_startup, - shutdown: visor_shutdown, - ioctl: visor_ioctl, - set_termios: visor_set_termios, - write: visor_write, - write_room: visor_write_room, - chars_in_buffer: visor_chars_in_buffer, - write_bulk_callback: visor_write_bulk_callback, - read_bulk_callback: visor_read_bulk_callback, -}; - -/* device info for the Palm 4.0 devices */ -struct usb_serial_device_type palm_4_0_device = { - name: "Palm 4.0", - id_table: palm_4_0_id_table, - needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ +/* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ +static struct usb_serial_device_type handspring_device = { + name: "Handspring Visor / Palm 4.0 / Clié 4.0", + id_table: combined_id_table, num_interrupt_in: 0, num_bulk_in: 2, num_bulk_out: 2, @@ -235,14 +198,10 @@ read_bulk_callback: visor_read_bulk_callback, }; - /* device info for the Sony Clie OS version 3.5 */ static struct usb_serial_device_type clie_3_5_device = { name: "Sony Clié 3.5", id_table: clie_id_3_5_table, - needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ num_interrupt_in: 0, num_bulk_in: 1, num_bulk_out: 1, @@ -260,31 +219,6 @@ read_bulk_callback: visor_read_bulk_callback, }; -/* device info for the Sony Clie OS version 4.0 */ -static struct usb_serial_device_type clie_4_0_device = { - name: "Sony Clié 4.0", - id_table: clie_id_4_0_table, - needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */ - needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ - needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ - num_interrupt_in: 0, - num_bulk_in: 2, - num_bulk_out: 2, - num_ports: 2, - open: visor_open, - close: visor_close, - throttle: visor_throttle, - unthrottle: visor_unthrottle, - startup: visor_startup, - shutdown: visor_shutdown, - ioctl: visor_ioctl, - set_termios: visor_set_termios, - write: visor_write, - write_room: visor_write_room, - chars_in_buffer: visor_chars_in_buffer, - write_bulk_callback: visor_write_bulk_callback, - read_bulk_callback: visor_read_bulk_callback, -}; #define NUM_URBS 24 #define URB_TRANSFER_BUFFER_SIZE 768 @@ -317,8 +251,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; + if (port->open_count == 1) { bytes_in = 0; bytes_out = 0; @@ -328,10 +261,12 @@ port->tty->low_latency = 1; /* Start reading from the device */ - FILL_BULK_URB(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, - visor_read_bulk_callback, port); + usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_rcvbulkpipe (serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + visor_read_bulk_callback, port); result = usb_submit_urb(port->read_urb); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); @@ -380,7 +315,6 @@ /* shutdown our bulk read */ usb_unlink_urb (port->read_urb); } - port->active = 0; port->open_count = 0; } up (&port->sem); @@ -441,8 +375,11 @@ usb_serial_debug_data (__FILE__, __FUNCTION__, transfer_size, urb->transfer_buffer); /* build up our urb */ - FILL_BULK_URB (urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), - urb->transfer_buffer, transfer_size, visor_write_bulk_callback, port); + usb_fill_bulk_urb (urb, serial->dev, + usb_sndbulkpipe (serial->dev, + port->bulk_out_endpointAddress), + urb->transfer_buffer, transfer_size, + visor_write_bulk_callback, port); urb->transfer_flags |= USB_QUEUE_BULK; /* send it down the pipe */ @@ -572,10 +509,12 @@ } /* Continue trying to always read */ - FILL_BULK_URB(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, - visor_read_bulk_callback, port); + usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_rcvbulkpipe (serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + visor_read_bulk_callback, port); result = usb_submit_urb(port->read_urb); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); @@ -713,11 +652,8 @@ dbg (__FUNCTION__); /* stop reads and writes on all ports */ - for (i=0; i < serial->num_ports; ++i) { - while (serial->port[i].open_count > 0) { - visor_close (&serial->port[i], NULL); - } - } + for (i=0; i < serial->num_ports; ++i) + serial->port[i].open_count = 0; } @@ -801,9 +737,7 @@ int i; usb_serial_register (&handspring_device); - usb_serial_register (&palm_4_0_device); usb_serial_register (&clie_3_5_device); - usb_serial_register (&clie_4_0_device); /* create our write urb pool and transfer buffers */ spin_lock_init (&write_urb_pool_lock); @@ -835,9 +769,7 @@ unsigned long flags; usb_serial_deregister (&handspring_device); - usb_serial_deregister (&palm_4_0_device); usb_serial_deregister (&clie_3_5_device); - usb_serial_deregister (&clie_4_0_device); spin_lock_irqsave (&write_urb_pool_lock, flags); diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/whiteheat.c linux/drivers/usb/serial/whiteheat.c --- v2.5.0/linux/drivers/usb/serial/whiteheat.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/serial/whiteheat.c Sat Dec 8 20:28:45 2001 @@ -88,7 +88,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.1" +#define DRIVER_VERSION "v1.2" #define DRIVER_AUTHOR "Greg Kroah-Hartman " #define DRIVER_DESC "USB ConnectTech WhiteHEAT driver" @@ -128,28 +128,23 @@ static void whiteheat_set_termios (struct usb_serial_port *port, struct termios * old); static void whiteheat_throttle (struct usb_serial_port *port); static void whiteheat_unthrottle (struct usb_serial_port *port); -static int whiteheat_startup (struct usb_serial *serial); -static void whiteheat_shutdown (struct usb_serial *serial); +static int whiteheat_fake_startup (struct usb_serial *serial); +static int whiteheat_real_startup (struct usb_serial *serial); +static void whiteheat_real_shutdown (struct usb_serial *serial); -struct usb_serial_device_type whiteheat_fake_device = { +static struct usb_serial_device_type whiteheat_fake_device = { name: "Connect Tech - WhiteHEAT - (prerenumeration)", id_table: id_table_prerenumeration, - needs_interrupt_in: DONT_CARE, /* don't have to have an interrupt in endpoint */ - needs_bulk_in: DONT_CARE, /* don't have to have a bulk in endpoint */ - needs_bulk_out: DONT_CARE, /* don't have to have a bulk out endpoint */ num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, num_ports: 1, - startup: whiteheat_startup + startup: whiteheat_fake_startup, }; -struct usb_serial_device_type whiteheat_device = { +static struct usb_serial_device_type whiteheat_device = { name: "Connect Tech - WhiteHEAT", id_table: id_table_std, - needs_interrupt_in: DONT_CARE, /* don't have to have an interrupt in endpoint */ - needs_bulk_in: DONT_CARE, /* don't have to have a bulk in endpoint */ - needs_bulk_out: DONT_CARE, /* don't have to have a bulk out endpoint */ num_interrupt_in: NUM_DONT_CARE, num_bulk_in: NUM_DONT_CARE, num_bulk_out: NUM_DONT_CARE, @@ -160,7 +155,8 @@ unthrottle: whiteheat_unthrottle, ioctl: whiteheat_ioctl, set_termios: whiteheat_set_termios, - shutdown: whiteheat_shutdown, + startup: whiteheat_real_startup, + shutdown: whiteheat_real_shutdown, }; struct whiteheat_private { @@ -313,9 +309,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /* set up some stuff for our command port */ command_port = &port->serial->port[COMMAND_PORT]; if (command_port->private == NULL) { @@ -395,7 +389,7 @@ /* shutdown our bulk reads and writes */ usb_unlink_urb (port->write_urb); usb_unlink_urb (port->read_urb); - port->active = 0; + port->open_count = 0; } MOD_DEC_USE_COUNT; up (&port->sem); @@ -539,7 +533,7 @@ - device renumerated itself and comes up as new device id with all firmware download completed. */ -static int whiteheat_startup (struct usb_serial *serial) +static int whiteheat_fake_startup (struct usb_serial *serial) { int response; const struct whiteheat_hex_record *record; @@ -598,7 +592,66 @@ } -static void whiteheat_shutdown (struct usb_serial *serial) +static int whiteheat_real_startup (struct usb_serial *serial) +{ + struct whiteheat_hw_info *hw_info; + int pipe; + int ret; + int alen; + __u8 command[2] = { WHITEHEAT_GET_HW_INFO, 0 }; + __u8 result[sizeof(*hw_info) + 1]; + + pipe = usb_rcvbulkpipe (serial->dev, 7); + usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ); + /* + * We ignore the return code. In the case where rmmod/insmod is + * performed with a WhiteHEAT connected, the above times out + * because the endpoint is already prepped, meaning the below succeeds + * regardless. All other cases the above succeeds. + */ + + pipe = usb_sndbulkpipe (serial->dev, 7); + ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, 2 * HZ); + if (ret) { + err("%s: Couldn't send command [%d]", serial->type->name, ret); + goto error_out; + } else if (alen != sizeof(command)) { + err("%s: Send command incomplete [%d]", serial->type->name, alen); + goto error_out; + } + + pipe = usb_rcvbulkpipe (serial->dev, 7); + ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ); + if (ret) { + err("%s: Couldn't get results [%d]", serial->type->name, ret); + goto error_out; + } else if (alen != sizeof(result)) { + err("%s: Get results incomplete [%d]", serial->type->name, alen); + goto error_out; + } else if (result[0] != command[0]) { + err("%s: Command failed [%d]", serial->type->name, result[0]); + goto error_out; + } + + hw_info = (struct whiteheat_hw_info *)&result[1]; + + info("%s: Driver %s: Firmware v%d.%02d", serial->type->name, + DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev); + + return 0; + +error_out: + err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name); + /* + * Return that we've claimed the interface. A failure here may be + * due to interception by the command_callback routine or other + * causes that don't mean that the firmware isn't running. This may + * change in the future. Probably should actually. + */ + return 0; +} + +static void whiteheat_real_shutdown (struct usb_serial *serial) { struct usb_serial_port *command_port; int i; @@ -660,7 +713,7 @@ { usb_serial_register (&whiteheat_fake_device); usb_serial_register (&whiteheat_device); - info(DRIVER_VERSION ":" DRIVER_DESC); + info(DRIVER_DESC " " DRIVER_VERSION); return 0; } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/serial/whiteheat_fw.h linux/drivers/usb/serial/whiteheat_fw.h --- v2.5.0/linux/drivers/usb/serial/whiteheat_fw.h Mon Oct 9 14:25:56 2000 +++ linux/drivers/usb/serial/whiteheat_fw.h Thu Nov 29 13:45:52 2001 @@ -47,28 +47,28 @@ }; static const struct whiteheat_hex_record whiteheat_firmware[] = { -{ 0x0000, 3, {0x02, 0x95, 0x09} }, +{ 0x0000, 3, {0x02, 0x95, 0xe7} }, { 0x0003, 3, {0x02, 0x13, 0x12} }, -{ 0x000b, 3, {0x02, 0x0a, 0x91} }, -{ 0x0033, 3, {0x02, 0x08, 0x1b} }, +{ 0x000b, 3, {0x02, 0x0b, 0xb5} }, +{ 0x0033, 3, {0x02, 0x08, 0x18} }, { 0x0043, 3, {0x02, 0x0a, 0x00} }, -{ 0x005b, 3, {0x02, 0x1a, 0xd2} }, +{ 0x005b, 3, {0x02, 0x11, 0xdd} }, { 0x0370, 16, {0x90, 0x7f, 0xe9, 0xe0, 0x70, 0x03, 0x02, 0x04, 0x73, 0x14, 0x70, 0x03, 0x02, 0x04, 0xe7, 0x24} }, { 0x0380, 16, {0xfe, 0x70, 0x03, 0x02, 0x05, 0x4f, 0x24, 0xfb, 0x70, 0x03, 0x02, 0x04, 0x64, 0x14, 0x70, 0x03} }, { 0x0390, 16, {0x02, 0x04, 0x52, 0x14, 0x70, 0x03, 0x02, 0x04, 0x3a, 0x14, 0x70, 0x03, 0x02, 0x04, 0x49, 0x24} }, { 0x03a0, 16, {0x05, 0x60, 0x03, 0x02, 0x05, 0x9e, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60} }, { 0x03b0, 16, {0x36, 0x24, 0x02, 0x70, 0x7b, 0x74, 0x12, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5} }, -{ 0x03c0, 16, {0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x81, 0xea, 0x49, 0x60, 0x0d} }, +{ 0x03c0, 16, {0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x99, 0xea, 0x49, 0x60, 0x0d} }, { 0x03d0, 16, {0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4} }, -{ 0x03e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x40, 0xea} }, -{ 0x03f0, 16, {0x49, 0x60, 0x33, 0x12, 0x9f, 0x48, 0xf5, 0x4b, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4b, 0xd3} }, -{ 0x0400, 16, {0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4b, 0x40} }, -{ 0x0410, 16, {0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4b, 0x12, 0x8e, 0x81, 0x90, 0x7f, 0xb5} }, -{ 0x0420, 16, {0xe5, 0x4b, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} }, +{ 0x03e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x58, 0xea} }, +{ 0x03f0, 16, {0x49, 0x60, 0x33, 0x12, 0xa0, 0x3f, 0xf5, 0x4c, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4c, 0xd3} }, +{ 0x0400, 16, {0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4c, 0xe5, 0x4c, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4c, 0x40} }, +{ 0x0410, 16, {0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4c, 0x12, 0x8f, 0x3b, 0x90, 0x7f, 0xb5} }, +{ 0x0420, 16, {0xe5, 0x4c, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} }, { 0x0430, 16, {0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x21, 0xf0} }, { 0x0440, 16, {0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x21, 0x02} }, -{ 0x0450, 16, {0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x31, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} }, -{ 0x0460, 16, {0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x31, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} }, +{ 0x0450, 16, {0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x32, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} }, +{ 0x0460, 16, {0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x32, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} }, { 0x0470, 16, {0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02} }, { 0x0480, 16, {0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x05, 0xe4, 0x33, 0x4f, 0x90} }, { 0x0490, 16, {0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0xe4} }, @@ -79,8 +79,8 @@ { 0x04e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24} }, { 0x04f0, 16, {0x02, 0x60, 0x03, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02} }, { 0x0500, 16, {0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0} }, -{ 0x0510, 16, {0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4b, 0xef, 0x30, 0xe7, 0x03} }, -{ 0x0520, 16, {0x43, 0x4b, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4b, 0xf0, 0xe5, 0x4b, 0x44, 0x20, 0xf0, 0xef, 0xf4} }, +{ 0x0510, 16, {0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4c, 0xef, 0x30, 0xe7, 0x03} }, +{ 0x0520, 16, {0x43, 0x4c, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4c, 0xf0, 0xe5, 0x4c, 0x44, 0x20, 0xf0, 0xef, 0xf4} }, { 0x0530, 16, {0x54, 0x80, 0xfd, 0xc4, 0x54, 0x0f, 0x2e, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f} }, { 0x0540, 16, {0xf5, 0x83, 0xe4, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90} }, { 0x0550, 16, {0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4} }, @@ -90,229 +90,226 @@ { 0x0590, 16, {0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f} }, { 0x05a0, 12, {0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} }, { 0x05ac, 1, {0x22} }, -{ 0x05ad, 16, {0x75, 0x47, 0xff, 0x75, 0x46, 0xff, 0x75, 0x45, 0x0f, 0x75, 0x44, 0x00, 0xd2, 0x03, 0xc2, 0x06} }, +{ 0x05ad, 16, {0x75, 0x48, 0xff, 0x75, 0x47, 0xff, 0x75, 0x46, 0x0f, 0x75, 0x45, 0x00, 0xd2, 0x03, 0xc2, 0x06} }, { 0x05bd, 16, {0xc2, 0x02, 0xc2, 0x00, 0xc2, 0x05, 0xc2, 0x01, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xe4, 0x90} }, { 0x05cd, 16, {0x01, 0xbc, 0xf0, 0xc2, 0x04, 0x90, 0x01, 0xc0, 0xf0, 0xa3, 0xf0, 0xc2, 0xaf, 0xc2, 0xa8, 0x12} }, -{ 0x05dd, 16, {0x0b, 0x8d, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} }, +{ 0x05dd, 16, {0x0c, 0x22, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} }, { 0x05ed, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0x7e} }, -{ 0x05fd, 16, {0x01, 0x7f, 0x00, 0x12, 0x10, 0x2c, 0x75, 0x49, 0x12, 0x75, 0x4a, 0x0a, 0x90, 0x01, 0x0b, 0xe0} }, -{ 0x060d, 16, {0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83} }, -{ 0x061d, 16, {0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} }, -{ 0x062d, 16, {0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} }, -{ 0x063d, 16, {0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, -{ 0x064d, 16, {0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} }, +{ 0x05fd, 16, {0x01, 0x7f, 0x00, 0x12, 0x19, 0xc1, 0x75, 0x4a, 0x12, 0x75, 0x4b, 0x0a, 0x90, 0x01, 0x0b, 0xe0} }, +{ 0x060d, 16, {0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83} }, +{ 0x061d, 16, {0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70} }, +{ 0x062d, 16, {0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} }, +{ 0x063d, 16, {0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, +{ 0x064d, 16, {0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14} }, { 0x065d, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x12, 0x0a, 0xe4, 0x93, 0xff, 0x74, 0x01, 0x93, 0x90} }, { 0x066d, 16, {0x01, 0x1c, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0xff, 0xa3, 0xe0, 0xfe, 0xef} }, { 0x067d, 16, {0x6e, 0xff, 0x90, 0x01, 0x1c, 0xf0, 0xa3, 0xe0, 0x6f, 0xff, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0x6f} }, -{ 0x068d, 16, {0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x4f, 0x10, 0x75, 0x50, 0x02, 0x75} }, -{ 0x069d, 16, {0x51, 0x12, 0x75, 0x52, 0xac, 0x12, 0x91, 0x7a, 0x75, 0x49, 0x12, 0x75, 0x4a, 0xb2, 0x90, 0x01} }, -{ 0x06ad, 16, {0x0d, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82} }, -{ 0x06bd, 16, {0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} }, -{ 0x06cd, 16, {0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} }, -{ 0x06dd, 16, {0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} }, -{ 0x06ed, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4a, 0xe5, 0x4a, 0xae, 0x49, 0x70, 0x02, 0x05, 0x49} }, +{ 0x068d, 16, {0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x50, 0x10, 0x75, 0x51, 0x02, 0x75} }, +{ 0x069d, 16, {0x52, 0x12, 0x75, 0x53, 0xac, 0x12, 0x92, 0x2a, 0x75, 0x4a, 0x12, 0x75, 0x4b, 0xb2, 0x90, 0x01} }, +{ 0x06ad, 16, {0x0d, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82} }, +{ 0x06bd, 16, {0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70} }, +{ 0x06cd, 16, {0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} }, +{ 0x06dd, 16, {0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14} }, +{ 0x06ed, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xae, 0x4a, 0x70, 0x02, 0x05, 0x4a} }, { 0x06fd, 16, {0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x75, 0x82, 0x10, 0x75, 0x83, 0x01, 0xe0, 0xfc, 0xa3} }, -{ 0x070d, 16, {0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0xa0, 0xfb, 0x7e, 0x01} }, -{ 0x071d, 16, {0x7f, 0x18, 0x12, 0x85, 0x2f, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, -{ 0x072d, 16, {0xa3, 0xe0, 0xff, 0x75, 0x4f, 0x0a, 0x75, 0x50, 0x06, 0x75, 0x51, 0x12, 0x75, 0x52, 0xb8, 0x12} }, -{ 0x073d, 16, {0x91, 0x7a, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} }, +{ 0x070d, 16, {0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0xa1, 0xf2, 0x7e, 0x01} }, +{ 0x071d, 16, {0x7f, 0x18, 0x12, 0x85, 0xcf, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, +{ 0x072d, 16, {0xa3, 0xe0, 0xff, 0x75, 0x50, 0x0a, 0x75, 0x51, 0x06, 0x75, 0x52, 0x12, 0x75, 0x53, 0xb8, 0x12} }, +{ 0x073d, 16, {0x92, 0x2a, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} }, { 0x074d, 16, {0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x1f, 0xf0, 0xd2, 0xaf} }, -{ 0x075d, 16, {0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xd0, 0x75, 0x43, 0x50} }, -{ 0x076d, 16, {0x75, 0x42, 0x6d, 0x75, 0x41, 0x33, 0x75, 0x40, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} }, -{ 0x077d, 16, {0x7d, 0xff, 0x7c, 0xff, 0x78, 0x40, 0x12, 0xa0, 0xe4, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} }, -{ 0x078d, 16, {0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0d, 0x12, 0x09, 0xf5, 0x50} }, -{ 0x079d, 16, {0x06, 0x12, 0x0b, 0x00, 0x12, 0x09, 0xfa, 0xc2, 0x06, 0x12, 0x93, 0x98, 0x90, 0x01, 0xbd, 0xe0} }, -{ 0x07ad, 16, {0x60, 0x0c, 0x12, 0x8f, 0x55, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x02} }, -{ 0x07bd, 16, {0xaf, 0xe0, 0xb4, 0x0f, 0x03, 0x12, 0x96, 0xe2, 0x12, 0x9d, 0xa2, 0xe4, 0xff, 0x74, 0x01, 0xa8} }, -{ 0x07cd, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60, 0x14} }, -{ 0x07dd, 16, {0x74, 0x27, 0x2f, 0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00} }, -{ 0x07ed, 16, {0x8e, 0x48, 0x80, 0x03, 0x75, 0x48, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5} }, -{ 0x07fd, 16, {0x83, 0xe5, 0x48, 0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7f} }, -{ 0x080d, 13, {0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x8e} }, -{ 0x081a, 1, {0x22} }, -{ 0x081b, 4, {0x53, 0xd8, 0xef, 0x32} }, -{ 0x081f, 16, {0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x7f, 0x0a, 0xfe, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0x74, 0x89} }, -{ 0x082f, 16, {0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0x29, 0x90, 0x7f} }, -{ 0x083f, 16, {0x96, 0xe0, 0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x02, 0x7d, 0xff} }, -{ 0x084f, 16, {0x12, 0x11, 0x77, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x02} }, -{ 0x085f, 16, {0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0} }, -{ 0x086f, 16, {0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf} }, -{ 0x087f, 16, {0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0, 0x7f} }, -{ 0x088f, 7, {0x32, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x22} }, -{ 0x0896, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} }, -{ 0x08a6, 16, {0x09, 0x29, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x11, 0x77, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29} }, -{ 0x08b6, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f} }, -{ 0x08c6, 16, {0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0} }, -{ 0x08d6, 16, {0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01} }, -{ 0x08e6, 12, {0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x12, 0x0b, 0x00, 0x22} }, -{ 0x08f2, 16, {0x90, 0x95, 0xbe, 0xe4, 0x93, 0x70, 0x2f, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} }, -{ 0x0902, 16, {0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90, 0x7f} }, -{ 0x0912, 16, {0x9d, 0x74, 0x02, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12, 0xf0, 0x12, 0x08, 0x1f, 0x75, 0x82, 0xbe} }, -{ 0x0922, 7, {0x75, 0x83, 0x95, 0x74, 0xff, 0xf0, 0x22} }, -{ 0x0929, 16, {0x8e, 0x58, 0x8f, 0x59, 0xe5, 0x59, 0x15, 0x59, 0xae, 0x58, 0x70, 0x02, 0x15, 0x58, 0x4e, 0x60} }, -{ 0x0939, 7, {0x05, 0x12, 0x0a, 0x58, 0x80, 0xee, 0x22} }, -{ 0x0940, 2, {0x8f, 0x4c} }, -{ 0x0942, 16, {0xe4, 0xf5, 0x4d, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x6a, 0xab, 0x4e, 0xaa, 0x4f} }, -{ 0x0952, 16, {0xa9, 0x50, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0xb4, 0x03, 0x1d, 0xaf, 0x4d, 0x05, 0x4d, 0xef} }, -{ 0x0962, 16, {0xb5, 0x4c, 0x01, 0x22, 0x12, 0x9f, 0x48, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} }, -{ 0x0972, 14, {0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x0980, 1, {0x22} }, -{ 0x0981, 16, {0xe4, 0xfe, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x12, 0xab, 0x4e, 0xaa, 0x4f, 0xa9} }, -{ 0x0991, 16, {0x50, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} }, -{ 0x09a1, 16, {0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x9f, 0xba, 0x85, 0xf0, 0x4c, 0xf5, 0x4d, 0x62, 0x4c} }, -{ 0x09b1, 16, {0xe5, 0x4c, 0x62, 0x4d, 0xe5, 0x4d, 0x62, 0x4c, 0x29, 0xfd, 0xe5, 0x4c, 0x3a, 0xa9, 0x05, 0x75} }, -{ 0x09c1, 14, {0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x09cf, 1, {0x22} }, -{ 0x09d0, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} }, -{ 0x09e0, 16, {0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0x29, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} }, -{ 0x09f0, 5, {0xe0, 0x44, 0x04, 0xf0, 0x22} }, -{ 0x09f5, 5, {0x12, 0x08, 0x96, 0xd3, 0x22} }, -{ 0x09fa, 5, {0x12, 0x08, 0x1f, 0xd3, 0x22} }, +{ 0x075d, 16, {0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xc1, 0x75, 0x44, 0x50} }, +{ 0x076d, 16, {0x75, 0x43, 0x6d, 0x75, 0x42, 0x33, 0x75, 0x41, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} }, +{ 0x077d, 16, {0x7d, 0xff, 0x7c, 0xff, 0x78, 0x41, 0x12, 0xa1, 0xdb, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} }, +{ 0x078d, 16, {0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0a, 0x12, 0x09, 0xf7, 0x50} }, +{ 0x079d, 16, {0x03, 0x12, 0x0a, 0xe8, 0xc2, 0x06, 0x12, 0x94, 0x62, 0x90, 0x01, 0xbd, 0xe0, 0x60, 0x0c, 0x12} }, +{ 0x07ad, 16, {0x90, 0x05, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x02, 0xaf, 0xe0, 0xb4} }, +{ 0x07bd, 16, {0x0f, 0x03, 0x12, 0x97, 0xbd, 0x12, 0x9e, 0x99, 0xe4, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80} }, +{ 0x07cd, 16, {0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60, 0x14, 0x74, 0x27, 0x2f} }, +{ 0x07dd, 16, {0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0x8e, 0x49, 0x80} }, +{ 0x07ed, 16, {0x03, 0x75, 0x49, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe5, 0x49} }, +{ 0x07fd, 16, {0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7f, 0x01, 0x80, 0x02} }, +{ 0x080d, 10, {0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x8e} }, +{ 0x0817, 1, {0x22} }, +{ 0x0818, 4, {0x53, 0xd8, 0xef, 0x32} }, +{ 0x081c, 16, {0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x44, 0x30, 0xf0, 0x90, 0x7f} }, +{ 0x082c, 16, {0x95, 0xe0, 0x44, 0xc0, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0} }, +{ 0x083c, 16, {0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x08} }, +{ 0x084c, 16, {0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfb, 0xf0, 0x7f} }, +{ 0x085c, 16, {0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0x7d} }, +{ 0x086c, 16, {0xff, 0x12, 0x82, 0xa8, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44} }, +{ 0x087c, 16, {0x02, 0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96} }, +{ 0x088c, 16, {0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54} }, +{ 0x089c, 16, {0xbf, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0} }, +{ 0x08ac, 8, {0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x22} }, +{ 0x08b4, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} }, +{ 0x08c4, 16, {0x09, 0xaa, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x82, 0xa8} }, +{ 0x08d4, 16, {0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05} }, +{ 0x08e4, 16, {0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00} }, +{ 0x08f4, 16, {0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09} }, +{ 0x0904, 16, {0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0xe5} }, +{ 0x0914, 16, {0x30, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x54, 0xcf, 0xf0, 0x90, 0x7f, 0x95} }, +{ 0x0924, 8, {0xe0, 0x54, 0x3f, 0xf0, 0x12, 0x0b, 0x00, 0x22} }, +{ 0x092c, 16, {0x90, 0x0a, 0xf0, 0xe4, 0x93, 0x70, 0x76, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} }, +{ 0x093c, 16, {0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa} }, +{ 0x094c, 16, {0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x08, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf} }, +{ 0x095c, 16, {0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x20, 0x70, 0xe0, 0xff, 0xc4, 0x54, 0x0f} }, +{ 0x096c, 16, {0xf5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x07, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x80, 0xf0, 0xe4, 0x90} }, +{ 0x097c, 16, {0x7f, 0x97, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0b} }, +{ 0x098c, 16, {0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12} }, +{ 0x099c, 14, {0xf0, 0x12, 0x08, 0x1c, 0x75, 0x82, 0xf0, 0x75, 0x83, 0x0a, 0x74, 0xff, 0xf0, 0x22} }, +{ 0x09aa, 16, {0x8e, 0x5b, 0x8f, 0x5c, 0xe5, 0x5c, 0x15, 0x5c, 0xae, 0x5b, 0x70, 0x02, 0x15, 0x5b, 0x4e, 0x60} }, +{ 0x09ba, 7, {0x05, 0x12, 0x09, 0xe6, 0x80, 0xee, 0x22} }, +{ 0x09c1, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} }, +{ 0x09d1, 16, {0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} }, +{ 0x09e1, 5, {0xe0, 0x44, 0x04, 0xf0, 0x22} }, +{ 0x09e6, 16, {0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} }, +{ 0x09f6, 1, {0x22} }, +{ 0x09f7, 5, {0x12, 0x08, 0xb4, 0xd3, 0x22} }, +{ 0x09fc, 1, {0x32} }, +{ 0x09fd, 1, {0x32} }, +{ 0x09fe, 1, {0x32} }, { 0x09ff, 1, {0x32} }, -{ 0x0a00, 16, {0x02, 0x0b, 0xaa, 0x00, 0x02, 0x0b, 0xdd, 0x00, 0x02, 0x0b, 0xc2, 0x00, 0x02, 0x0c, 0x1c, 0x00} }, -{ 0x0a10, 16, {0x02, 0x0c, 0x06, 0x00, 0x02, 0x09, 0xff, 0x00, 0x02, 0x0a, 0xfe, 0x00, 0x02, 0x0a, 0xff, 0x00} }, -{ 0x0a20, 16, {0x02, 0x0c, 0x37, 0x00, 0x02, 0x0d, 0x29, 0x00, 0x02, 0x0c, 0x73, 0x00, 0x02, 0x0d, 0x7d, 0x00} }, -{ 0x0a30, 16, {0x02, 0x0c, 0xaf, 0x00, 0x02, 0x0d, 0xd1, 0x00, 0x02, 0x0c, 0xeb, 0x00, 0x02, 0x0e, 0x25, 0x00} }, -{ 0x0a40, 16, {0x02, 0x0d, 0x27, 0x00, 0x02, 0x0e, 0x79, 0x00, 0x02, 0x0d, 0x28, 0x00, 0x02, 0x0e, 0x7a, 0x00} }, -{ 0x0a50, 8, {0x02, 0x0e, 0x7b, 0x00, 0x02, 0x0e, 0x91, 0x00} }, -{ 0x0a58, 16, {0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} }, -{ 0x0a68, 1, {0x22} }, -{ 0x0a69, 16, {0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} }, -{ 0x0a79, 16, {0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} }, -{ 0x0a89, 7, {0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} }, -{ 0x0a90, 1, {0x22} }, -{ 0x0a91, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} }, -{ 0x0aa1, 1, {0x07} }, -{ 0x0aa2, 16, {0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} }, -{ 0x0ab2, 16, {0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} }, -{ 0x0ac2, 16, {0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} }, -{ 0x0ad2, 16, {0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} }, -{ 0x0ae2, 13, {0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} }, -{ 0x0aef, 15, {0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0afe, 1, {0x32} }, -{ 0x0aff, 1, {0x32} }, +{ 0x0a00, 16, {0x02, 0x0c, 0x4e, 0x00, 0x02, 0x0c, 0x81, 0x00, 0x02, 0x0c, 0x66, 0x00, 0x02, 0x0c, 0xc0, 0x00} }, +{ 0x0a10, 16, {0x02, 0x0c, 0xaa, 0x00, 0x02, 0x09, 0xfc, 0x00, 0x02, 0x09, 0xfd, 0x00, 0x02, 0x09, 0xfe, 0x00} }, +{ 0x0a20, 16, {0x02, 0x0c, 0xdb, 0x00, 0x02, 0x0d, 0xcb, 0x00, 0x02, 0x0d, 0x17, 0x00, 0x02, 0x0e, 0x1f, 0x00} }, +{ 0x0a30, 16, {0x02, 0x0d, 0x53, 0x00, 0x02, 0x0e, 0x73, 0x00, 0x02, 0x0d, 0x8f, 0x00, 0x02, 0x0e, 0xc7, 0x00} }, +{ 0x0a40, 16, {0x02, 0x09, 0xff, 0x00, 0x02, 0x0a, 0xee, 0x00, 0x02, 0x0a, 0xed, 0x00, 0x02, 0x0a, 0xef, 0x00} }, +{ 0x0a50, 8, {0x02, 0x0f, 0x1b, 0x00, 0x02, 0x0f, 0x31, 0x00} }, +{ 0x0a58, 2, {0x8f, 0x4d} }, +{ 0x0a5a, 16, {0xe4, 0xf5, 0x4e, 0x75, 0x4f, 0xff, 0x75, 0x50, 0x12, 0x75, 0x51, 0x6a, 0xab, 0x4f, 0xaa, 0x50} }, +{ 0x0a6a, 16, {0xa9, 0x51, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0xb4, 0x03, 0x1d, 0xaf, 0x4e, 0x05, 0x4e, 0xef} }, +{ 0x0a7a, 16, {0xb5, 0x4d, 0x01, 0x22, 0x12, 0xa0, 0x3f, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} }, +{ 0x0a8a, 14, {0x4f, 0xff, 0xf5, 0x50, 0x89, 0x51, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, +{ 0x0a98, 1, {0x22} }, +{ 0x0a99, 16, {0xe4, 0xfe, 0x75, 0x4f, 0xff, 0x75, 0x50, 0x12, 0x75, 0x51, 0x12, 0xab, 0x4f, 0xaa, 0x50, 0xa9} }, +{ 0x0aa9, 16, {0x51, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} }, +{ 0x0ab9, 16, {0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0xa0, 0xb1, 0x85, 0xf0, 0x4d, 0xf5, 0x4e, 0x62, 0x4d} }, +{ 0x0ac9, 16, {0xe5, 0x4d, 0x62, 0x4e, 0xe5, 0x4e, 0x62, 0x4d, 0x29, 0xfd, 0xe5, 0x4d, 0x3a, 0xa9, 0x05, 0x75} }, +{ 0x0ad9, 14, {0x4f, 0xff, 0xf5, 0x50, 0x89, 0x51, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, +{ 0x0ae7, 1, {0x22} }, +{ 0x0ae8, 5, {0x12, 0x08, 0x1c, 0xd3, 0x22} }, +{ 0x0aed, 1, {0x32} }, +{ 0x0aee, 1, {0x32} }, +{ 0x0aef, 1, {0x32} }, +{ 0x0af0, 3, {0x00, 0x04, 0x00} }, { 0x0b00, 9, {0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x74} }, { 0x0b7d, 16, {0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} }, -{ 0x0b8d, 16, {0xd2, 0x00, 0x75, 0x8e, 0x10, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12, 0x08, 0xf2} }, -{ 0x0b9d, 13, {0x12, 0x0e, 0xad, 0x12, 0x11, 0xe5, 0x12, 0x11, 0xc8, 0x12, 0x0a, 0x69, 0x22} }, -{ 0x0baa, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} }, -{ 0x0bba, 8, {0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0bc2, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0bd2, 11, {0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0bdd, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0x90} }, -{ 0x0bed, 16, {0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2b, 0x70, 0x03, 0x75} }, -{ 0x0bfd, 9, {0x2b, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0c06, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} }, -{ 0x0c16, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0c1c, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x30, 0x02, 0x02, 0xd2, 0x06, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0c2c, 11, {0xab, 0x74, 0x08, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0c37, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0c47, 16, {0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0x30, 0xe0, 0x13, 0xe5, 0x3b, 0x30, 0xe0, 0x07, 0x90, 0x20} }, -{ 0x0c57, 16, {0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} }, -{ 0x0c67, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0c73, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0c83, 16, {0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x30, 0x30, 0xe1, 0x13, 0xe5, 0x3b, 0x30, 0xe1, 0x07, 0x90, 0x20} }, -{ 0x0c93, 16, {0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} }, -{ 0x0ca3, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0caf, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0cbf, 16, {0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x30, 0x30, 0xe2, 0x13, 0xe5, 0x3b, 0x30, 0xe2, 0x07, 0x90, 0x20} }, -{ 0x0ccf, 16, {0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} }, -{ 0x0cdf, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0ceb, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0cfb, 16, {0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x30, 0xe3, 0x13, 0xe5, 0x3b, 0x30, 0xe3, 0x07, 0x90, 0x20} }, -{ 0x0d0b, 16, {0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} }, -{ 0x0d1b, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d27, 1, {0x32} }, -{ 0x0d28, 1, {0x32} }, -{ 0x0d29, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0d39, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0x20} }, -{ 0x0d49, 16, {0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} }, -{ 0x0d59, 16, {0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, -{ 0x0d69, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, -{ 0x0d79, 4, {0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d7d, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0d8d, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x30, 0x20} }, -{ 0x0d9d, 16, {0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} }, -{ 0x0dad, 16, {0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, -{ 0x0dbd, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, -{ 0x0dcd, 4, {0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0dd1, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0de1, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x30, 0x20} }, -{ 0x0df1, 16, {0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} }, -{ 0x0e01, 16, {0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, -{ 0x0e11, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, -{ 0x0e21, 4, {0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0e25, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0e35, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x20} }, -{ 0x0e45, 16, {0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} }, -{ 0x0e55, 16, {0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, -{ 0x0e65, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, -{ 0x0e75, 4, {0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0e79, 1, {0x32} }, -{ 0x0e7a, 1, {0x32} }, -{ 0x0e7b, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} }, -{ 0x0e8b, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0e91, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} }, -{ 0x0ea1, 12, {0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0ead, 16, {0x90, 0x01, 0x20, 0x12, 0xa1, 0x07, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} }, -{ 0x0ebd, 16, {0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} }, -{ 0x0ecd, 16, {0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} }, -{ 0x0edd, 16, {0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} }, -{ 0x0eed, 16, {0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9f} }, -{ 0x0efd, 16, {0x1f, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x86, 0x17, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} }, -{ 0x0f0d, 16, {0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} }, -{ 0x0f1d, 16, {0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} }, -{ 0x0f2d, 16, {0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} }, -{ 0x0f3d, 16, {0xf5, 0x30, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} }, -{ 0x0f4d, 16, {0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} }, -{ 0x0f5d, 16, {0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x83, 0xb7, 0x90, 0x01, 0x1e} }, -{ 0x0f6d, 16, {0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3a, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0} }, -{ 0x0f7d, 16, {0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54} }, -{ 0x0f8d, 16, {0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xee, 0xf0, 0x74, 0x36} }, -{ 0x0f9d, 16, {0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x32, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c, 0x2f, 0xf8, 0xe4, 0xf6} }, -{ 0x0fad, 16, {0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0} }, -{ 0x0fbd, 16, {0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0x4b, 0x60, 0x5e} }, -{ 0x0fcd, 4, {0xe4, 0x90, 0x01, 0x1e} }, -{ 0x0fd1, 16, {0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08} }, -{ 0x0fe1, 16, {0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4b, 0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75} }, -{ 0x0ff1, 16, {0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75} }, -{ 0x1001, 16, {0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0} }, -{ 0x1011, 16, {0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12} }, -{ 0x1021, 11, {0x83, 0x2d, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xa7, 0x22} }, -{ 0x102c, 4, {0xad, 0x07, 0xac, 0x06} }, -{ 0x1030, 16, {0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} }, -{ 0x1040, 16, {0x4a, 0x70, 0x03, 0x02, 0x11, 0x74, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x11, 0x46, 0x90} }, -{ 0x1050, 16, {0x10, 0x56, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x11, 0x24, 0x02, 0x10, 0xdc, 0x02, 0x10, 0xc5, 0x02} }, -{ 0x1060, 16, {0x10, 0xab, 0x02, 0x10, 0x9a, 0x02, 0x10, 0x85, 0x02, 0x10, 0x6b, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x1070, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} }, -{ 0x1080, 16, {0xf0, 0x19, 0x02, 0x11, 0x46, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} }, -{ 0x1090, 16, {0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x11, 0x46, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} }, -{ 0x10a0, 16, {0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x11, 0x46, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x10b0, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} }, -{ 0x10c0, 16, {0xf0, 0x19, 0x02, 0x11, 0x46, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x10d0, 16, {0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x54, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} }, -{ 0x10e0, 16, {0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} }, -{ 0x10f0, 16, {0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} }, -{ 0x1100, 16, {0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83} }, -{ 0x1110, 16, {0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} }, -{ 0x1120, 16, {0x9f, 0x8e, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} }, -{ 0x1130, 16, {0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} }, -{ 0x1140, 16, {0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x54, 0x30, 0xe0, 0xf7, 0x30} }, -{ 0x1150, 16, {0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} }, -{ 0x1160, 16, {0x10, 0x32, 0xe5, 0x54, 0x30, 0xe1, 0x03, 0x02, 0x10, 0x32, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} }, -{ 0x1170, 6, {0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} }, -{ 0x1176, 1, {0x22} }, -{ 0x1177, 2, {0xae, 0x07} }, -{ 0x1179, 16, {0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} }, -{ 0x1189, 16, {0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} }, -{ 0x1199, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} }, -{ 0x11a9, 16, {0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} }, -{ 0x11b9, 14, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} }, -{ 0x11c7, 1, {0x22} }, -{ 0x11c8, 16, {0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x02, 0x7d, 0xff, 0x12, 0x11, 0x77, 0x7f, 0x05} }, -{ 0x11d8, 13, {0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x03, 0x7d, 0xff, 0x12, 0x11, 0x77, 0x22} }, -{ 0x11e5, 16, {0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} }, -{ 0x11f5, 10, {0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} }, +{ 0x0b8d, 16, {0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} }, +{ 0x0b9d, 16, {0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} }, +{ 0x0bad, 7, {0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} }, +{ 0x0bb4, 1, {0x22} }, +{ 0x0bb5, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} }, +{ 0x0bc5, 1, {0x07} }, +{ 0x0bc6, 16, {0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} }, +{ 0x0bd6, 16, {0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} }, +{ 0x0be6, 16, {0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} }, +{ 0x0bf6, 16, {0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} }, +{ 0x0c06, 13, {0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} }, +{ 0x0c13, 15, {0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0c22, 16, {0xd2, 0x00, 0x75, 0x8e, 0x10, 0x12, 0x09, 0x2c, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x08, 0x90} }, +{ 0x0c32, 16, {0x7f, 0x92, 0x74, 0x02, 0xf0, 0x80, 0x05, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12} }, +{ 0x0c42, 12, {0x0f, 0x4d, 0x12, 0x92, 0xfb, 0x12, 0x1b, 0x0c, 0x12, 0x0b, 0x8d, 0x22} }, +{ 0x0c4e, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} }, +{ 0x0c5e, 8, {0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0c66, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} }, +{ 0x0c76, 11, {0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0c81, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0x90} }, +{ 0x0c91, 16, {0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2b, 0x70, 0x03, 0x75} }, +{ 0x0ca1, 9, {0x2b, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0caa, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} }, +{ 0x0cba, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0cc0, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x30, 0x02, 0x02, 0xd2, 0x06, 0x53, 0x91, 0xef, 0x90, 0x7f} }, +{ 0x0cd0, 11, {0xab, 0x74, 0x08, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0cdb, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, +{ 0x0ceb, 16, {0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x31, 0x30, 0xe0, 0x13, 0xe5, 0x3c, 0x30, 0xe0, 0x07, 0x90, 0x20} }, +{ 0x0cfb, 16, {0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} }, +{ 0x0d0b, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0d17, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, +{ 0x0d27, 16, {0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x31, 0x30, 0xe1, 0x13, 0xe5, 0x3c, 0x30, 0xe1, 0x07, 0x90, 0x20} }, +{ 0x0d37, 16, {0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} }, +{ 0x0d47, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0d53, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, +{ 0x0d63, 16, {0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x31, 0x30, 0xe2, 0x13, 0xe5, 0x3c, 0x30, 0xe2, 0x07, 0x90, 0x20} }, +{ 0x0d73, 16, {0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} }, +{ 0x0d83, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0d8f, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, +{ 0x0d9f, 16, {0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x31, 0x30, 0xe3, 0x13, 0xe5, 0x3c, 0x30, 0xe3, 0x07, 0x90, 0x20} }, +{ 0x0daf, 16, {0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} }, +{ 0x0dbf, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0dcb, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, +{ 0x0ddb, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x31, 0x20} }, +{ 0x0deb, 16, {0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} }, +{ 0x0dfb, 16, {0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, +{ 0x0e0b, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, +{ 0x0e1b, 4, {0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0e1f, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, +{ 0x0e2f, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x31, 0x20} }, +{ 0x0e3f, 16, {0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} }, +{ 0x0e4f, 16, {0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, +{ 0x0e5f, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, +{ 0x0e6f, 4, {0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0e73, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, +{ 0x0e83, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x31, 0x20} }, +{ 0x0e93, 16, {0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} }, +{ 0x0ea3, 16, {0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, +{ 0x0eb3, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, +{ 0x0ec3, 4, {0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0ec7, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, +{ 0x0ed7, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x31, 0x20} }, +{ 0x0ee7, 16, {0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} }, +{ 0x0ef7, 16, {0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, +{ 0x0f07, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, +{ 0x0f17, 4, {0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0f1b, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} }, +{ 0x0f2b, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0f31, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} }, +{ 0x0f41, 12, {0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0f4d, 16, {0x90, 0x01, 0x20, 0x12, 0xa1, 0xfe, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} }, +{ 0x0f5d, 16, {0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} }, +{ 0x0f6d, 16, {0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} }, +{ 0x0f7d, 16, {0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} }, +{ 0x0f8d, 16, {0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa0} }, +{ 0x0f9d, 16, {0x16, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x86, 0xb7, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} }, +{ 0x0fad, 16, {0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} }, +{ 0x0fbd, 16, {0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} }, +{ 0x0fcd, 16, {0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} }, +{ 0x0fdd, 16, {0xf5, 0x31, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} }, +{ 0x0fed, 16, {0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} }, +{ 0x0ffd, 16, {0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x84, 0x08, 0x90, 0x01, 0x1e} }, +{ 0x100d, 16, {0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3b, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0} }, +{ 0x101d, 16, {0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54} }, +{ 0x102d, 16, {0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xee, 0xf0, 0x74, 0x37} }, +{ 0x103d, 16, {0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x33, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c, 0x2f, 0xf8, 0xe4, 0xf6} }, +{ 0x104d, 16, {0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0} }, +{ 0x105d, 16, {0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0x4c, 0x60, 0x5e} }, +{ 0x106d, 4, {0xe4, 0x90, 0x01, 0x1e} }, +{ 0x1071, 16, {0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08} }, +{ 0x1081, 16, {0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4c, 0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75} }, +{ 0x1091, 16, {0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75} }, +{ 0x10a1, 16, {0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0} }, +{ 0x10b1, 16, {0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12} }, +{ 0x10c1, 11, {0x83, 0x7e, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xa7, 0x22} }, +{ 0x10cc, 4, {0x8e, 0x57, 0x8f, 0x58} }, +{ 0x10d0, 16, {0x75, 0x59, 0x03, 0xe5, 0x58, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xfe} }, +{ 0x10e0, 16, {0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x11, 0xda, 0xe5, 0x59, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} }, +{ 0x10f0, 16, {0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x11, 0x7e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} }, +{ 0x1100, 16, {0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} }, +{ 0x1110, 16, {0x80, 0x6c, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} }, +{ 0x1120, 16, {0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x59, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3} }, +{ 0x1130, 16, {0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x58, 0x24, 0x06, 0xf5, 0x82} }, +{ 0x1140, 16, {0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5} }, +{ 0x1150, 16, {0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x58, 0x24} }, +{ 0x1160, 16, {0x04, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0xa0, 0x85, 0x85} }, +{ 0x1170, 16, {0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x85, 0x90, 0x7f} }, +{ 0x1180, 16, {0xa5, 0xe0, 0xf5, 0x5a, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} }, +{ 0x1190, 16, {0x22, 0xe5, 0x5a, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} }, +{ 0x11a0, 16, {0xe5, 0x59, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, +{ 0x11b0, 16, {0x80, 0xf0, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} }, +{ 0x11c0, 16, {0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x5a, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} }, +{ 0x11d0, 12, {0x59, 0x03, 0x02, 0x10, 0xd3, 0x15, 0x59, 0x02, 0x10, 0xd3, 0x7f, 0x08} }, +{ 0x11dc, 1, {0x22} }, +{ 0x11dd, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} }, +{ 0x11ed, 15, {0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, { 0x1200, 16, {0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40, 0x10, 0x07, 0x01, 0x80, 0x42, 0x00, 0x01, 0x02} }, { 0x1210, 16, {0x03, 0x01, 0x09, 0x02, 0x58, 0x00, 0x01, 0x01, 0x04, 0x80, 0x3c, 0x09, 0x04, 0x00, 0x00, 0x0a} }, { 0x1220, 16, {0xff, 0xff, 0xff, 0x05, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40} }, @@ -339,14 +336,14 @@ { 0x1362, 16, {0x75, 0x28, 0x14, 0x02, 0x15, 0x0d, 0xe5, 0x29, 0x70, 0x03, 0x75, 0x29, 0x14, 0x02, 0x16, 0x9e} }, { 0x1372, 16, {0xe5, 0x2a, 0x70, 0x03, 0x75, 0x2a, 0x14, 0x02, 0x18, 0x2f, 0x90, 0x20, 0x02, 0xe0, 0x54, 0x3f} }, { 0x1382, 16, {0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02, 0x13} }, -{ 0x1392, 16, {0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x36, 0x02, 0x13, 0x43} }, +{ 0x1392, 16, {0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x37, 0x02, 0x13, 0x43} }, { 0x13a2, 16, {0x43, 0x82, 0x04, 0xe0, 0x43, 0x2c, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x05} }, -{ 0x13b2, 16, {0xe0, 0x42, 0x32, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} }, -{ 0x13c2, 16, {0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} }, +{ 0x13b2, 16, {0xe0, 0x42, 0x33, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} }, +{ 0x13c2, 16, {0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} }, { 0x13d2, 16, {0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x00, 0xf0, 0x90, 0x20} }, { 0x13e2, 16, {0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05, 0x86} }, { 0x13f2, 16, {0x90, 0x7e, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90, 0x7f} }, -{ 0x1402, 16, {0xe5, 0xe5, 0x3c, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} }, +{ 0x1402, 16, {0xe5, 0xe5, 0x3d, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} }, { 0x1412, 16, {0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90} }, { 0x1422, 16, {0x7f, 0xb7, 0xed, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f, 0x40} }, { 0x1432, 16, {0x90, 0x7e, 0x80, 0x05, 0x86, 0x90, 0x20, 0x00, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d, 0x84} }, @@ -364,14 +361,14 @@ { 0x14f2, 16, {0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90, 0x20, 0x01} }, { 0x1502, 16, {0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc7, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20, 0x0a, 0xe0, 0x54} }, { 0x1512, 16, {0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02} }, -{ 0x1522, 16, {0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x37, 0x02, 0x13} }, +{ 0x1522, 16, {0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x38, 0x02, 0x13} }, { 0x1532, 16, {0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2d, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82} }, -{ 0x1542, 16, {0x05, 0xe0, 0x42, 0x33, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} }, -{ 0x1552, 16, {0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} }, +{ 0x1542, 16, {0x05, 0xe0, 0x42, 0x34, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} }, +{ 0x1552, 16, {0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} }, { 0x1562, 16, {0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x01, 0xf0, 0x90} }, { 0x1572, 16, {0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05} }, { 0x1582, 16, {0x86, 0x90, 0x7e, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90} }, -{ 0x1592, 16, {0x7f, 0xe5, 0xe5, 0x3d, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} }, +{ 0x1592, 16, {0x7f, 0xe5, 0xe5, 0x3e, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} }, { 0x15a2, 16, {0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} }, { 0x15b2, 16, {0x90, 0x7f, 0xb9, 0xed, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f} }, { 0x15c2, 16, {0x40, 0x90, 0x7e, 0x00, 0x05, 0x86, 0x90, 0x20, 0x08, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d} }, @@ -390,13 +387,13 @@ { 0x1690, 16, {0x90, 0x20, 0x09, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20} }, { 0x16a0, 16, {0x12, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14} }, { 0x16b0, 16, {0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x17, 0x87, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5} }, -{ 0x16c0, 16, {0x38, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} }, -{ 0x16d0, 16, {0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x34, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} }, -{ 0x16e0, 16, {0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} }, +{ 0x16c0, 16, {0x39, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} }, +{ 0x16d0, 16, {0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x35, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} }, +{ 0x16e0, 16, {0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} }, { 0x16f0, 16, {0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74} }, { 0x1700, 16, {0x02, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90} }, { 0x1710, 16, {0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0} }, -{ 0x1720, 16, {0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3e, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} }, +{ 0x1720, 16, {0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} }, { 0x1730, 16, {0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58} }, { 0x1740, 16, {0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbb, 0xed, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfe, 0xf0, 0x02} }, { 0x1750, 16, {0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x80, 0x05, 0x86, 0x90, 0x20, 0x10, 0xe5, 0x84, 0xfe, 0x24} }, @@ -415,13 +412,13 @@ { 0x1820, 16, {0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x02, 0x13, 0x43, 0x90} }, { 0x1830, 16, {0x20, 0x1a, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5} }, { 0x1840, 16, {0x14, 0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x19, 0x18, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0} }, -{ 0x1850, 16, {0xf5, 0x39, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53} }, -{ 0x1860, 16, {0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x35, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} }, -{ 0x1870, 16, {0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe3, 0x0a, 0x53, 0x82} }, +{ 0x1850, 16, {0xf5, 0x3a, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53} }, +{ 0x1860, 16, {0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x36, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} }, +{ 0x1870, 16, {0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe3, 0x0a, 0x53, 0x82} }, { 0x1880, 16, {0xf8, 0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50} }, { 0x1890, 16, {0x74, 0x03, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0} }, { 0x18a0, 16, {0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84} }, -{ 0x18b0, 16, {0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} }, +{ 0x18b0, 16, {0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x40, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} }, { 0x18c0, 16, {0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20} }, { 0x18d0, 16, {0x58, 0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbd, 0xed, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfe, 0xf0} }, { 0x18e0, 16, {0x02, 0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x00, 0x05, 0x86, 0x90, 0x20, 0x18, 0xe5, 0x84, 0xfe} }, @@ -439,63 +436,61 @@ { 0x19a0, 16, {0x80, 0x1b, 0xe0, 0xde, 0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74} }, { 0x19b0, 16, {0x00, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcd, 0xf0, 0x02, 0x13, 0x43} }, { 0x19c0, 1, {0x32} }, -{ 0x19c1, 4, {0x8e, 0x54, 0x8f, 0x55} }, -{ 0x19c5, 16, {0x75, 0x56, 0x03, 0xe5, 0x55, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe} }, -{ 0x19d5, 16, {0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x1a, 0xcf, 0xe5, 0x56, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} }, -{ 0x19e5, 16, {0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x1a, 0x73, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} }, -{ 0x19f5, 16, {0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} }, -{ 0x1a05, 16, {0x80, 0x6c, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} }, -{ 0x1a15, 16, {0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x56, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} }, -{ 0x1a25, 16, {0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x55, 0x24, 0x06, 0xf5, 0x82} }, -{ 0x1a35, 16, {0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5} }, -{ 0x1a45, 16, {0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x55, 0x24} }, -{ 0x1a55, 16, {0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0x9f, 0x8e, 0x85} }, -{ 0x1a65, 16, {0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0x8e, 0x90, 0x7f} }, -{ 0x1a75, 16, {0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} }, -{ 0x1a85, 16, {0x22, 0xe5, 0x57, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} }, -{ 0x1a95, 16, {0xe5, 0x56, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x1aa5, 16, {0x80, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} }, -{ 0x1ab5, 16, {0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} }, -{ 0x1ac5, 12, {0x56, 0x03, 0x02, 0x19, 0xc8, 0x15, 0x56, 0x02, 0x19, 0xc8, 0x7f, 0x08} }, -{ 0x1ad1, 1, {0x22} }, -{ 0x1ad2, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} }, -{ 0x1ae2, 15, {0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x1af1, 4, {0x8e, 0x54, 0x8f, 0x55} }, -{ 0x1af5, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x56, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, -{ 0x1b05, 16, {0xe5, 0x56, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} }, -{ 0x1b15, 16, {0x54, 0x03, 0x70, 0x24, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x07, 0xaf} }, -{ 0x1b25, 16, {0x56, 0x7d, 0x02, 0x12, 0x83, 0x2d, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0x30, 0xe1} }, -{ 0x1b35, 10, {0x07, 0xaf, 0x56, 0x7d, 0x04, 0x12, 0x83, 0x2d, 0x7f, 0x00} }, -{ 0x1b3f, 1, {0x22} }, -{ 0x8000, 16, {0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0x9f, 0x61, 0xfd, 0x8b, 0x4d, 0x75} }, -{ 0x8010, 16, {0x4e, 0x12, 0x75, 0x4f, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4b} }, -{ 0x8020, 16, {0xf5, 0x4c, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} }, +{ 0x19c1, 4, {0xad, 0x07, 0xac, 0x06} }, +{ 0x19c5, 16, {0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} }, +{ 0x19d5, 16, {0x4a, 0x70, 0x03, 0x02, 0x1b, 0x09, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x1a, 0xdb, 0x90} }, +{ 0x19e5, 16, {0x19, 0xeb, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x1a, 0xb9, 0x02, 0x1a, 0x71, 0x02, 0x1a, 0x5a, 0x02} }, +{ 0x19f5, 16, {0x1a, 0x40, 0x02, 0x1a, 0x2f, 0x02, 0x1a, 0x1a, 0x02, 0x1a, 0x00, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, +{ 0x1a05, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} }, +{ 0x1a15, 16, {0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} }, +{ 0x1a25, 16, {0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x1a, 0xdb, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} }, +{ 0x1a35, 16, {0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, +{ 0x1a45, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} }, +{ 0x1a55, 16, {0xf0, 0x19, 0x02, 0x1a, 0xdb, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, +{ 0x1a65, 16, {0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x57, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} }, +{ 0x1a75, 16, {0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} }, +{ 0x1a85, 16, {0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} }, +{ 0x1a95, 16, {0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83} }, +{ 0x1aa5, 16, {0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} }, +{ 0x1ab5, 16, {0xa0, 0x85, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} }, +{ 0x1ac5, 16, {0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} }, +{ 0x1ad5, 16, {0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30} }, +{ 0x1ae5, 16, {0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} }, +{ 0x1af5, 16, {0x19, 0xc7, 0xe5, 0x57, 0x30, 0xe1, 0x03, 0x02, 0x19, 0xc7, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} }, +{ 0x1b05, 6, {0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} }, +{ 0x1b0b, 1, {0x22} }, +{ 0x1b0c, 16, {0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x1c, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x7f, 0x02} }, +{ 0x1b1c, 16, {0x7d, 0xff, 0x12, 0x82, 0xa8, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x7f, 0x03, 0x7d, 0xff} }, +{ 0x1b2c, 4, {0x12, 0x82, 0xa8, 0x22} }, +{ 0x8000, 16, {0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0xa0, 0x58, 0xfd, 0x8b, 0x4e, 0x75} }, +{ 0x8010, 16, {0x4f, 0x12, 0x75, 0x50, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4c} }, +{ 0x8020, 16, {0xf5, 0x4d, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} }, { 0x8030, 16, {0xa9, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0xe4, 0xfc, 0xec, 0x25, 0xe0, 0x24, 0xb4, 0xf5} }, { 0x8040, 16, {0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x0c, 0xbc, 0x10, 0xee, 0xe4, 0x90, 0x7f, 0xdd} }, -{ 0x8050, 16, {0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x4d, 0xaa, 0x4e, 0xa9, 0x4f} }, -{ 0x8060, 16, {0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} }, -{ 0x8070, 16, {0x12, 0x9f, 0x61, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0x9f, 0x61} }, +{ 0x8050, 16, {0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x4e, 0xaa, 0x4f, 0xa9, 0x50} }, +{ 0x8060, 16, {0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} }, +{ 0x8070, 16, {0x12, 0xa0, 0x58, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0xa0, 0x58} }, { 0x8080, 16, {0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x81, 0x16, 0xec, 0xc3, 0x94, 0x10} }, -{ 0x8090, 16, {0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4c, 0xae, 0x4b, 0x78, 0x02, 0xce} }, +{ 0x8090, 16, {0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4d, 0xae, 0x4c, 0x78, 0x02, 0xce} }, { 0x80a0, 16, {0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xf0, 0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} }, { 0x80b0, 16, {0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe0, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01, 0xa8, 0x06} }, { 0x80c0, 16, {0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe0, 0xf0, 0x90, 0x02, 0xae, 0xe0} }, -{ 0x80d0, 16, {0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4c, 0xae, 0x4b, 0x78} }, +{ 0x80d0, 16, {0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4d, 0xae, 0x4c, 0x78} }, { 0x80e0, 16, {0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xe8, 0x2c, 0xf5, 0x82, 0xe4, 0x34} }, { 0x80f0, 16, {0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe1, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01} }, { 0x8100, 16, {0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x02} }, -{ 0x8110, 16, {0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0x9f, 0x61, 0x25} }, -{ 0x8120, 16, {0x4c, 0xf5, 0x4c, 0xe4, 0x35, 0x4b, 0xf5, 0x4b, 0x90, 0x00, 0x05, 0x12, 0x9f, 0x61, 0xfe, 0xe4} }, -{ 0x8130, 16, {0x25, 0x4c, 0xf5, 0x4c, 0xee, 0x35, 0x4b, 0xf5, 0x4b, 0x02, 0x81, 0xb8, 0xab, 0x4d, 0xaa, 0x4e} }, -{ 0x8140, 16, {0xa9, 0x4f, 0x90, 0x00, 0x03, 0x12, 0x9f, 0x61, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} }, -{ 0x8150, 16, {0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0x9f, 0x61, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} }, +{ 0x8110, 16, {0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0xa0, 0x58, 0x25} }, +{ 0x8120, 16, {0x4d, 0xf5, 0x4d, 0xe4, 0x35, 0x4c, 0xf5, 0x4c, 0x90, 0x00, 0x05, 0x12, 0xa0, 0x58, 0xfe, 0xe4} }, +{ 0x8130, 16, {0x25, 0x4d, 0xf5, 0x4d, 0xee, 0x35, 0x4c, 0xf5, 0x4c, 0x02, 0x81, 0xb8, 0xab, 0x4e, 0xaa, 0x4f} }, +{ 0x8140, 16, {0xa9, 0x50, 0x90, 0x00, 0x03, 0x12, 0xa0, 0x58, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} }, +{ 0x8150, 16, {0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0xa0, 0x58, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} }, { 0x8160, 16, {0x4e, 0xef, 0x30, 0xe7, 0x1e, 0x90, 0x7f, 0xde, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80} }, { 0x8170, 16, {0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x4e} }, { 0x8180, 16, {0xf0, 0x80, 0x35, 0x90, 0x7f, 0xdf, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80, 0x02, 0xc3} }, { 0x8190, 16, {0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xad, 0xe0, 0x4e, 0xf0, 0xec} }, { 0x81a0, 16, {0x25, 0xe0, 0x24, 0xc5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x09, 0x7f} }, -{ 0x81b0, 16, {0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35} }, -{ 0x81c0, 16, {0x4e, 0xf5, 0x4e, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} }, +{ 0x81b0, 16, {0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x50, 0xf5, 0x50, 0xe4, 0x35} }, +{ 0x81c0, 16, {0x4f, 0xf5, 0x4f, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} }, { 0x81d0, 8, {0x7f, 0xae, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x00} }, { 0x81d8, 1, {0x22} }, { 0x81d9, 2, {0xac, 0x07} }, @@ -513,549 +508,569 @@ { 0x828b, 16, {0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f, 0xfa, 0x22, 0xc2, 0xaf, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, { 0x829b, 12, {0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0xd2, 0xaf, 0xff, 0x7e, 0x00} }, { 0x82a7, 1, {0x22} }, -{ 0x82a8, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} }, -{ 0x82b8, 16, {0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5e, 0x74, 0xbf} }, -{ 0x82c8, 16, {0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} }, -{ 0x82d8, 16, {0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} }, -{ 0x82e8, 16, {0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} }, -{ 0x82f8, 16, {0xef, 0x55, 0x3b, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} }, -{ 0x8308, 16, {0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} }, -{ 0x8318, 16, {0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5e, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} }, -{ 0x8328, 4, {0x83, 0xa3, 0xe9, 0xf0} }, -{ 0x832c, 1, {0x22} }, -{ 0x832d, 4, {0x8f, 0x5e, 0x8d, 0x5f} }, -{ 0x8331, 16, {0xe4, 0xf5, 0x60, 0x74, 0x3c, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24} }, -{ 0x8341, 16, {0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, -{ 0x8351, 16, {0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0xa0, 0xc0, 0x50} }, -{ 0x8361, 16, {0x3c, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} }, -{ 0x8371, 16, {0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} }, -{ 0x8381, 16, {0x00, 0xc3, 0x12, 0xa0, 0xc0, 0x40, 0x0c, 0x75, 0x60, 0x40, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76} }, -{ 0x8391, 16, {0x10, 0x80, 0x0a, 0x75, 0x60, 0x80, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76, 0x38, 0xe5, 0x60, 0x45} }, -{ 0x83a1, 16, {0x5f, 0x44, 0x01, 0xff, 0xe5, 0x5e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x83b1, 5, {0x20, 0xf5, 0x83, 0xef, 0xf0} }, -{ 0x83b6, 1, {0x22} }, -{ 0x83b7, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, -{ 0x83c7, 16, {0xe5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} }, -{ 0x83d7, 16, {0x55, 0x8f, 0x56, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} }, -{ 0x83e7, 16, {0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} }, -{ 0x83f7, 16, {0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x54, 0xf8, 0xe4, 0xf6, 0xe5, 0x56, 0x24, 0x04, 0xf5, 0x82} }, -{ 0x8407, 16, {0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x83, 0x2d} }, -{ 0x8417, 16, {0xaf, 0x54, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3, 0xe0} }, -{ 0x8427, 16, {0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x56, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83} }, -{ 0x8437, 16, {0xe0, 0xe5, 0x56, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x54} }, -{ 0x8447, 16, {0x7d, 0x06, 0x12, 0x83, 0x2d, 0x74, 0xf8, 0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} }, -{ 0x8457, 16, {0xe4, 0xf0, 0xe5, 0x54, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24} }, -{ 0x8467, 16, {0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xef} }, -{ 0x8477, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x54, 0x74, 0x01} }, -{ 0x8487, 13, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7f, 0x00} }, -{ 0x8494, 1, {0x22} }, -{ 0x8495, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, -{ 0x84a5, 16, {0xaf, 0x54, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0x74, 0xf8, 0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02} }, -{ 0x84b5, 16, {0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x84c5, 16, {0x20, 0xaf, 0x82, 0xf5, 0x56, 0x8f, 0x57, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} }, -{ 0x84d5, 16, {0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x83, 0x2d, 0xe5} }, -{ 0x84e5, 16, {0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x57} }, -{ 0x84f5, 16, {0x82, 0x85, 0x56, 0x83, 0xe0, 0xf5, 0x55, 0xaf, 0x54, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} }, -{ 0x8505, 16, {0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x30, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4} }, -{ 0x8515, 16, {0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82} }, -{ 0x8525, 9, {0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} }, -{ 0x852e, 1, {0x22} }, -{ 0x852f, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} }, -{ 0x853f, 16, {0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} }, -{ 0x854f, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} }, -{ 0x855f, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} }, -{ 0x856f, 16, {0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} }, -{ 0x857f, 16, {0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} }, -{ 0x858f, 16, {0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} }, -{ 0x859f, 16, {0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} }, -{ 0x85af, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} }, -{ 0x85bf, 3, {0x83, 0xf0, 0x22} }, -{ 0x85c2, 4, {0xad, 0x07, 0xac, 0x06} }, -{ 0x85c6, 16, {0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} }, -{ 0x85d6, 16, {0x22, 0x8c, 0x54, 0x8d, 0x55, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x85e6, 16, {0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} }, -{ 0x85f6, 16, {0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x55, 0xe5, 0x55, 0xaa, 0x54, 0x70, 0x02} }, -{ 0x8606, 16, {0x05, 0x54, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x8616, 1, {0x22} }, -{ 0x8617, 4, {0x8e, 0x54, 0x8f, 0x55} }, -{ 0x861b, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5b, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, -{ 0x862b, 16, {0xe5, 0x5b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} }, -{ 0x863b, 16, {0x5c, 0x8f, 0x5d, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} }, -{ 0x864b, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa0} }, -{ 0x865b, 16, {0xc0, 0x40, 0x10, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0xa1, 0x07, 0x00, 0x00, 0x00} }, -{ 0x866b, 16, {0x08, 0x80, 0x2e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} }, -{ 0x867b, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa0} }, -{ 0x868b, 16, {0xc0, 0x50, 0x0e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0xa1, 0x07, 0x00, 0x07, 0x08} }, -{ 0x869b, 16, {0x00, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} }, -{ 0x86ab, 16, {0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa0, 0x2e, 0x8f, 0x59} }, -{ 0x86bb, 16, {0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa0} }, -{ 0x86cb, 16, {0x2e, 0xaf, 0x03, 0x8f, 0x5a, 0xaf, 0x59, 0xae, 0x58, 0xad, 0x57, 0xac, 0x56, 0x7b, 0x0a, 0x7a} }, -{ 0x86db, 16, {0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa0, 0x2e, 0x8f, 0x59, 0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56} }, -{ 0x86eb, 16, {0xe5, 0x5a, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x59, 0x24, 0x01, 0xf5, 0x59, 0xe4, 0x35, 0x58} }, -{ 0x86fb, 16, {0xf5, 0x58, 0xe4, 0x35, 0x57, 0xf5, 0x57, 0xe4, 0x35, 0x56, 0xf5, 0x56, 0x85, 0x5d, 0x82, 0x85} }, -{ 0x870b, 16, {0x5c, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} }, -{ 0x871b, 16, {0x80, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xe5, 0x59, 0xf0, 0xaf, 0x59, 0xae, 0x58, 0xad} }, -{ 0x872b, 16, {0x57, 0xac, 0x56, 0x78, 0x08, 0x12, 0xa0, 0xd1, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xef} }, -{ 0x873b, 16, {0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} }, -{ 0x874b, 16, {0x5a, 0xe5, 0x55, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62} }, -{ 0x875b, 16, {0x05, 0x43, 0x5a, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5a, 0x08, 0x80, 0x11, 0xef} }, -{ 0x876b, 16, {0xb4, 0x74, 0x05, 0x43, 0x5a, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22} }, -{ 0x877b, 16, {0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03} }, -{ 0x878b, 16, {0x43, 0x5a, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5a, 0x40, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82} }, -{ 0x879b, 16, {0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4} }, -{ 0x87ab, 16, {0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf, 0x5b, 0x74, 0x01} }, -{ 0x87bb, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0xe5, 0x5d, 0x24, 0x04, 0xf5} }, -{ 0x87cb, 16, {0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5a, 0x80, 0x10, 0xaf} }, -{ 0x87db, 16, {0x5b, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x3b, 0x85} }, -{ 0x87eb, 16, {0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c} }, -{ 0x87fb, 16, {0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5a, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} }, -{ 0x880b, 16, {0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83} }, -{ 0x881b, 16, {0xef, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5} }, -{ 0x882b, 16, {0x5d, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09} }, -{ 0x883b, 16, {0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x06, 0xf5, 0x82, 0xe4} }, -{ 0x884b, 16, {0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5} }, -{ 0x885b, 16, {0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0} }, -{ 0x886b, 16, {0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c} }, -{ 0x887b, 16, {0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5b, 0x7d, 0x06, 0x12, 0x83, 0x2d, 0x75, 0x5a, 0x08, 0xe5, 0x55} }, -{ 0x888b, 16, {0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5a, 0x10, 0xe5} }, -{ 0x889b, 16, {0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5a, 0xf0} }, -{ 0x88ab, 16, {0xe5, 0x55, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05} }, -{ 0x88bb, 16, {0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x55, 0x24, 0x06, 0xf5} }, -{ 0x88cb, 16, {0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94} }, -{ 0x88db, 16, {0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24} }, -{ 0x88eb, 16, {0xfb, 0x4f, 0xf5, 0x5a, 0xe5, 0x55, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0} }, -{ 0x88fb, 16, {0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a} }, -{ 0x890b, 16, {0x70, 0x14, 0x43, 0x5a, 0x18, 0x80, 0x12, 0x43, 0x5a, 0x08, 0x80, 0x0d, 0x43, 0x5a, 0x38, 0x80} }, -{ 0x891b, 16, {0x08, 0x43, 0x5a, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3} }, -{ 0x892b, 16, {0xa3, 0xa3, 0xe5, 0x5a, 0xf0, 0xaf, 0x5b, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0xaa, 0x54, 0xa9, 0x55} }, -{ 0x893b, 16, {0x7b, 0x01, 0xc0, 0x01, 0xe5, 0x5b, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35} }, -{ 0x894b, 15, {0xf0, 0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9f, 0x1f, 0x7f, 0x00} }, -{ 0x895a, 1, {0x22} }, -{ 0x895b, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, -{ 0x896b, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} }, -{ 0x897b, 16, {0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} }, -{ 0x898b, 16, {0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} }, -{ 0x899b, 16, {0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} }, -{ 0x89ab, 16, {0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} }, -{ 0x89bb, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x54, 0x7f, 0x02, 0x12, 0x81, 0xd9} }, -{ 0x89cb, 16, {0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xe5, 0x54, 0x5f, 0x90, 0x01, 0x32, 0xf0, 0x7e} }, -{ 0x89db, 10, {0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12, 0x8e, 0xb4, 0x7f, 0x00} }, -{ 0x89e5, 1, {0x22} }, -{ 0x89e6, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, -{ 0x89f6, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} }, -{ 0x8a06, 16, {0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} }, -{ 0x8a16, 16, {0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x8e} }, -{ 0x8a26, 3, {0xb4, 0x7f, 0x00} }, -{ 0x8a29, 1, {0x22} }, -{ 0x8a2a, 4, {0xad, 0x07, 0xac, 0x06} }, -{ 0x8a2e, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, -{ 0x8a3e, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, -{ 0x8a4e, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} }, -{ 0x8a5e, 16, {0x44, 0x02, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} }, -{ 0x8a6e, 4, {0xfd, 0xf0, 0x7f, 0x00} }, -{ 0x8a72, 1, {0x22} }, -{ 0x8a73, 4, {0xad, 0x07, 0xac, 0x06} }, -{ 0x8a77, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, -{ 0x8a87, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, -{ 0x8a97, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} }, -{ 0x8aa7, 16, {0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} }, -{ 0x8ab7, 4, {0xfe, 0xf0, 0x7f, 0x00} }, -{ 0x8abb, 1, {0x22} }, -{ 0x8abc, 4, {0xad, 0x07, 0xac, 0x06} }, -{ 0x8ac0, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, -{ 0x8ad0, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, -{ 0x8ae0, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} }, -{ 0x8af0, 16, {0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} }, -{ 0x8b00, 1, {0x22} }, -{ 0x8b01, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} }, -{ 0x8b11, 16, {0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3a, 0x7f, 0x00} }, -{ 0x8b21, 1, {0x22} }, -{ 0x8b22, 4, {0x8e, 0x54, 0x8f, 0x55} }, -{ 0x8b26, 16, {0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x59, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x56, 0xc3} }, -{ 0x8b36, 16, {0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x56, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} }, -{ 0x8b46, 16, {0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x57, 0x7e, 0x75, 0x58} }, -{ 0x8b56, 16, {0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x57, 0x7e, 0x75, 0x58, 0x00, 0x80, 0x16, 0x7e} }, -{ 0x8b66, 16, {0x7d, 0x7f, 0x80, 0x75, 0x57, 0x7d, 0x75, 0x58, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} }, -{ 0x8b76, 16, {0x57, 0x7d, 0x75, 0x58, 0x00, 0xe5, 0x59, 0x70, 0x1b, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0x74} }, -{ 0x8b86, 16, {0xff, 0xf0, 0xe5, 0x56, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} }, -{ 0x8b96, 16, {0x01, 0xf0, 0x80, 0x48, 0xe5, 0x55, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x54, 0xfe, 0xe5, 0x59, 0x60} }, -{ 0x8ba6, 16, {0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} }, -{ 0x8bb6, 16, {0x58, 0xe5, 0x58, 0xaa, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} }, -{ 0x8bc6, 16, {0x15, 0x59, 0x80, 0xd9, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x56, 0x25} }, -{ 0x8bd6, 14, {0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} }, -{ 0x8be4, 1, {0x22} }, -{ 0x8be5, 16, {0xef, 0x24, 0x05, 0xf5, 0x55, 0xe4, 0x3e, 0xf5, 0x54, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} }, -{ 0x8bf5, 16, {0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} }, -{ 0x8c05, 16, {0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x56, 0xf5, 0x57, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} }, -{ 0x8c15, 16, {0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8c, 0xc6} }, -{ 0x8c25, 16, {0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0x12, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe} }, -{ 0x8c35, 16, {0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x59, 0x74, 0x01, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59} }, -{ 0x8c45, 16, {0x94, 0x40, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5} }, -{ 0x8c55, 16, {0x57, 0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x50, 0x03, 0x02, 0x8d, 0x15, 0xae, 0x58, 0xaf, 0x59} }, -{ 0x8c65, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} }, -{ 0x8c75, 16, {0x56, 0xf5, 0x57, 0x02, 0x8d, 0x15, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} }, -{ 0x8c85, 16, {0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59, 0x94} }, -{ 0x8c95, 16, {0x10, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x10, 0xd3, 0xe5, 0x57} }, -{ 0x8ca5, 16, {0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x40, 0x68, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85} }, -{ 0x8cb5, 16, {0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x80} }, -{ 0x8cc5, 16, {0x4f, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} }, -{ 0x8cd5, 16, {0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0x45, 0x59, 0x60, 0x0b, 0xd3, 0xe5, 0x59, 0x94, 0x40, 0xe5} }, -{ 0x8ce5, 16, {0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5, 0x57, 0x95, 0x59} }, -{ 0x8cf5, 16, {0xe5, 0x56, 0x95, 0x58, 0x40, 0x17, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} }, -{ 0x8d05, 16, {0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x7f, 0x01, 0x22} }, -{ 0x8d15, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8d, 0xd5, 0x24, 0xf9} }, -{ 0x8d25, 16, {0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8e, 0x25, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8e, 0x69} }, -{ 0x8d35, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} }, -{ 0x8d45, 16, {0x94, 0x00, 0x40, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57} }, -{ 0x8d55, 16, {0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x75, 0xe0} }, -{ 0x8d65, 16, {0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f} }, -{ 0x8d75, 16, {0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} }, -{ 0x8d85, 16, {0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8e} }, -{ 0x8d95, 16, {0x69, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x76} }, -{ 0x8da5, 16, {0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02} }, -{ 0x8db5, 16, {0x8e, 0x69, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} }, -{ 0x8dc5, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} }, -{ 0x8dd5, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} }, -{ 0x8de5, 16, {0x94, 0x00, 0x50, 0x03, 0x02, 0x8e, 0x69, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} }, -{ 0x8df5, 16, {0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e} }, -{ 0x8e05, 16, {0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} }, -{ 0x8e15, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} }, -{ 0x8e25, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} }, -{ 0x8e35, 16, {0xa3, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x60, 0x24} }, -{ 0x8e45, 16, {0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} }, -{ 0x8e55, 16, {0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83} }, -{ 0x8e65, 16, {0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3} }, -{ 0x8e75, 11, {0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x8e, 0xb4, 0x7f, 0x00} }, -{ 0x8e80, 1, {0x22} }, -{ 0x8e81, 16, {0x8e, 0x5f, 0x8f, 0x60, 0x8c, 0x61, 0x8d, 0x62, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x60} }, -{ 0x8e91, 16, {0xe5, 0x60, 0xae, 0x5f, 0x70, 0x02, 0x05, 0x5f, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} }, -{ 0x8ea1, 16, {0x62, 0xe5, 0x62, 0xac, 0x61, 0x70, 0x02, 0x05, 0x61, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, -{ 0x8eb1, 3, {0x80, 0xd6, 0x22} }, -{ 0x8eb4, 6, {0x8d, 0x5a, 0xab, 0x07, 0xaa, 0x06} }, -{ 0x8eba, 16, {0x75, 0x5e, 0x40, 0x75, 0x5d, 0x0d, 0x75, 0x5c, 0x03, 0x75, 0x5b, 0x00, 0x90, 0x7f, 0xc2, 0xe0} }, -{ 0x8eca, 16, {0x20, 0xe1, 0xf9, 0xaf, 0x5e, 0xae, 0x5d, 0xad, 0x5c, 0xac, 0x5b, 0xec, 0x4d, 0x4e, 0x4f, 0x70} }, -{ 0x8eda, 16, {0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} }, -{ 0x8eea, 16, {0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5a, 0x12, 0x8e, 0x81, 0x90, 0x7f, 0xc3} }, -{ 0x8efa, 8, {0xe5, 0x5a, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x8f02, 1, {0x22} }, -{ 0x8f03, 16, {0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0x90, 0x20, 0x70, 0xe0, 0x54, 0xf0, 0xff, 0xc4, 0x54, 0x0f} }, -{ 0x8f13, 16, {0x90, 0x01, 0x85, 0xf0, 0x90, 0x95, 0xbf, 0xe4, 0x93, 0x90, 0x01, 0x86, 0xf0, 0x90, 0x95, 0xc0} }, -{ 0x8f23, 16, {0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} }, -{ 0x8f33, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e} }, -{ 0x8f43, 16, {0x01, 0x7f, 0x7c, 0x12, 0x10, 0x2c, 0x7e, 0x01, 0x7f, 0x84, 0x7d, 0x14, 0x12, 0x8e, 0xb4, 0x7f} }, -{ 0x8f53, 1, {0x00} }, -{ 0x8f54, 1, {0x22} }, -{ 0x8f55, 16, {0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4b, 0x7b, 0x75, 0x4c, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} }, -{ 0x8f65, 16, {0x4b, 0x4e, 0x85, 0x4c, 0x4f, 0xe5, 0x4f, 0x24, 0x01, 0xf5, 0x53, 0xe4, 0x35, 0x4e, 0xf5, 0x52} }, -{ 0x8f75, 16, {0xe4, 0xf5, 0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} }, -{ 0x8f85, 16, {0x5b, 0x90, 0x8f, 0x8d, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x8f, 0xb1, 0x02, 0x8f, 0xb1, 0x02, 0x8f} }, -{ 0x8f95, 16, {0xbb, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xd9, 0x02, 0x8f, 0xb1} }, -{ 0x8fa5, 16, {0x02, 0x8f, 0xcf, 0x02, 0x8f, 0xb1, 0x02, 0x8f, 0xe1, 0x02, 0x8f, 0xb1, 0xef, 0x64, 0x02, 0x60} }, -{ 0x8fb5, 16, {0x2b, 0x75, 0x4d, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x4d, 0xff, 0x80, 0x1c} }, -{ 0x8fc5, 16, {0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x4d, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} }, -{ 0x8fd5, 16, {0x4d, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x60, 0x15} }, -{ 0x8fe5, 16, {0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} }, -{ 0x8ff5, 16, {0x8e, 0xb4, 0xaf, 0x4d, 0x22, 0xe4, 0xf5, 0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0x14} }, -{ 0x9005, 16, {0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x91, 0x23, 0x90, 0x90, 0x14, 0xf8, 0x28, 0x28, 0x73, 0x02} }, -{ 0x9015, 16, {0x90, 0x41, 0x02, 0x90, 0x4d, 0x02, 0x90, 0x59, 0x02, 0x90, 0xa7, 0x02, 0x90, 0xb2, 0x02, 0x90} }, -{ 0x9025, 16, {0xbd, 0x02, 0x90, 0xc8, 0x02, 0x90, 0xd3, 0x02, 0x90, 0xde, 0x02, 0x90, 0xe9, 0x02, 0x90, 0xf4} }, -{ 0x9035, 16, {0x02, 0x90, 0xfb, 0x02, 0x91, 0x23, 0x02, 0x91, 0x06, 0x02, 0x91, 0x11, 0xaf, 0x53, 0xae, 0x52} }, -{ 0x9045, 16, {0x12, 0x83, 0xb7, 0x8f, 0x4d, 0x02, 0x91, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x84, 0x95, 0x8f} }, -{ 0x9055, 16, {0x4d, 0x02, 0x91, 0x26, 0x85, 0x52, 0x50, 0x85, 0x53, 0x51, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4} }, -{ 0x9065, 16, {0x35, 0x50, 0xfe, 0x12, 0x85, 0x2f, 0xaf, 0x51, 0xae, 0x50, 0x12, 0x85, 0xc2, 0x8f, 0x4d, 0xef} }, -{ 0x9075, 16, {0x64, 0x01, 0x60, 0x03, 0x02, 0x91, 0x26, 0xaf, 0x51, 0xae, 0x50, 0x12, 0x86, 0x17, 0x8f, 0x4d} }, -{ 0x9085, 16, {0xe5, 0x4d, 0x70, 0x03, 0x02, 0x91, 0x26, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0x75, 0xf0} }, -{ 0x9095, 16, {0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x86, 0x17, 0x02} }, -{ 0x90a5, 16, {0x91, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0x2a, 0x8f, 0x4d, 0x80, 0x74, 0xaf, 0x53, 0xae} }, -{ 0x90b5, 16, {0x52, 0x12, 0x8a, 0x73, 0x8f, 0x4d, 0x80, 0x69, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0xbc, 0x8f} }, -{ 0x90c5, 16, {0x4d, 0x80, 0x5e, 0xaf, 0x4c, 0xae, 0x4b, 0x12, 0x8b, 0xe5, 0x8f, 0x4d, 0x80, 0x53, 0xaf, 0x53} }, -{ 0x90d5, 16, {0xae, 0x52, 0x12, 0x89, 0x5b, 0x8f, 0x4d, 0x80, 0x48, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x1a, 0xf1} }, -{ 0x90e5, 16, {0x8f, 0x4d, 0x80, 0x3d, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x89, 0xe6, 0x8f, 0x4d, 0x80, 0x32, 0x12} }, -{ 0x90f5, 16, {0x8f, 0x03, 0x8f, 0x4d, 0x80, 0x2b, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8b, 0x01, 0x8f, 0x4d, 0x80} }, -{ 0x9105, 16, {0x20, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8b, 0x22, 0x8f, 0x4d, 0x80, 0x15, 0xaf, 0x4c, 0xae, 0x4b} }, -{ 0x9115, 16, {0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8e, 0x81, 0xe4, 0xf5, 0x4d, 0x80, 0x03, 0x75, 0x4d} }, -{ 0x9125, 16, {0xff, 0xe5, 0x4d, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e} }, -{ 0x9135, 16, {0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x8e, 0xb4, 0xaf} }, -{ 0x9145, 16, {0x4d, 0x22, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} }, -{ 0x9155, 16, {0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85} }, -{ 0x9165, 16, {0x52, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x8e, 0xb4} }, -{ 0x9175, 4, {0x8f, 0x4d, 0xaf, 0x4d} }, -{ 0x9179, 1, {0x22} }, -{ 0x917a, 8, {0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b} }, -{ 0x9182, 16, {0x75, 0x55, 0x01, 0x75, 0x56, 0x9c, 0xe4, 0xf5, 0x54, 0xaf, 0x50, 0x15, 0x50, 0xef, 0x70, 0x03} }, -{ 0x9192, 16, {0x02, 0x92, 0x18, 0xaf, 0x4f, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4e} }, -{ 0x91a2, 16, {0xae, 0x4d, 0xad, 0x4c, 0xac, 0x4b, 0x12, 0xa0, 0x2e, 0xaf, 0x03, 0x8f, 0x53, 0xaf, 0x4e, 0xae} }, -{ 0x91b2, 16, {0x4d, 0xad, 0x4c, 0xac, 0x4b, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x4f, 0xe4} }, -{ 0x91c2, 16, {0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} }, -{ 0x91d2, 16, {0x12, 0xa0, 0x2e, 0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b, 0xe5, 0x53, 0x24, 0x30, 0xf5} }, -{ 0x91e2, 16, {0x53, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x53, 0xf5, 0x53, 0x05, 0x56, 0xe5, 0x56} }, -{ 0x91f2, 16, {0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x56, 0xe5} }, -{ 0x9202, 16, {0x56, 0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x53, 0xf0, 0x05} }, -{ 0x9212, 16, {0x54, 0x05, 0x54, 0x02, 0x91, 0x8b, 0xe5, 0x56, 0x15, 0x56, 0x70, 0x02, 0x15, 0x55, 0xaf, 0x54} }, -{ 0x9222, 16, {0x15, 0x54, 0xef, 0x60, 0x23, 0xe5, 0x56, 0x15, 0x56, 0xae, 0x55, 0x70, 0x02, 0x15, 0x55, 0xf5} }, -{ 0x9232, 16, {0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x52, 0xe5, 0x52, 0xac, 0x51, 0x70, 0x02, 0x05, 0x51, 0x14} }, -{ 0x9242, 8, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} }, -{ 0x924a, 1, {0x22} }, -{ 0x924b, 16, {0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} }, -{ 0x925b, 16, {0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} }, -{ 0x926b, 16, {0xe4, 0xef, 0x55, 0x30, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} }, -{ 0x927b, 16, {0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} }, -{ 0x928b, 16, {0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9f, 0x8e, 0xfc, 0xd3, 0xe5, 0xf0} }, -{ 0x929b, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} }, -{ 0x92ab, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x92bb, 1, {0x22} }, -{ 0x92bc, 16, {0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} }, -{ 0x92cc, 16, {0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} }, -{ 0x92dc, 16, {0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} }, -{ 0x92ec, 16, {0x9f, 0x1f, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9f, 0x8e, 0xfc, 0xd3, 0xe5, 0xf0} }, -{ 0x92fc, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} }, -{ 0x930c, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x931c, 1, {0x22} }, -{ 0x931d, 16, {0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x50, 0x7b, 0x75, 0x51} }, -{ 0x932d, 16, {0x80, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x50, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x52, 0xf5} }, -{ 0x933d, 16, {0x53, 0x89, 0x54, 0xfe, 0x12, 0x92, 0xbc, 0xef, 0x60, 0x50, 0xab, 0x52, 0xaa, 0x53, 0xa9, 0x54} }, -{ 0x934d, 16, {0x12, 0x9f, 0x48, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0xb4, 0x02, 0x16, 0xc2, 0xaf} }, -{ 0x935d, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} }, -{ 0x936d, 16, {0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} }, -{ 0x937d, 16, {0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x30, 0x60, 0x0f, 0x85, 0x51, 0x82, 0x85, 0x50} }, -{ 0x938d, 10, {0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} }, -{ 0x9397, 1, {0x22} }, -{ 0x9398, 16, {0x12, 0x93, 0x1d, 0xe4, 0xf5, 0x4b, 0x74, 0x36, 0x25, 0x4b, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4c} }, -{ 0x93a8, 16, {0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4c, 0xff, 0xc4} }, -{ 0x93b8, 16, {0x54, 0x0f, 0xf5, 0x4d, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} }, -{ 0x93c8, 16, {0x83, 0xe5, 0x4c, 0xf0, 0xaf, 0x4b, 0x7d, 0x01, 0xe5, 0x4c, 0x45, 0x4d, 0xfb, 0x12, 0x92, 0x4b} }, -{ 0x93d8, 16, {0xef, 0x70, 0x05, 0x12, 0x93, 0x1d, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40} }, -{ 0x93e8, 16, {0xb5, 0x12, 0x93, 0x1d, 0xe5, 0x3a, 0x60, 0x48, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} }, -{ 0x93f8, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x55, 0x3a, 0x60, 0x29, 0xe5, 0x4b} }, -{ 0x9408, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} }, -{ 0x9418, 16, {0x16, 0xaf, 0x4b, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05, 0x12, 0x93, 0x1d} }, -{ 0x9428, 16, {0x80, 0xef, 0xe5, 0x4c, 0xf4, 0x52, 0x3a, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xbb} }, -{ 0x9438, 16, {0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x95, 0x05, 0x74, 0x19, 0xf0, 0x7f, 0x02, 0x12, 0x81} }, -{ 0x9448, 16, {0xd9, 0x8e, 0x4e, 0x8f, 0x4f, 0xc3, 0xe5, 0x4e, 0x64, 0x80, 0x94, 0x80, 0x40, 0xee, 0x90, 0x01} }, -{ 0x9458, 16, {0xbc, 0xe0, 0x65, 0x4f, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8, 0x07} }, -{ 0x9468, 16, {0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xbc, 0xe0, 0x55, 0x4c, 0x60} }, -{ 0x9478, 16, {0x14, 0xaf, 0x4b, 0x7d, 0x08, 0xe5, 0x4c, 0x55, 0x4f, 0xfb, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05} }, -{ 0x9488, 16, {0x12, 0x93, 0x1d, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xcc, 0x90, 0x01} }, -{ 0x9498, 16, {0xbc, 0xe5, 0x4f, 0xf0, 0xe4, 0xf5, 0x4b, 0xc2, 0xaf, 0x74, 0x32, 0x25, 0x4b, 0xf8, 0xe6, 0xf5} }, -{ 0x94a8, 16, {0x4c, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4c, 0x1e, 0xe5, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x02} }, -{ 0x94b8, 16, {0xab, 0x4c, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05, 0x12, 0x93, 0x1d, 0x80, 0xef, 0x74, 0x2c, 0x25} }, -{ 0x94c8, 16, {0x4b, 0xf8, 0xe6, 0xf5, 0x4c, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} }, -{ 0x94d8, 16, {0xe0, 0x65, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x04, 0xab, 0x4c, 0x12, 0x92, 0x4b, 0xef, 0x70} }, -{ 0x94e8, 16, {0x05, 0x12, 0x93, 0x1d, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5} }, -{ 0x94f8, 16, {0x83, 0xe5, 0x4c, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0x9a, 0x12, 0x93, 0x1d} }, -{ 0x9508, 1, {0x22} }, -{ 0x9509, 12, {0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x62, 0x02, 0x95, 0x50} }, -{ 0x9515, 16, {0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} }, -{ 0x9525, 16, {0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} }, -{ 0x9535, 16, {0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} }, -{ 0x9545, 16, {0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x95, 0x95, 0xe4, 0x7e} }, -{ 0x9555, 16, {0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} }, -{ 0x9565, 16, {0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} }, -{ 0x9575, 16, {0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} }, -{ 0x9585, 16, {0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} }, -{ 0x9595, 16, {0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} }, -{ 0x95a5, 16, {0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} }, -{ 0x95b5, 8, {0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} }, -{ 0x95bd, 1, {0x00} }, -{ 0x95be, 3, {0x00, 0x03, 0x1d} }, -{ 0x95c1, 8, {0x8b, 0x54, 0x8a, 0x55, 0x89, 0x56, 0x8d, 0x57} }, -{ 0x95c9, 16, {0xe4, 0xf5, 0x58, 0xf5, 0x59, 0xaf, 0x57, 0x15, 0x57, 0xef, 0x60, 0x36, 0xab, 0x54, 0x05, 0x56} }, -{ 0x95d9, 16, {0xe5, 0x56, 0xaa, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf9, 0x12, 0x9f, 0x48, 0xff, 0xe5, 0x58} }, -{ 0x95e9, 16, {0xe5, 0x59, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0xa2, 0x2f, 0xf5, 0x82, 0xee, 0x34} }, -{ 0x95f9, 16, {0x9b, 0xf5, 0x83, 0xe5, 0x58, 0xff, 0xe4, 0x93, 0xf5, 0x58, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x59} }, -{ 0x9609, 6, {0x80, 0xc3, 0xae, 0x58, 0xaf, 0x59} }, -{ 0x960f, 1, {0x22} }, -{ 0x9610, 11, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} }, -{ 0x961b, 16, {0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} }, -{ 0x962b, 16, {0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} }, -{ 0x963b, 16, {0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} }, -{ 0x964b, 10, {0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} }, -{ 0x9655, 9, {0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x965e, 2, {0xa9, 0x03} }, -{ 0x9660, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} }, -{ 0x9670, 16, {0x57, 0x45, 0x58, 0xf5, 0x59, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} }, -{ 0x9680, 16, {0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} }, -{ 0x9690, 16, {0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x59, 0xeb} }, -{ 0x96a0, 16, {0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x59, 0xfc, 0xb5, 0x06, 0x03, 0xaf} }, -{ 0x96b0, 16, {0x05, 0x22, 0xe5, 0x57, 0x5c, 0xfe, 0xe5, 0x58, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} }, -{ 0x96c0, 16, {0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} }, -{ 0x96d0, 16, {0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x57, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x58, 0x22, 0x7f} }, -{ 0x96e0, 1, {0x00} }, -{ 0x96e1, 1, {0x22} }, -{ 0x96e2, 16, {0x75, 0x50, 0x02, 0x75, 0x51, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x51, 0x82, 0x85} }, -{ 0x96f2, 16, {0x50, 0x83, 0xe0, 0xff, 0x90, 0x03, 0x36, 0xf0, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0} }, -{ 0x9702, 16, {0x90, 0x03, 0x37, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0x75, 0x52, 0x03, 0x75, 0x53, 0x39, 0xef, 0x14} }, -{ 0x9712, 16, {0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9b, 0x6a, 0x90, 0x97, 0x21, 0xf8, 0x28, 0x28, 0x73, 0x02} }, -{ 0x9722, 16, {0x97, 0x42, 0x02, 0x97, 0xe1, 0x02, 0x98, 0xe6, 0x02, 0x99, 0x06, 0x02, 0x99, 0x06, 0x02, 0x99} }, -{ 0x9732, 16, {0xa1, 0x02, 0x99, 0xdc, 0x02, 0x9a, 0x01, 0x02, 0x9a, 0xbf, 0x02, 0x9a, 0xef, 0x02, 0x9b, 0x1b} }, -{ 0x9742, 16, {0xe4, 0xf5, 0x4b, 0xe5, 0x4b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20} }, -{ 0x9752, 16, {0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74, 0x8a, 0x2e} }, -{ 0x9762, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4c, 0x80, 0x0d, 0x74, 0x8a, 0x2e} }, -{ 0x9772, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4c, 0xe5, 0x4f, 0x24, 0x07, 0xf5, 0x82} }, -{ 0x9782, 16, {0xe4, 0x35, 0x4e, 0xf5, 0x83, 0xe5, 0x4c, 0xf0, 0xe0, 0xf5, 0x4d, 0x65, 0x4c, 0x60, 0x38, 0xe4} }, -{ 0x9792, 16, {0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfd, 0x05, 0x53, 0xe5, 0x53, 0xaa, 0x52, 0x70, 0x02} }, -{ 0x97a2, 16, {0x05, 0x52, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70} }, -{ 0x97b2, 16, {0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4c, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} }, -{ 0x97c2, 16, {0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64, 0x02, 0x70} }, -{ 0x97d2, 16, {0x87, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60, 0x03, 0x02, 0x97, 0x45, 0x02, 0x9b, 0x70, 0xe4} }, -{ 0x97e2, 16, {0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0x05, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x03} }, -{ 0x97f2, 16, {0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x96, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe4, 0xf5, 0x4d, 0x7e} }, -{ 0x9802, 16, {0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} }, -{ 0x9812, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xc4, 0xf0, 0x90, 0x01} }, -{ 0x9822, 16, {0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0x74, 0x02} }, -{ 0x9832, 16, {0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4c, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0} }, -{ 0x9842, 16, {0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52} }, -{ 0x9852, 16, {0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} }, -{ 0x9862, 16, {0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4d, 0xff, 0x90, 0x01, 0xc4, 0xe0} }, -{ 0x9872, 16, {0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfe, 0x05, 0x53, 0xe5, 0x53} }, -{ 0x9882, 16, {0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05, 0x53, 0xe5} }, -{ 0x9892, 16, {0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53} }, -{ 0x98a2, 16, {0x82, 0x85, 0x52, 0x83, 0xe5, 0x4c, 0xf0, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x70, 0x16, 0x74, 0x08} }, -{ 0x98b2, 16, {0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35, 0x4e, 0xf5, 0x4e, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60} }, -{ 0x98c2, 16, {0x03, 0x02, 0x98, 0x0d, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x05, 0x4b} }, -{ 0x98d2, 16, {0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3, 0x74, 0x12} }, -{ 0x98e2, 16, {0xf0, 0x02, 0x9b, 0x70, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0, 0x14, 0xff, 0x74, 0x01} }, -{ 0x98f2, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01, 0xc4} }, -{ 0x9902, 16, {0xf0, 0x02, 0x9b, 0x70, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4, 0xf5} }, -{ 0x9912, 16, {0x4d, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01, 0xc0} }, -{ 0x9922, 16, {0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} }, -{ 0x9932, 16, {0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4d, 0xe5, 0x4d, 0x60, 0x03, 0x02, 0x9b, 0x70, 0x90, 0x01, 0xc0} }, -{ 0x9942, 16, {0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7f} }, -{ 0x9952, 16, {0x02, 0x12, 0x81, 0xd9, 0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xef, 0x54, 0x0f, 0xf5} }, -{ 0x9962, 16, {0x4d, 0x90, 0x02, 0xf7, 0xe0, 0x55, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f} }, -{ 0x9972, 16, {0x4c, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4c, 0x70, 0x04, 0x7f} }, -{ 0x9982, 16, {0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4c, 0xe5, 0x4c, 0x70, 0x03, 0x02, 0x9b, 0x70, 0xe4, 0x90} }, -{ 0x9992, 16, {0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0xe4} }, -{ 0x99a2, 16, {0xff, 0xfd, 0x12, 0x82, 0xa8, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0x85} }, -{ 0x99b2, 16, {0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x4f, 0x82, 0x85} }, -{ 0x99c2, 16, {0x4e, 0x83, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3} }, -{ 0x99d2, 16, {0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xd2, 0x04, 0x02, 0x9b, 0x70, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00} }, -{ 0x99e2, 16, {0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xe5, 0x4f, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x4e, 0xf5} }, -{ 0x99f2, 16, {0x83, 0xe0, 0x30, 0xe6, 0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x02, 0x9b, 0x70, 0xe4} }, -{ 0x9a02, 16, {0xf5, 0x4d, 0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0xe5, 0x4b, 0x75, 0xf0, 0x08} }, -{ 0x9a12, 16, {0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xf5, 0x83} }, -{ 0x9a22, 16, {0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf} }, -{ 0x9a32, 16, {0x4b, 0x7d, 0x01, 0x7b, 0x01, 0x75, 0x57, 0x80, 0x75, 0x58, 0x40, 0x12, 0x96, 0x5e, 0x8f, 0x4d} }, -{ 0x9a42, 16, {0xe5, 0x4d, 0x70, 0x11, 0xaf, 0x4b, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20} }, -{ 0x9a52, 16, {0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d, 0x01, 0xfb, 0x75, 0x57} }, -{ 0x9a62, 16, {0x80, 0x75, 0x58, 0x40, 0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d} }, -{ 0x9a72, 16, {0x02, 0xfb, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20, 0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xaf, 0x4b, 0x7d} }, -{ 0x9a82, 16, {0x01, 0x12, 0x82, 0xa8, 0xe5, 0x4d, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04} }, -{ 0x9a92, 16, {0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83} }, -{ 0x9aa2, 16, {0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0x05, 0x4b} }, -{ 0x9ab2, 16, {0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x50, 0x03, 0x02, 0x9a, 0x06, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03} }, -{ 0x9ac2, 16, {0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74} }, -{ 0x9ad2, 16, {0x9b, 0xf0, 0xa3, 0x74, 0x92, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08} }, -{ 0x9ae2, 16, {0x70, 0x03, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03} }, -{ 0x9af2, 16, {0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5} }, -{ 0x9b02, 16, {0x52, 0xf0, 0xa3, 0xe5, 0x53, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10, 0x2c, 0xef, 0x64, 0x08} }, -{ 0x9b12, 16, {0x60, 0x5c, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x51, 0x24, 0x02, 0xff, 0xe4, 0x35} }, -{ 0x9b22, 16, {0x50, 0xfa, 0xa9, 0x07, 0x7b, 0x01, 0x7d, 0x10, 0x12, 0x95, 0xc1, 0xef, 0x4e, 0x70, 0x32, 0x90} }, -{ 0x9b32, 16, {0x03, 0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5} }, -{ 0x9b42, 16, {0x51, 0x24, 0x02, 0x90, 0x03, 0x60, 0xf0, 0xe4, 0x35, 0x50, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03} }, -{ 0x9b52, 16, {0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80} }, -{ 0x9b62, 16, {0x0d, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01} }, -{ 0x9b72, 16, {0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70} }, -{ 0x9b82, 15, {0xf6, 0x7e, 0x03, 0x7f, 0x35, 0x7d, 0x24, 0x12, 0x8e, 0xb4, 0xe4, 0x90, 0x02, 0xaf, 0xf0} }, -{ 0x9b91, 1, {0x22} }, -{ 0x9b92, 16, {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} }, -{ 0x9ba2, 16, {0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} }, -{ 0x9bb2, 16, {0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} }, -{ 0x9bc2, 16, {0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} }, -{ 0x9bd2, 16, {0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} }, -{ 0x9be2, 16, {0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} }, -{ 0x9bf2, 16, {0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} }, -{ 0x9c02, 16, {0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} }, -{ 0x9c12, 16, {0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} }, -{ 0x9c22, 16, {0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} }, -{ 0x9c32, 16, {0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} }, -{ 0x9c42, 16, {0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} }, -{ 0x9c52, 16, {0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} }, -{ 0x9c62, 16, {0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} }, -{ 0x9c72, 16, {0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} }, -{ 0x9c82, 16, {0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} }, -{ 0x9c92, 16, {0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} }, -{ 0x9ca2, 16, {0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} }, -{ 0x9cb2, 16, {0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} }, -{ 0x9cc2, 16, {0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} }, -{ 0x9cd2, 16, {0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} }, -{ 0x9ce2, 16, {0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} }, -{ 0x9cf2, 16, {0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} }, -{ 0x9d02, 16, {0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} }, -{ 0x9d12, 16, {0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} }, -{ 0x9d22, 16, {0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} }, -{ 0x9d32, 16, {0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} }, -{ 0x9d42, 16, {0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} }, -{ 0x9d52, 16, {0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} }, -{ 0x9d62, 16, {0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} }, -{ 0x9d72, 16, {0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} }, -{ 0x9d82, 16, {0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} }, -{ 0x9d92, 16, {0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} }, -{ 0x9da2, 16, {0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} }, -{ 0x9db2, 16, {0x9e, 0x45, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9e, 0x45, 0xef, 0x75, 0xf0} }, -{ 0x9dc2, 16, {0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} }, -{ 0x9dd2, 16, {0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} }, -{ 0x9de2, 16, {0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} }, -{ 0x9df2, 16, {0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} }, -{ 0x9e02, 16, {0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} }, -{ 0x9e12, 16, {0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} }, -{ 0x9e22, 16, {0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} }, -{ 0x9e32, 16, {0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} }, -{ 0x9e42, 12, {0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9d, 0xa4} }, -{ 0x9e4e, 1, {0x22} }, -{ 0x9e4f, 16, {0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} }, -{ 0x9e5f, 16, {0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} }, -{ 0x9e6f, 16, {0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} }, -{ 0x9e7f, 16, {0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} }, -{ 0x9e8f, 16, {0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} }, -{ 0x9e9f, 16, {0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} }, -{ 0x9eaf, 16, {0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} }, -{ 0x9ebf, 16, {0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} }, -{ 0x9ecf, 16, {0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} }, -{ 0x9edf, 16, {0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} }, -{ 0x9eef, 16, {0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} }, -{ 0x9eff, 16, {0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} }, -{ 0x9f0f, 16, {0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} }, -{ 0x9f1f, 16, {0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} }, -{ 0x9f2f, 16, {0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} }, -{ 0x9f3f, 9, {0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9e, 0x9f, 0x73} }, -{ 0x9f48, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} }, -{ 0x9f58, 9, {0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} }, -{ 0x9f61, 16, {0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} }, -{ 0x9f71, 16, {0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} }, -{ 0x9f81, 13, {0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} }, -{ 0x9f8e, 16, {0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} }, -{ 0x9f9e, 6, {0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} }, -{ 0x9fa4, 16, {0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} }, -{ 0x9fb4, 6, {0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} }, -{ 0x9fba, 16, {0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} }, -{ 0x9fca, 16, {0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} }, -{ 0x9fda, 16, {0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} }, -{ 0x9fea, 8, {0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} }, -{ 0x9ff2, 16, {0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} }, -{ 0xa002, 16, {0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} }, -{ 0xa012, 16, {0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} }, -{ 0xa022, 16, {0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} }, -{ 0xa032, 16, {0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} }, -{ 0xa042, 16, {0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} }, -{ 0xa052, 16, {0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} }, -{ 0xa062, 16, {0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} }, -{ 0xa072, 16, {0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} }, -{ 0xa082, 16, {0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} }, -{ 0xa092, 16, {0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} }, -{ 0xa0a2, 16, {0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} }, -{ 0xa0b2, 14, {0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} }, -{ 0xa0c0, 16, {0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} }, -{ 0xa0d0, 1, {0x22} }, -{ 0xa0d1, 16, {0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} }, -{ 0xa0e1, 3, {0xd8, 0xf1, 0x22} }, -{ 0xa0e4, 16, {0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} }, -{ 0xa0f4, 7, {0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} }, -{ 0xa0fb, 12, {0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} }, -{ 0xa107, 16, {0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa1, 0x1e, 0x12, 0xa1, 0x1e, 0x12} }, -{ 0xa117, 16, {0xa1, 0x1e, 0x12, 0xa1, 0x1e, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} }, -{ 0xa127, 16, {0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} }, -{ 0xa137, 1, {0x22} }, +{ 0x82a8, 2, {0xae, 0x07} }, +{ 0x82aa, 16, {0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} }, +{ 0x82ba, 16, {0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} }, +{ 0x82ca, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} }, +{ 0x82da, 16, {0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} }, +{ 0x82ea, 14, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} }, +{ 0x82f8, 1, {0x22} }, +{ 0x82f9, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} }, +{ 0x8309, 16, {0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5f, 0x74, 0xbf} }, +{ 0x8319, 16, {0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} }, +{ 0x8329, 16, {0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} }, +{ 0x8339, 16, {0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} }, +{ 0x8349, 16, {0xef, 0x55, 0x3c, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} }, +{ 0x8359, 16, {0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} }, +{ 0x8369, 16, {0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5f, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} }, +{ 0x8379, 4, {0x83, 0xa3, 0xe9, 0xf0} }, +{ 0x837d, 1, {0x22} }, +{ 0x837e, 4, {0x8f, 0x5f, 0x8d, 0x60} }, +{ 0x8382, 16, {0xe4, 0xf5, 0x61, 0x74, 0x3d, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5f, 0x75, 0xf0, 0x0d, 0xa4, 0x24} }, +{ 0x8392, 16, {0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, +{ 0x83a2, 16, {0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0xa1, 0xb7, 0x50} }, +{ 0x83b2, 16, {0x3c, 0xe5, 0x5f, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} }, +{ 0x83c2, 16, {0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} }, +{ 0x83d2, 16, {0x00, 0xc3, 0x12, 0xa1, 0xb7, 0x40, 0x0c, 0x75, 0x61, 0x40, 0x74, 0x3d, 0x25, 0x5f, 0xf8, 0x76} }, +{ 0x83e2, 16, {0x10, 0x80, 0x0a, 0x75, 0x61, 0x80, 0x74, 0x3d, 0x25, 0x5f, 0xf8, 0x76, 0x38, 0xe5, 0x61, 0x45} }, +{ 0x83f2, 16, {0x60, 0x44, 0x01, 0xff, 0xe5, 0x5f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} }, +{ 0x8402, 5, {0x20, 0xf5, 0x83, 0xef, 0xf0} }, +{ 0x8407, 1, {0x22} }, +{ 0x8408, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x55, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, +{ 0x8418, 16, {0xe5, 0x55, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} }, +{ 0x8428, 16, {0x56, 0x8f, 0x57, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} }, +{ 0x8438, 16, {0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} }, +{ 0x8448, 16, {0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x55, 0xf8, 0xe4, 0xf6, 0xe5, 0x57, 0x24, 0x04, 0xf5, 0x82} }, +{ 0x8458, 16, {0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf, 0x55, 0x7d, 0x06, 0x12, 0x83, 0x7e} }, +{ 0x8468, 16, {0xaf, 0x55, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0x85, 0x57, 0x82, 0x85, 0x56, 0x83, 0xa3, 0xa3, 0xe0} }, +{ 0x8478, 16, {0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83} }, +{ 0x8488, 16, {0xe0, 0xe5, 0x57, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x55} }, +{ 0x8498, 16, {0x7d, 0x06, 0x12, 0x83, 0x7e, 0x74, 0xf8, 0x25, 0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} }, +{ 0x84a8, 16, {0xe4, 0xf0, 0xe5, 0x55, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24} }, +{ 0x84b8, 16, {0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xef} }, +{ 0x84c8, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x55, 0x74, 0x01} }, +{ 0x84d8, 13, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x7f, 0x00} }, +{ 0x84e5, 1, {0x22} }, +{ 0x84e6, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x55, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, +{ 0x84f6, 16, {0xaf, 0x55, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0x74, 0xf8, 0x25, 0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02} }, +{ 0x8506, 16, {0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x55, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} }, +{ 0x8516, 16, {0x20, 0xaf, 0x82, 0xf5, 0x57, 0x8f, 0x58, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} }, +{ 0x8526, 16, {0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x55, 0x7d, 0x06, 0x12, 0x83, 0x7e, 0xe5} }, +{ 0x8536, 16, {0x58, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x58} }, +{ 0x8546, 16, {0x82, 0x85, 0x57, 0x83, 0xe0, 0xf5, 0x56, 0xaf, 0x55, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} }, +{ 0x8556, 16, {0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x31, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4} }, +{ 0x8566, 16, {0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82} }, +{ 0x8576, 9, {0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} }, +{ 0x857f, 1, {0x22} }, +{ 0x8580, 4, {0x8e, 0x55, 0x8f, 0x56} }, +{ 0x8584, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x57, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, +{ 0x8594, 16, {0xe5, 0x57, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} }, +{ 0x85a4, 16, {0x54, 0x03, 0x70, 0x24, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x07, 0xaf} }, +{ 0x85b4, 16, {0x57, 0x7d, 0x02, 0x12, 0x83, 0x7e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0x30, 0xe1} }, +{ 0x85c4, 10, {0x07, 0xaf, 0x57, 0x7d, 0x04, 0x12, 0x83, 0x7e, 0x7f, 0x00} }, +{ 0x85ce, 1, {0x22} }, +{ 0x85cf, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} }, +{ 0x85df, 16, {0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} }, +{ 0x85ef, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} }, +{ 0x85ff, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} }, +{ 0x860f, 16, {0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} }, +{ 0x861f, 16, {0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} }, +{ 0x862f, 16, {0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} }, +{ 0x863f, 16, {0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} }, +{ 0x864f, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} }, +{ 0x865f, 3, {0x83, 0xf0, 0x22} }, +{ 0x8662, 4, {0xad, 0x07, 0xac, 0x06} }, +{ 0x8666, 16, {0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} }, +{ 0x8676, 16, {0x22, 0x8c, 0x55, 0x8d, 0x56, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} }, +{ 0x8686, 16, {0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} }, +{ 0x8696, 16, {0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x56, 0xe5, 0x56, 0xaa, 0x55, 0x70, 0x02} }, +{ 0x86a6, 16, {0x05, 0x55, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, +{ 0x86b6, 1, {0x22} }, +{ 0x86b7, 4, {0x8e, 0x55, 0x8f, 0x56} }, +{ 0x86bb, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5c, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, +{ 0x86cb, 16, {0xe5, 0x5c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} }, +{ 0x86db, 16, {0x5d, 0x8f, 0x5e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} }, +{ 0x86eb, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa1} }, +{ 0x86fb, 16, {0xb7, 0x40, 0x10, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0x12, 0xa1, 0xfe, 0x00, 0x00, 0x00} }, +{ 0x870b, 16, {0x08, 0x80, 0x2e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} }, +{ 0x871b, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa1} }, +{ 0x872b, 16, {0xb7, 0x50, 0x0e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0x12, 0xa1, 0xfe, 0x00, 0x07, 0x08} }, +{ 0x873b, 16, {0x00, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} }, +{ 0x874b, 16, {0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa1, 0x25, 0x8f, 0x5a} }, +{ 0x875b, 16, {0x8e, 0x59, 0x8d, 0x58, 0x8c, 0x57, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa1} }, +{ 0x876b, 16, {0x25, 0xaf, 0x03, 0x8f, 0x5b, 0xaf, 0x5a, 0xae, 0x59, 0xad, 0x58, 0xac, 0x57, 0x7b, 0x0a, 0x7a} }, +{ 0x877b, 16, {0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa1, 0x25, 0x8f, 0x5a, 0x8e, 0x59, 0x8d, 0x58, 0x8c, 0x57} }, +{ 0x878b, 16, {0xe5, 0x5b, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x5a, 0x24, 0x01, 0xf5, 0x5a, 0xe4, 0x35, 0x59} }, +{ 0x879b, 16, {0xf5, 0x59, 0xe4, 0x35, 0x58, 0xf5, 0x58, 0xe4, 0x35, 0x57, 0xf5, 0x57, 0x85, 0x5e, 0x82, 0x85} }, +{ 0x87ab, 16, {0x5d, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} }, +{ 0x87bb, 16, {0x80, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xe5, 0x5a, 0xf0, 0xaf, 0x5a, 0xae, 0x59, 0xad} }, +{ 0x87cb, 16, {0x58, 0xac, 0x57, 0x78, 0x08, 0x12, 0xa1, 0xc8, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xef} }, +{ 0x87db, 16, {0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} }, +{ 0x87eb, 16, {0x5b, 0xe5, 0x56, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62} }, +{ 0x87fb, 16, {0x05, 0x43, 0x5b, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5b, 0x08, 0x80, 0x11, 0xef} }, +{ 0x880b, 16, {0xb4, 0x74, 0x05, 0x43, 0x5b, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22} }, +{ 0x881b, 16, {0xe5, 0x56, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03} }, +{ 0x882b, 16, {0x43, 0x5b, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5b, 0x40, 0xe5, 0x5e, 0x24, 0x04, 0xf5, 0x82} }, +{ 0x883b, 16, {0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x56, 0x24, 0x0b, 0xf5, 0x82, 0xe4} }, +{ 0x884b, 16, {0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf, 0x5c, 0x74, 0x01} }, +{ 0x885b, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3c, 0xe5, 0x5e, 0x24, 0x04, 0xf5} }, +{ 0x886b, 16, {0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5b, 0x80, 0x10, 0xaf} }, +{ 0x887b, 16, {0x5c, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x3c, 0x85} }, +{ 0x888b, 16, {0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d} }, +{ 0x889b, 16, {0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5b, 0xf0, 0xe5, 0x56, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x88ab, 16, {0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83} }, +{ 0x88bb, 16, {0xef, 0xf0, 0xe5, 0x56, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5} }, +{ 0x88cb, 16, {0x5e, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x56, 0x24, 0x09} }, +{ 0x88db, 16, {0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x06, 0xf5, 0x82, 0xe4} }, +{ 0x88eb, 16, {0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x56, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5} }, +{ 0x88fb, 16, {0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0} }, +{ 0x890b, 16, {0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d} }, +{ 0x891b, 16, {0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5c, 0x7d, 0x06, 0x12, 0x83, 0x7e, 0x75, 0x5b, 0x08, 0xe5, 0x56} }, +{ 0x892b, 16, {0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5b, 0x10, 0xe5} }, +{ 0x893b, 16, {0x5e, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5b, 0xf0} }, +{ 0x894b, 16, {0xe5, 0x56, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05} }, +{ 0x895b, 16, {0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x56, 0x24, 0x06, 0xf5} }, +{ 0x896b, 16, {0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94} }, +{ 0x897b, 16, {0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24} }, +{ 0x898b, 16, {0xfb, 0x4f, 0xf5, 0x5b, 0xe5, 0x56, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0} }, +{ 0x899b, 16, {0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a} }, +{ 0x89ab, 16, {0x70, 0x14, 0x43, 0x5b, 0x18, 0x80, 0x12, 0x43, 0x5b, 0x08, 0x80, 0x0d, 0x43, 0x5b, 0x38, 0x80} }, +{ 0x89bb, 16, {0x08, 0x43, 0x5b, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3} }, +{ 0x89cb, 16, {0xa3, 0xa3, 0xe5, 0x5b, 0xf0, 0xaf, 0x5c, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0xaa, 0x55, 0xa9, 0x56} }, +{ 0x89db, 16, {0x7b, 0x01, 0xc0, 0x01, 0xe5, 0x5c, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35} }, +{ 0x89eb, 15, {0xf0, 0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa0, 0x16, 0x7f, 0x00} }, +{ 0x89fa, 1, {0x22} }, +{ 0x89fb, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, +{ 0x8a0b, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} }, +{ 0x8a1b, 16, {0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} }, +{ 0x8a2b, 16, {0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} }, +{ 0x8a3b, 16, {0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} }, +{ 0x8a4b, 16, {0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} }, +{ 0x8a5b, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x55, 0xe5, 0x30, 0xc3, 0x94, 0x01} }, +{ 0x8a6b, 16, {0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x56, 0x00, 0xf5, 0x57, 0x80, 0x09, 0x7f} }, +{ 0x8a7b, 16, {0x02, 0x12, 0x81, 0xd9, 0x8e, 0x56, 0x8f, 0x57, 0xc3, 0xe5, 0x56, 0x64, 0x80, 0x94, 0x80, 0x40} }, +{ 0x8a8b, 16, {0xda, 0xe5, 0x55, 0x55, 0x57, 0x90, 0x01, 0x32, 0xf0, 0x7e, 0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12} }, +{ 0x8a9b, 4, {0x8f, 0x6e, 0x7f, 0x00} }, +{ 0x8a9f, 1, {0x22} }, +{ 0x8aa0, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, +{ 0x8ab0, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} }, +{ 0x8ac0, 16, {0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x8ad0, 16, {0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x8f} }, +{ 0x8ae0, 3, {0x6e, 0x7f, 0x00} }, +{ 0x8ae3, 1, {0x22} }, +{ 0x8ae4, 4, {0xad, 0x07, 0xac, 0x06} }, +{ 0x8ae8, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, +{ 0x8af8, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, +{ 0x8b08, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} }, +{ 0x8b18, 16, {0x44, 0x02, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} }, +{ 0x8b28, 4, {0xfd, 0xf0, 0x7f, 0x00} }, +{ 0x8b2c, 1, {0x22} }, +{ 0x8b2d, 4, {0xad, 0x07, 0xac, 0x06} }, +{ 0x8b31, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, +{ 0x8b41, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, +{ 0x8b51, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} }, +{ 0x8b61, 16, {0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} }, +{ 0x8b71, 4, {0xfe, 0xf0, 0x7f, 0x00} }, +{ 0x8b75, 1, {0x22} }, +{ 0x8b76, 4, {0xad, 0x07, 0xac, 0x06} }, +{ 0x8b7a, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, +{ 0x8b8a, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, +{ 0x8b9a, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} }, +{ 0x8baa, 16, {0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} }, +{ 0x8bba, 1, {0x22} }, +{ 0x8bbb, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} }, +{ 0x8bcb, 16, {0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0x7f, 0x00} }, +{ 0x8bdb, 1, {0x22} }, +{ 0x8bdc, 4, {0x8e, 0x55, 0x8f, 0x56} }, +{ 0x8be0, 16, {0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x5a, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xd3} }, +{ 0x8bf0, 16, {0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x57, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} }, +{ 0x8c00, 16, {0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x58, 0x7e, 0x75, 0x59} }, +{ 0x8c10, 16, {0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x58, 0x7e, 0x75, 0x59, 0x00, 0x80, 0x16, 0x7e} }, +{ 0x8c20, 16, {0x7d, 0x7f, 0x80, 0x75, 0x58, 0x7d, 0x75, 0x59, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} }, +{ 0x8c30, 16, {0x58, 0x7d, 0x75, 0x59, 0x00, 0xe5, 0x5a, 0x70, 0x1b, 0x85, 0x59, 0x82, 0x85, 0x58, 0x83, 0x74} }, +{ 0x8c40, 16, {0xff, 0xf0, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} }, +{ 0x8c50, 16, {0x01, 0xf0, 0x80, 0x48, 0xe5, 0x56, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x55, 0xfe, 0xe5, 0x5a, 0x60} }, +{ 0x8c60, 16, {0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} }, +{ 0x8c70, 16, {0x59, 0xe5, 0x59, 0xaa, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} }, +{ 0x8c80, 16, {0x15, 0x5a, 0x80, 0xd9, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x57, 0x25} }, +{ 0x8c90, 14, {0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} }, +{ 0x8c9e, 1, {0x22} }, +{ 0x8c9f, 16, {0xef, 0x24, 0x05, 0xf5, 0x56, 0xe4, 0x3e, 0xf5, 0x55, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} }, +{ 0x8caf, 16, {0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3} }, +{ 0x8cbf, 16, {0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x57, 0xf5, 0x58, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} }, +{ 0x8ccf, 16, {0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8d, 0x80} }, +{ 0x8cdf, 16, {0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0xcc, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe} }, +{ 0x8cef, 16, {0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x5a, 0x74, 0x01, 0x9e, 0xf5, 0x59, 0xd3, 0xe5, 0x5a} }, +{ 0x8cff, 16, {0x94, 0x40, 0xe5, 0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x40, 0xd3, 0xe5} }, +{ 0x8d0f, 16, {0x58, 0x95, 0x5a, 0xe5, 0x57, 0x95, 0x59, 0x50, 0x03, 0x02, 0x8d, 0xcf, 0xae, 0x59, 0xaf, 0x5a} }, +{ 0x8d1f, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} }, +{ 0x8d2f, 16, {0x57, 0xf5, 0x58, 0x02, 0x8d, 0xcf, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} }, +{ 0x8d3f, 16, {0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x5a, 0xe4, 0x9e, 0xf5, 0x59, 0xd3, 0xe5, 0x5a, 0x94} }, +{ 0x8d4f, 16, {0x10, 0xe5, 0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x10, 0xd3, 0xe5, 0x58} }, +{ 0x8d5f, 16, {0x95, 0x5a, 0xe5, 0x57, 0x95, 0x59, 0x40, 0x68, 0xae, 0x59, 0xaf, 0x5a, 0x85, 0x56, 0x82, 0x85} }, +{ 0x8d6f, 16, {0x55, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x57, 0xf5, 0x58, 0x80} }, +{ 0x8d7f, 16, {0x4f, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} }, +{ 0x8d8f, 16, {0xf5, 0x5a, 0xe4, 0x9e, 0xf5, 0x59, 0x45, 0x5a, 0x60, 0x0b, 0xd3, 0xe5, 0x5a, 0x94, 0x40, 0xe5} }, +{ 0x8d9f, 16, {0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x40, 0xd3, 0xe5, 0x58, 0x95, 0x5a} }, +{ 0x8daf, 16, {0xe5, 0x57, 0x95, 0x59, 0x40, 0x17, 0xae, 0x59, 0xaf, 0x5a, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} }, +{ 0x8dbf, 16, {0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x57, 0xf5, 0x58, 0x7f, 0x01, 0x22} }, +{ 0x8dcf, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8e, 0x8f, 0x24, 0xf9} }, +{ 0x8ddf, 16, {0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8e, 0xdf, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8f, 0x23} }, +{ 0x8def, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} }, +{ 0x8dff, 16, {0x94, 0x00, 0x40, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58} }, +{ 0x8e0f, 16, {0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x70, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x75, 0xe0} }, +{ 0x8e1f, 16, {0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0} }, +{ 0x8e2f, 16, {0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} }, +{ 0x8e3f, 16, {0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8f} }, +{ 0x8e4f, 16, {0x23, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x76} }, +{ 0x8e5f, 16, {0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x70, 0x03, 0x02} }, +{ 0x8e6f, 16, {0x8f, 0x23, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} }, +{ 0x8e7f, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} }, +{ 0x8e8f, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} }, +{ 0x8e9f, 16, {0x94, 0x00, 0x50, 0x03, 0x02, 0x8f, 0x23, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} }, +{ 0x8eaf, 16, {0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e} }, +{ 0x8ebf, 16, {0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} }, +{ 0x8ecf, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} }, +{ 0x8edf, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} }, +{ 0x8eef, 16, {0xa3, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x60, 0x24} }, +{ 0x8eff, 16, {0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} }, +{ 0x8f0f, 16, {0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83} }, +{ 0x8f1f, 16, {0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3} }, +{ 0x8f2f, 11, {0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x8f, 0x6e, 0x7f, 0x00} }, +{ 0x8f3a, 1, {0x22} }, +{ 0x8f3b, 16, {0x8e, 0x60, 0x8f, 0x61, 0x8c, 0x62, 0x8d, 0x63, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x61} }, +{ 0x8f4b, 16, {0xe5, 0x61, 0xae, 0x60, 0x70, 0x02, 0x05, 0x60, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} }, +{ 0x8f5b, 16, {0x63, 0xe5, 0x63, 0xac, 0x62, 0x70, 0x02, 0x05, 0x62, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, +{ 0x8f6b, 3, {0x80, 0xd6, 0x22} }, +{ 0x8f6e, 6, {0x8d, 0x5b, 0xab, 0x07, 0xaa, 0x06} }, +{ 0x8f74, 16, {0x75, 0x5f, 0x40, 0x75, 0x5e, 0x0d, 0x75, 0x5d, 0x03, 0x75, 0x5c, 0x00, 0x90, 0x7f, 0xc2, 0xe0} }, +{ 0x8f84, 16, {0x20, 0xe1, 0xf9, 0xaf, 0x5f, 0xae, 0x5e, 0xad, 0x5d, 0xac, 0x5c, 0xec, 0x4d, 0x4e, 0x4f, 0x70} }, +{ 0x8f94, 16, {0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} }, +{ 0x8fa4, 16, {0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5b, 0x12, 0x8f, 0x3b, 0x90, 0x7f, 0xc3} }, +{ 0x8fb4, 8, {0xe5, 0x5b, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, +{ 0x8fbc, 1, {0x22} }, +{ 0x8fbd, 16, {0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0xa3, 0xe5, 0x30, 0xf0, 0x90, 0x0a, 0xf1, 0xe4, 0x93, 0x90} }, +{ 0x8fcd, 16, {0x01, 0x86, 0xf0, 0x90, 0x0a, 0xf2, 0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c} }, +{ 0x8fdd, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01} }, +{ 0x8fed, 16, {0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e, 0x01, 0x7f, 0x7c, 0x12, 0x19, 0xc1, 0x7e, 0x01, 0x7f, 0x84} }, +{ 0x8ffd, 7, {0x7d, 0x14, 0x12, 0x8f, 0x6e, 0x7f, 0x00} }, +{ 0x9004, 1, {0x22} }, +{ 0x9005, 16, {0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4c, 0x7b, 0x75, 0x4d, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} }, +{ 0x9015, 16, {0x4c, 0x4f, 0x85, 0x4d, 0x50, 0xe5, 0x50, 0x24, 0x01, 0xf5, 0x54, 0xe4, 0x35, 0x4f, 0xf5, 0x53} }, +{ 0x9025, 16, {0xe4, 0xf5, 0x4e, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} }, +{ 0x9035, 16, {0x5b, 0x90, 0x90, 0x3d, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x90, 0x61, 0x02, 0x90, 0x61, 0x02, 0x90} }, +{ 0x9045, 16, {0x6b, 0x02, 0x90, 0x75, 0x02, 0x90, 0x75, 0x02, 0x90, 0x75, 0x02, 0x90, 0x89, 0x02, 0x90, 0x61} }, +{ 0x9055, 16, {0x02, 0x90, 0x7f, 0x02, 0x90, 0x61, 0x02, 0x90, 0x91, 0x02, 0x90, 0x61, 0xef, 0x64, 0x02, 0x60} }, +{ 0x9065, 16, {0x2b, 0x75, 0x4e, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x4e, 0xff, 0x80, 0x1c} }, +{ 0x9075, 16, {0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x4e, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} }, +{ 0x9085, 16, {0x4e, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x4e, 0xff, 0xe5, 0x4e, 0x60, 0x15} }, +{ 0x9095, 16, {0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} }, +{ 0x90a5, 16, {0x8f, 0x6e, 0xaf, 0x4e, 0x22, 0xe4, 0xf5, 0x4e, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0x14} }, +{ 0x90b5, 16, {0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x91, 0xd3, 0x90, 0x90, 0xc4, 0xf8, 0x28, 0x28, 0x73, 0x02} }, +{ 0x90c5, 16, {0x90, 0xf1, 0x02, 0x90, 0xfd, 0x02, 0x91, 0x09, 0x02, 0x91, 0x57, 0x02, 0x91, 0x62, 0x02, 0x91} }, +{ 0x90d5, 16, {0x6d, 0x02, 0x91, 0x78, 0x02, 0x91, 0x83, 0x02, 0x91, 0x8e, 0x02, 0x91, 0x99, 0x02, 0x91, 0xa4} }, +{ 0x90e5, 16, {0x02, 0x91, 0xab, 0x02, 0x91, 0xd3, 0x02, 0x91, 0xb6, 0x02, 0x91, 0xc1, 0xaf, 0x54, 0xae, 0x53} }, +{ 0x90f5, 16, {0x12, 0x84, 0x08, 0x8f, 0x4e, 0x02, 0x91, 0xd6, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x84, 0xe6, 0x8f} }, +{ 0x9105, 16, {0x4e, 0x02, 0x91, 0xd6, 0x85, 0x53, 0x51, 0x85, 0x54, 0x52, 0xe5, 0x52, 0x24, 0x01, 0xff, 0xe4} }, +{ 0x9115, 16, {0x35, 0x51, 0xfe, 0x12, 0x85, 0xcf, 0xaf, 0x52, 0xae, 0x51, 0x12, 0x86, 0x62, 0x8f, 0x4e, 0xef} }, +{ 0x9125, 16, {0x64, 0x01, 0x60, 0x03, 0x02, 0x91, 0xd6, 0xaf, 0x52, 0xae, 0x51, 0x12, 0x86, 0xb7, 0x8f, 0x4e} }, +{ 0x9135, 16, {0xe5, 0x4e, 0x70, 0x03, 0x02, 0x91, 0xd6, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0x75, 0xf0} }, +{ 0x9145, 16, {0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x86, 0xb7, 0x02} }, +{ 0x9155, 16, {0x91, 0xd6, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8a, 0xe4, 0x8f, 0x4e, 0x80, 0x74, 0xaf, 0x54, 0xae} }, +{ 0x9165, 16, {0x53, 0x12, 0x8b, 0x2d, 0x8f, 0x4e, 0x80, 0x69, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0x76, 0x8f} }, +{ 0x9175, 16, {0x4e, 0x80, 0x5e, 0xaf, 0x4d, 0xae, 0x4c, 0x12, 0x8c, 0x9f, 0x8f, 0x4e, 0x80, 0x53, 0xaf, 0x54} }, +{ 0x9185, 16, {0xae, 0x53, 0x12, 0x89, 0xfb, 0x8f, 0x4e, 0x80, 0x48, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x85, 0x80} }, +{ 0x9195, 16, {0x8f, 0x4e, 0x80, 0x3d, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8a, 0xa0, 0x8f, 0x4e, 0x80, 0x32, 0x12} }, +{ 0x91a5, 16, {0x8f, 0xbd, 0x8f, 0x4e, 0x80, 0x2b, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0xbb, 0x8f, 0x4e, 0x80} }, +{ 0x91b5, 16, {0x20, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0xdc, 0x8f, 0x4e, 0x80, 0x15, 0xaf, 0x4d, 0xae, 0x4c} }, +{ 0x91c5, 16, {0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8f, 0x3b, 0xe4, 0xf5, 0x4e, 0x80, 0x03, 0x75, 0x4e} }, +{ 0x91d5, 16, {0xff, 0xe5, 0x4e, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x50, 0x82, 0x85, 0x4f} }, +{ 0x91e5, 16, {0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x8f, 0x6e, 0xaf} }, +{ 0x91f5, 16, {0x4e, 0x22, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} }, +{ 0x9205, 16, {0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x54, 0x82, 0x85} }, +{ 0x9215, 16, {0x53, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x8f, 0x6e} }, +{ 0x9225, 4, {0x8f, 0x4e, 0xaf, 0x4e} }, +{ 0x9229, 1, {0x22} }, +{ 0x922a, 8, {0x8f, 0x4f, 0x8e, 0x4e, 0x8d, 0x4d, 0x8c, 0x4c} }, +{ 0x9232, 16, {0x75, 0x56, 0x01, 0x75, 0x57, 0x9c, 0xe4, 0xf5, 0x55, 0xaf, 0x51, 0x15, 0x51, 0xef, 0x70, 0x03} }, +{ 0x9242, 16, {0x02, 0x92, 0xc8, 0xaf, 0x50, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4f} }, +{ 0x9252, 16, {0xae, 0x4e, 0xad, 0x4d, 0xac, 0x4c, 0x12, 0xa1, 0x25, 0xaf, 0x03, 0x8f, 0x54, 0xaf, 0x4f, 0xae} }, +{ 0x9262, 16, {0x4e, 0xad, 0x4d, 0xac, 0x4c, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x50, 0xe4} }, +{ 0x9272, 16, {0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} }, +{ 0x9282, 16, {0x12, 0xa1, 0x25, 0x8f, 0x4f, 0x8e, 0x4e, 0x8d, 0x4d, 0x8c, 0x4c, 0xe5, 0x54, 0x24, 0x30, 0xf5} }, +{ 0x9292, 16, {0x54, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x54, 0xf5, 0x54, 0x05, 0x57, 0xe5, 0x57} }, +{ 0x92a2, 16, {0xae, 0x56, 0x70, 0x02, 0x05, 0x56, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x57, 0xe5} }, +{ 0x92b2, 16, {0x57, 0xae, 0x56, 0x70, 0x02, 0x05, 0x56, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x54, 0xf0, 0x05} }, +{ 0x92c2, 16, {0x55, 0x05, 0x55, 0x02, 0x92, 0x3b, 0xe5, 0x57, 0x15, 0x57, 0x70, 0x02, 0x15, 0x56, 0xaf, 0x55} }, +{ 0x92d2, 16, {0x15, 0x55, 0xef, 0x60, 0x23, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0xf5} }, +{ 0x92e2, 16, {0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14} }, +{ 0x92f2, 8, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} }, +{ 0x92fa, 1, {0x22} }, +{ 0x92fb, 16, {0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} }, +{ 0x930b, 10, {0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} }, +{ 0x9315, 16, {0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} }, +{ 0x9325, 16, {0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} }, +{ 0x9335, 16, {0xe4, 0xef, 0x55, 0x31, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} }, +{ 0x9345, 16, {0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} }, +{ 0x9355, 16, {0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa0, 0x85, 0xfc, 0xd3, 0xe5, 0xf0} }, +{ 0x9365, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} }, +{ 0x9375, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, +{ 0x9385, 1, {0x22} }, +{ 0x9386, 16, {0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} }, +{ 0x9396, 16, {0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} }, +{ 0x93a6, 16, {0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} }, +{ 0x93b6, 16, {0xa0, 0x16, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa0, 0x85, 0xfc, 0xd3, 0xe5, 0xf0} }, +{ 0x93c6, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} }, +{ 0x93d6, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, +{ 0x93e6, 1, {0x22} }, +{ 0x93e7, 16, {0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x51, 0x7b, 0x75, 0x52} }, +{ 0x93f7, 16, {0x80, 0xe5, 0x52, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x51, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x53, 0xf5} }, +{ 0x9407, 16, {0x54, 0x89, 0x55, 0xfe, 0x12, 0x93, 0x86, 0xef, 0x60, 0x50, 0xab, 0x53, 0xaa, 0x54, 0xa9, 0x55} }, +{ 0x9417, 16, {0x12, 0xa0, 0x3f, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0xb4, 0x02, 0x16, 0xc2, 0xaf} }, +{ 0x9427, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} }, +{ 0x9437, 16, {0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} }, +{ 0x9447, 16, {0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x31, 0x60, 0x0f, 0x85, 0x52, 0x82, 0x85, 0x51} }, +{ 0x9457, 10, {0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} }, +{ 0x9461, 1, {0x22} }, +{ 0x9462, 16, {0x12, 0x93, 0xe7, 0xe4, 0xf5, 0x4c, 0x74, 0x37, 0x25, 0x4c, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4d} }, +{ 0x9472, 16, {0x74, 0xc5, 0x25, 0x4c, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4d, 0xff, 0xc4} }, +{ 0x9482, 16, {0x54, 0x0f, 0xf5, 0x4e, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4c, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} }, +{ 0x9492, 16, {0x83, 0xe5, 0x4d, 0xf0, 0xaf, 0x4c, 0x7d, 0x01, 0xe5, 0x4d, 0x45, 0x4e, 0xfb, 0x12, 0x93, 0x15} }, +{ 0x94a2, 16, {0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xec, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40} }, +{ 0x94b2, 16, {0xb5, 0x12, 0x93, 0xe7, 0xe5, 0x3b, 0x60, 0x48, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0x74, 0x01, 0xa8} }, +{ 0x94c2, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x55, 0x3b, 0x60, 0x29, 0xe5, 0x4c} }, +{ 0x94d2, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} }, +{ 0x94e2, 16, {0x16, 0xaf, 0x4c, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7} }, +{ 0x94f2, 16, {0x80, 0xef, 0xe5, 0x4d, 0xf4, 0x52, 0x3b, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40, 0xbb} }, +{ 0x9502, 16, {0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x95, 0xe3, 0x74, 0x19, 0xf0, 0xe5, 0x30, 0xc3, 0x94} }, +{ 0x9512, 16, {0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x4f, 0x00, 0xf5, 0x50, 0x80, 0x09} }, +{ 0x9522, 16, {0x7f, 0x02, 0x12, 0x81, 0xd9, 0x8e, 0x4f, 0x8f, 0x50, 0xc3, 0xe5, 0x4f, 0x64, 0x80, 0x94, 0x80} }, +{ 0x9532, 16, {0x40, 0xda, 0x90, 0x01, 0xbc, 0xe0, 0x65, 0x50, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c} }, +{ 0x9542, 16, {0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x90, 0x01, 0xbc} }, +{ 0x9552, 16, {0xe0, 0x55, 0x4d, 0x60, 0x14, 0xaf, 0x4c, 0x7d, 0x08, 0xe5, 0x4d, 0x55, 0x50, 0xfb, 0x12, 0x93} }, +{ 0x9562, 16, {0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xec, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04} }, +{ 0x9572, 16, {0x40, 0xcc, 0x90, 0x01, 0xbc, 0xe5, 0x50, 0xf0, 0xe4, 0xf5, 0x4c, 0xc2, 0xaf, 0x74, 0x33, 0x25} }, +{ 0x9582, 16, {0x4c, 0xf8, 0xe6, 0xf5, 0x4d, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4d, 0x1e, 0xe5, 0x4d, 0x60, 0x11} }, +{ 0x9592, 16, {0xaf, 0x4c, 0x7d, 0x02, 0xab, 0x4d, 0x12, 0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80} }, +{ 0x95a2, 16, {0xef, 0x74, 0x2c, 0x25, 0x4c, 0xf8, 0xe6, 0xf5, 0x4d, 0x74, 0xfc, 0x25, 0x4c, 0xf5, 0x82, 0xe4} }, +{ 0x95b2, 16, {0x34, 0x02, 0xf5, 0x83, 0xe0, 0x65, 0x4d, 0x60, 0x11, 0xaf, 0x4c, 0x7d, 0x04, 0xab, 0x4d, 0x12} }, +{ 0x95c2, 16, {0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4c, 0xf5, 0x82} }, +{ 0x95d2, 16, {0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe5, 0x4d, 0xf0, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40} }, +{ 0x95e2, 4, {0x9a, 0x12, 0x93, 0xe7} }, +{ 0x95e6, 1, {0x22} }, +{ 0x95e7, 12, {0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x63, 0x02, 0x96, 0x2e} }, +{ 0x95f3, 16, {0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} }, +{ 0x9603, 16, {0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} }, +{ 0x9613, 16, {0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} }, +{ 0x9623, 16, {0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x96, 0x73, 0xe4, 0x7e} }, +{ 0x9633, 16, {0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} }, +{ 0x9643, 16, {0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} }, +{ 0x9653, 16, {0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} }, +{ 0x9663, 16, {0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} }, +{ 0x9673, 16, {0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} }, +{ 0x9683, 16, {0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} }, +{ 0x9693, 8, {0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} }, +{ 0x969b, 1, {0x00} }, +{ 0x969c, 8, {0x8b, 0x57, 0x8a, 0x58, 0x89, 0x59, 0x8d, 0x5a} }, +{ 0x96a4, 16, {0xe4, 0xf5, 0x5b, 0xf5, 0x5c, 0xaf, 0x5a, 0x15, 0x5a, 0xef, 0x60, 0x36, 0xab, 0x57, 0x05, 0x59} }, +{ 0x96b4, 16, {0xe5, 0x59, 0xaa, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf9, 0x12, 0xa0, 0x3f, 0xff, 0xe5, 0x5b} }, +{ 0x96c4, 16, {0xe5, 0x5c, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0x99, 0x2f, 0xf5, 0x82, 0xee, 0x34} }, +{ 0x96d4, 16, {0x9c, 0xf5, 0x83, 0xe5, 0x5b, 0xff, 0xe4, 0x93, 0xf5, 0x5b, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x5c} }, +{ 0x96e4, 6, {0x80, 0xc3, 0xae, 0x5b, 0xaf, 0x5c} }, +{ 0x96ea, 1, {0x22} }, +{ 0x96eb, 11, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} }, +{ 0x96f6, 16, {0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} }, +{ 0x9706, 16, {0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} }, +{ 0x9716, 16, {0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} }, +{ 0x9726, 10, {0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} }, +{ 0x9730, 9, {0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x9739, 2, {0xa9, 0x03} }, +{ 0x973b, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} }, +{ 0x974b, 16, {0x5a, 0x45, 0x5b, 0xf5, 0x5c, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} }, +{ 0x975b, 16, {0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} }, +{ 0x976b, 16, {0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x5c, 0xeb} }, +{ 0x977b, 16, {0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x5c, 0xfc, 0xb5, 0x06, 0x03, 0xaf} }, +{ 0x978b, 16, {0x05, 0x22, 0xe5, 0x5a, 0x5c, 0xfe, 0xe5, 0x5b, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} }, +{ 0x979b, 16, {0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} }, +{ 0x97ab, 16, {0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x5a, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x5b, 0x22, 0x7f} }, +{ 0x97bb, 1, {0x00} }, +{ 0x97bc, 1, {0x22} }, +{ 0x97bd, 16, {0x75, 0x53, 0x02, 0x75, 0x54, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x54, 0x82, 0x85} }, +{ 0x97cd, 16, {0x53, 0x83, 0xa3, 0xe0, 0xff, 0x90, 0x03, 0x37, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0} }, +{ 0x97dd, 16, {0x90, 0x03, 0x36, 0xf0, 0x90, 0x03, 0x38, 0x74, 0xff, 0xf0, 0x75, 0x55, 0x03, 0x75, 0x56, 0x39} }, +{ 0x97ed, 16, {0xef, 0x14, 0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9c, 0x61, 0x90, 0x97, 0xfe, 0xf8, 0x28, 0x28} }, +{ 0x97fd, 16, {0x73, 0x02, 0x98, 0x1f, 0x02, 0x98, 0xbe, 0x02, 0x99, 0xc3, 0x02, 0x99, 0xe2, 0x02, 0x99, 0xe2} }, +{ 0x980d, 16, {0x02, 0x9a, 0x98, 0x02, 0x9a, 0xd3, 0x02, 0x9a, 0xf8, 0x02, 0x9b, 0xb6, 0x02, 0x9b, 0xe6, 0x02} }, +{ 0x981d, 16, {0x9c, 0x12, 0xe4, 0xf5, 0x4c, 0xe5, 0x4c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4} }, +{ 0x982d, 16, {0x34, 0x20, 0xaf, 0x82, 0xf5, 0x51, 0x8f, 0x52, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74} }, +{ 0x983d, 16, {0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4d, 0x80, 0x0d, 0x74} }, +{ 0x984d, 16, {0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4d, 0xe5, 0x52, 0x24, 0x07} }, +{ 0x985d, 16, {0xf5, 0x82, 0xe4, 0x35, 0x51, 0xf5, 0x83, 0xe5, 0x4d, 0xf0, 0xe0, 0xf5, 0x4e, 0x65, 0x4d, 0x60} }, +{ 0x986d, 16, {0x38, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xfd, 0x05, 0x56, 0xe5, 0x56, 0xaa, 0x55} }, +{ 0x987d, 16, {0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x56, 0xe5, 0x56, 0xac} }, +{ 0x988d, 16, {0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4d, 0xf0, 0x85, 0x56, 0x82} }, +{ 0x989d, 16, {0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64} }, +{ 0x98ad, 16, {0x02, 0x70, 0x87, 0x05, 0x4c, 0xe5, 0x4c, 0x64, 0x04, 0x60, 0x03, 0x02, 0x98, 0x22, 0x02, 0x9c} }, +{ 0x98bd, 16, {0x67, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0x05, 0x4c, 0xe5, 0x4c, 0xd3} }, +{ 0x98cd, 16, {0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x96, 0xf0, 0xa3, 0x74, 0xeb, 0xf0, 0xe4, 0xf5} }, +{ 0x98dd, 16, {0x4e, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75, 0x52, 0x00, 0xf5, 0x4c, 0xaf, 0x4c, 0x74} }, +{ 0x98ed, 16, {0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x90, 0x01, 0xc4, 0xf0} }, +{ 0x98fd, 16, {0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xa3} }, +{ 0x990d, 16, {0x74, 0x02, 0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4d, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02} }, +{ 0x991d, 16, {0xa3, 0xe0, 0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xff, 0x05, 0x56, 0xe5, 0x56} }, +{ 0x992d, 16, {0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x56, 0x82} }, +{ 0x993d, 16, {0x85, 0x55, 0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4e, 0xff, 0x90, 0x01} }, +{ 0x994d, 16, {0xc4, 0xe0, 0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xfe, 0x05, 0x56} }, +{ 0x995d, 16, {0xe5, 0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05} }, +{ 0x996d, 16, {0x56, 0xe5, 0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, +{ 0x997d, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe5, 0x4d, 0xf0, 0x75, 0x4e, 0xff, 0xe5, 0x4e, 0x70, 0x16} }, +{ 0x998d, 16, {0x74, 0x08, 0x25, 0x52, 0xf5, 0x52, 0xe4, 0x35, 0x51, 0xf5, 0x51, 0x05, 0x4c, 0xe5, 0x4c, 0x64} }, +{ 0x999d, 16, {0x04, 0x60, 0x03, 0x02, 0x98, 0xea, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0x7d, 0x01, 0x12, 0x82, 0xf9} }, +{ 0x99ad, 16, {0x05, 0x4c, 0xe5, 0x4c, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3} }, +{ 0x99bd, 16, {0x74, 0x12, 0xf0, 0x02, 0x9c, 0x67, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0, 0x14, 0xff, 0x74} }, +{ 0x99cd, 16, {0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01} }, +{ 0x99dd, 16, {0xc4, 0xf0, 0x02, 0x9c, 0x67, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4} }, +{ 0x99ed, 16, {0xf5, 0x4e, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01} }, +{ 0x99fd, 16, {0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x56, 0x82, 0x85} }, +{ 0x9a0d, 16, {0x55, 0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4e, 0xe5, 0x4e, 0x60, 0x03, 0x02, 0x9c, 0x67, 0x90, 0x01} }, +{ 0x9a1d, 16, {0xc0, 0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6} }, +{ 0x9a2d, 16, {0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x4f, 0x00} }, +{ 0x9a3d, 16, {0xf5, 0x50, 0x80, 0x09, 0x7f, 0x02, 0x12, 0x81, 0xd9, 0x8e, 0x4f, 0x8f, 0x50, 0xc3, 0xe5, 0x4f} }, +{ 0x9a4d, 16, {0x64, 0x80, 0x94, 0x80, 0x40, 0xda, 0xe5, 0x50, 0x54, 0x0f, 0xf5, 0x4e, 0x90, 0x02, 0xf7, 0xe0} }, +{ 0x9a5d, 16, {0x55, 0x4e, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4d, 0x85, 0x54, 0x82, 0x85} }, +{ 0x9a6d, 16, {0x53, 0x83, 0xa3, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} }, +{ 0x9a7d, 16, {0x00, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x03, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x85} }, +{ 0x9a8d, 16, {0x56, 0x82, 0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0xe4, 0xff, 0xfd, 0x12, 0x82} }, +{ 0x9a9d, 16, {0xf9, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75, 0x52, 0x00, 0x85, 0x52, 0x82, 0x85, 0x51} }, +{ 0x9aad, 16, {0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0x74, 0x01} }, +{ 0x9abd, 16, {0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f} }, +{ 0x9acd, 16, {0xf0, 0xd2, 0x04, 0x02, 0x9c, 0x67, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75} }, +{ 0x9add, 16, {0x52, 0x00, 0xe5, 0x52, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x51, 0xf5, 0x83, 0xe0, 0x30, 0xe6} }, +{ 0x9aed, 16, {0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0x02, 0x9c, 0x67, 0xe4, 0xf5, 0x4e, 0xf5, 0x4c} }, +{ 0x9afd, 16, {0xaf, 0x4c, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0xe5, 0x4c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5} }, +{ 0x9b0d, 16, {0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x51, 0x8f, 0x52, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04} }, +{ 0x9b1d, 16, {0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x4c, 0x7d, 0x01, 0x7b} }, +{ 0x9b2d, 16, {0x01, 0x75, 0x5a, 0x80, 0x75, 0x5b, 0x40, 0x12, 0x97, 0x39, 0x8f, 0x4e, 0xe5, 0x4e, 0x70, 0x11} }, +{ 0x9b3d, 16, {0xaf, 0x4c, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x5a, 0x10, 0x75, 0x5b, 0x20, 0x12, 0x97, 0x39, 0x8f} }, +{ 0x9b4d, 16, {0x4e, 0xe5, 0x4e, 0x70, 0x10, 0xaf, 0x4c, 0x7d, 0x01, 0xfb, 0x75, 0x5a, 0x80, 0x75, 0x5b, 0x40} }, +{ 0x9b5d, 16, {0x12, 0x97, 0x39, 0x8f, 0x4e, 0xe5, 0x4e, 0x70, 0x10, 0xaf, 0x4c, 0x7d, 0x02, 0xfb, 0x75, 0x5a} }, +{ 0x9b6d, 16, {0x10, 0x75, 0x5b, 0x20, 0x12, 0x97, 0x39, 0x8f, 0x4e, 0xaf, 0x4c, 0x7d, 0x01, 0x12, 0x82, 0xf9} }, +{ 0x9b7d, 16, {0xe5, 0x4e, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xff, 0x05, 0x56, 0xe5} }, +{ 0x9b8d, 16, {0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x56} }, +{ 0x9b9d, 16, {0x82, 0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0x05, 0x4c, 0xe5, 0x4c, 0xd3, 0x94} }, +{ 0x9bad, 16, {0x03, 0x50, 0x03, 0x02, 0x9a, 0xfd, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} }, +{ 0x9bbd, 16, {0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x9c, 0xf0, 0xa3, 0x74} }, +{ 0x9bcd, 16, {0x89, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10, 0xcc, 0xef, 0x64, 0x08, 0x70, 0x03, 0x02, 0x9c} }, +{ 0x9bdd, 16, {0x67, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} }, +{ 0x9bed, 16, {0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5, 0x55, 0xf0, 0xa3, 0xe5} }, +{ 0x9bfd, 16, {0x56, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x5c, 0xe4, 0x90} }, +{ 0x9c0d, 16, {0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x54, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x53, 0xfa, 0xa9, 0x07} }, +{ 0x9c1d, 16, {0x7b, 0x01, 0x7d, 0x10, 0x12, 0x96, 0x9c, 0xef, 0x4e, 0x70, 0x32, 0x90, 0x03, 0x59, 0xf0, 0xa3} }, +{ 0x9c2d, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5, 0x54, 0x24, 0x02, 0x90} }, +{ 0x9c3d, 16, {0x03, 0x60, 0xf0, 0xe4, 0x35, 0x53, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10} }, +{ 0x9c4d, 16, {0xcc, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x0d, 0xe4, 0x90, 0x03} }, +{ 0x9c5d, 16, {0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3} }, +{ 0x9c6d, 16, {0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7e, 0x03, 0x7f} }, +{ 0x9c7d, 11, {0x35, 0x7d, 0x24, 0x12, 0x8f, 0x6e, 0xe4, 0x90, 0x02, 0xaf, 0xf0} }, +{ 0x9c88, 1, {0x22} }, +{ 0x9c89, 16, {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} }, +{ 0x9c99, 16, {0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} }, +{ 0x9ca9, 16, {0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} }, +{ 0x9cb9, 16, {0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} }, +{ 0x9cc9, 16, {0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} }, +{ 0x9cd9, 16, {0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} }, +{ 0x9ce9, 16, {0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} }, +{ 0x9cf9, 16, {0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} }, +{ 0x9d09, 16, {0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} }, +{ 0x9d19, 16, {0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} }, +{ 0x9d29, 16, {0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} }, +{ 0x9d39, 16, {0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} }, +{ 0x9d49, 16, {0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} }, +{ 0x9d59, 16, {0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} }, +{ 0x9d69, 16, {0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} }, +{ 0x9d79, 16, {0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} }, +{ 0x9d89, 16, {0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} }, +{ 0x9d99, 16, {0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} }, +{ 0x9da9, 16, {0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} }, +{ 0x9db9, 16, {0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} }, +{ 0x9dc9, 16, {0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} }, +{ 0x9dd9, 16, {0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} }, +{ 0x9de9, 16, {0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} }, +{ 0x9df9, 16, {0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} }, +{ 0x9e09, 16, {0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} }, +{ 0x9e19, 16, {0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} }, +{ 0x9e29, 16, {0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} }, +{ 0x9e39, 16, {0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} }, +{ 0x9e49, 16, {0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} }, +{ 0x9e59, 16, {0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} }, +{ 0x9e69, 16, {0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} }, +{ 0x9e79, 16, {0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} }, +{ 0x9e89, 16, {0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} }, +{ 0x9e99, 16, {0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} }, +{ 0x9ea9, 16, {0x9f, 0x3c, 0x74, 0x37, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9f, 0x3c, 0xef, 0x75, 0xf0} }, +{ 0x9eb9, 16, {0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} }, +{ 0x9ec9, 16, {0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} }, +{ 0x9ed9, 16, {0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} }, +{ 0x9ee9, 16, {0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} }, +{ 0x9ef9, 16, {0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} }, +{ 0x9f09, 16, {0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} }, +{ 0x9f19, 16, {0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} }, +{ 0x9f29, 16, {0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} }, +{ 0x9f39, 12, {0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9e, 0x9b} }, +{ 0x9f45, 1, {0x22} }, +{ 0x9f46, 16, {0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} }, +{ 0x9f56, 16, {0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} }, +{ 0x9f66, 16, {0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} }, +{ 0x9f76, 16, {0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} }, +{ 0x9f86, 16, {0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} }, +{ 0x9f96, 16, {0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} }, +{ 0x9fa6, 16, {0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} }, +{ 0x9fb6, 16, {0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} }, +{ 0x9fc6, 16, {0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} }, +{ 0x9fd6, 16, {0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} }, +{ 0x9fe6, 16, {0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} }, +{ 0x9ff6, 16, {0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} }, +{ 0xa006, 16, {0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} }, +{ 0xa016, 16, {0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} }, +{ 0xa026, 16, {0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} }, +{ 0xa036, 9, {0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9f, 0x96, 0x73} }, +{ 0xa03f, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} }, +{ 0xa04f, 9, {0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} }, +{ 0xa058, 16, {0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} }, +{ 0xa068, 16, {0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} }, +{ 0xa078, 13, {0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} }, +{ 0xa085, 16, {0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} }, +{ 0xa095, 6, {0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} }, +{ 0xa09b, 16, {0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} }, +{ 0xa0ab, 6, {0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} }, +{ 0xa0b1, 16, {0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} }, +{ 0xa0c1, 16, {0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} }, +{ 0xa0d1, 16, {0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} }, +{ 0xa0e1, 8, {0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} }, +{ 0xa0e9, 16, {0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} }, +{ 0xa0f9, 16, {0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} }, +{ 0xa109, 16, {0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} }, +{ 0xa119, 16, {0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} }, +{ 0xa129, 16, {0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} }, +{ 0xa139, 16, {0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} }, +{ 0xa149, 16, {0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} }, +{ 0xa159, 16, {0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} }, +{ 0xa169, 16, {0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} }, +{ 0xa179, 16, {0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} }, +{ 0xa189, 16, {0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} }, +{ 0xa199, 16, {0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} }, +{ 0xa1a9, 14, {0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} }, +{ 0xa1b7, 16, {0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} }, +{ 0xa1c7, 1, {0x22} }, +{ 0xa1c8, 16, {0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} }, +{ 0xa1d8, 3, {0xd8, 0xf1, 0x22} }, +{ 0xa1db, 16, {0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} }, +{ 0xa1eb, 7, {0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} }, +{ 0xa1f2, 12, {0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} }, +{ 0xa1fe, 16, {0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa2, 0x15, 0x12, 0xa2, 0x15, 0x12} }, +{ 0xa20e, 16, {0xa2, 0x15, 0x12, 0xa2, 0x15, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} }, +{ 0xa21e, 16, {0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} }, +{ 0xa22e, 1, {0x22} }, { 0xffff, 0, {0x00} } }; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/storage/scsiglue.c linux/drivers/usb/storage/scsiglue.c --- v2.5.0/linux/drivers/usb/storage/scsiglue.c Sun Nov 11 10:01:32 2001 +++ linux/drivers/usb/storage/scsiglue.c Wed Nov 28 10:22:27 2001 @@ -388,7 +388,6 @@ present: 0, unchecked_isa_dma: FALSE, use_clustering: TRUE, - use_new_eh_code: TRUE, emulated: TRUE }; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c --- v2.5.0/linux/drivers/usb/usb-ohci.c Fri Nov 9 13:41:42 2001 +++ linux/drivers/usb/usb-ohci.c Sat Dec 8 20:28:45 2001 @@ -485,7 +485,7 @@ /* implicitly requeued */ urb->actual_length = 0; - urb->status = USB_ST_URB_PENDING; + urb->status = -EINPROGRESS; if (urb_priv->state != URB_DEL) td_submit_urb (urb); break; @@ -502,7 +502,7 @@ urb->complete (urb); spin_lock_irqsave (&usb_ed_lock, flags); urb->actual_length = 0; - urb->status = USB_ST_URB_PENDING; + urb->status = -EINPROGRESS; urb->start_frame = urb_priv->ed->last_iso + 1; if (urb_priv->state != URB_DEL) { for (i = 0; i < urb->number_of_packets; i++) { @@ -673,7 +673,7 @@ urb->actual_length = 0; urb->hcpriv = urb_priv; - urb->status = USB_ST_URB_PENDING; + urb->status = -EINPROGRESS; /* link the ed into a chain if is not already */ if (ed->state != ED_OPER) @@ -737,7 +737,7 @@ if (usb_pipedevice (urb->pipe) == ohci->rh.devnum) return rh_unlink_urb (urb); - if (urb->hcpriv && (urb->status == USB_ST_URB_PENDING)) { + if (urb->hcpriv && (urb->status == -EINPROGRESS)) { if (!ohci->disabled) { urb_priv_t * urb_priv; @@ -777,11 +777,11 @@ /* wait until all TDs are deleted */ set_current_state(TASK_UNINTERRUPTIBLE); - while (timeout && (urb->status == USB_ST_URB_PENDING)) + while (timeout && (urb->status == -EINPROGRESS)) timeout = schedule_timeout (timeout); set_current_state(TASK_RUNNING); remove_wait_queue (&unlink_wakeup, &wait); - if (urb->status == USB_ST_URB_PENDING) { + if (urb->status == -EINPROGRESS) { err ("unlink URB timeout"); return -ETIMEDOUT; } diff -u --recursive --new-file v2.5.0/linux/drivers/usb/usb-ohci.h linux/drivers/usb/usb-ohci.h --- v2.5.0/linux/drivers/usb/usb-ohci.h Wed Oct 24 08:26:12 2001 +++ linux/drivers/usb/usb-ohci.h Sat Dec 8 20:28:45 2001 @@ -11,22 +11,22 @@ static int cc_to_error[16] = { /* mapping of the OHCI CC status to error codes */ - /* No Error */ USB_ST_NOERROR, - /* CRC Error */ USB_ST_CRC, - /* Bit Stuff */ USB_ST_BITSTUFF, - /* Data Togg */ USB_ST_CRC, - /* Stall */ USB_ST_STALL, - /* DevNotResp */ USB_ST_NORESPONSE, - /* PIDCheck */ USB_ST_BITSTUFF, - /* UnExpPID */ USB_ST_BITSTUFF, - /* DataOver */ USB_ST_DATAOVERRUN, - /* DataUnder */ USB_ST_DATAUNDERRUN, - /* reservd */ USB_ST_NORESPONSE, - /* reservd */ USB_ST_NORESPONSE, - /* BufferOver */ USB_ST_BUFFEROVERRUN, - /* BuffUnder */ USB_ST_BUFFERUNDERRUN, - /* Not Access */ USB_ST_NORESPONSE, - /* Not Access */ USB_ST_NORESPONSE + /* No Error */ 0, + /* CRC Error */ -EILSEQ, + /* Bit Stuff */ -EPROTO, + /* Data Togg */ -EILSEQ, + /* Stall */ -EPIPE, + /* DevNotResp */ -ETIMEDOUT, + /* PIDCheck */ -EPROTO, + /* UnExpPID */ -EPROTO, + /* DataOver */ -EOVERFLOW, + /* DataUnder */ -EREMOTEIO, + /* reservd */ -ETIMEDOUT, + /* reservd */ -ETIMEDOUT, + /* BufferOver */ -ECOMM, + /* BuffUnder */ -ENOSR, + /* Not Access */ -ETIMEDOUT, + /* Not Access */ -ETIMEDOUT }; #include diff -u --recursive --new-file v2.5.0/linux/drivers/usb/usb.c linux/drivers/usb/usb.c --- v2.5.0/linux/drivers/usb/usb.c Wed Nov 21 09:59:11 2001 +++ linux/drivers/usb/usb.c Sat Dec 8 20:28:45 2001 @@ -7,7 +7,8 @@ * (C) Copyright Gregory P. Smith 1999 * (C) Copyright Deti Fliegl 1999 (new USB architecture) * (C) Copyright Randy Dunlap 2000 - * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id) + * (C) Copyright David Brownell 2000-2001 (kernel hotplug, usb_device_id, + more docs, etc) * (C) Copyright Yggdrasil Computing, Inc. 2000 * (usb_device_id matching changes by Adam J. Richter) * @@ -105,8 +106,8 @@ * Goes through all unclaimed USB interfaces, and offers them to all * registered USB drivers through the 'probe' function. * This will automatically be called after usb_register is called. - * It is called by some of the USB subsystems after one of their subdrivers - * are registered. + * It is called by some of the subsystems layered over USB + * after one of their subdrivers are registered. */ void usb_scan_devices(void) { @@ -193,6 +194,22 @@ up (&usb_bus_list_lock); } +/** + * usb_ifnum_to_if - get the interface object with a given interface number + * @dev: the device whose current configuration is considered + * @ifnum: the desired interface + * + * This walks the device descriptor for the currently active configuration + * and returns a pointer to the interface with that particular interface + * number, or null. + * + * Note that configuration descriptors are not required to assign interface + * numbers sequentially, so that it would be incorrect to assume that + * the first interface in that descriptor corresponds to interface zero. + * This routine helps device drivers avoid such mistakes. + * However, you should make sure that you do the right thing with any + * alternate settings available for this interfaces. + */ struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum) { int i; @@ -204,6 +221,20 @@ return NULL; } +/** + * usb_epnum_to_ep_desc - get the endpoint object with a given endpoint number + * @dev: the device whose current configuration is considered + * @epnum: the desired endpoint + * + * This walks the device descriptor for the currently active configuration, + * and returns a pointer to the endpoint with that particular endpoint + * number, or null. + * + * Note that interface descriptors are not required to assign endpont + * numbers sequentially, so that it would be incorrect to assume that + * the first endpoint in that descriptor corresponds to interface zero. + * This routine helps device drivers avoid such mistakes. + */ struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum) { int i, j, k; @@ -261,7 +292,7 @@ * bustime is from calc_bus_time(), but converted to microseconds. * * returns if successful, - * or USB_ST_BANDWIDTH_ERROR if bandwidth request fails. + * or -ENOSPC if bandwidth request fails. * * FIXME: * This initial implementation does not use Endpoint.bInterval @@ -302,7 +333,7 @@ if (!usb_bandwidth_option) /* don't enforce it */ return (bustime); - return (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? bustime : USB_ST_BANDWIDTH_ERROR; + return (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? bustime : -ENOSPC; } void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc) @@ -356,7 +387,7 @@ } /** - * usb_alloc_bus - creates a new USB host controller structure + * usb_alloc_bus - creates a new USB host controller structure (usbcore-internal) * @op: pointer to a struct usb_operations that this bus structure should use * * Creates a USB host controller bus structure with the specified @@ -398,7 +429,7 @@ } /** - * usb_free_bus - frees the memory used by a bus structure + * usb_free_bus - frees the memory used by a bus structure (usbcore-internal) * @bus: pointer to the bus to free * * (For use only by USB Host Controller Drivers.) @@ -412,10 +443,12 @@ } /** - * usb_register_bus - registers the USB host controller with the usb core + * usb_register_bus - registers the USB host controller with the usb core (usbcore-internal) * @bus: pointer to the bus to register * * (For use only by USB Host Controller Drivers.) + * + * This call is synchronous, and may not be used in an interrupt context. */ void usb_register_bus(struct usb_bus *bus) { @@ -441,10 +474,12 @@ } /** - * usb_deregister_bus - deregisters the USB host controller + * usb_deregister_bus - deregisters the USB host controller (usbcore-internal) * @bus: pointer to the bus to deregister * * (For use only by USB Host Controller Drivers.) + * + * This call is synchronous, and may not be used in an interrupt context. */ void usb_deregister_bus(struct usb_bus *bus) { @@ -493,27 +528,49 @@ } -/* - * This is intended to be used by usb device drivers that need to - * claim more than one interface on a device at once when probing - * (audio and acm are good examples). No device driver should have - * to mess with the internal usb_interface or usb_device structure - * members. +/** + * usb_driver_claim_interface - bind a driver to an interface + * @driver: the driver to be bound + * @iface: the interface to which it will be bound + * @priv: driver data associated with that interface + * + * This is used by usb device drivers that need to claim more than one + * interface on a device when probing (audio and acm are current examples). + * No device driver should directly modify internal usb_interface or + * usb_device structure members. + * + * Few drivers should need to use this routine, since the most natural + * way to bind to an interface is to return the private data from + * the driver's probe() method. Any driver that does use this must + * first be sure that no other driver has claimed the interface, by + * checking with usb_interface_claimed(). */ void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv) { if (!iface || !driver) return; - dbg("%s driver claimed interface %p", driver->name, iface); + // FIXME change API to report an error in this case + if (iface->driver) + err ("%s driver booted %s off interface %p", + driver->name, iface->driver->name, iface); + else + dbg("%s driver claimed interface %p", driver->name, iface); iface->driver = driver; iface->private_data = priv; } /* usb_driver_claim_interface() */ -/* +/** + * usb_interface_claimed - returns true iff an interface is claimed + * @iface: the interface being checked + * * This should be used by drivers to check other interfaces to see if - * they are available or not. + * they are available or not. If another driver has claimed the interface, + * they may not claim it. Otherwise it's OK to claim it using + * usb_driver_claim_interface(). + * + * Returns true (nonzero) iff the interface is claimed, else false (zero). */ int usb_interface_claimed(struct usb_interface *iface) { @@ -523,8 +580,19 @@ return (iface->driver != NULL); } /* usb_interface_claimed() */ -/* - * This should be used by drivers to release their claimed interfaces +/** + * usb_driver_release_interface - unbind a driver from an interface + * @driver: the driver to be unbound + * @iface: the interface from which it will be unbound + * + * This should be used by drivers to release their claimed interfaces. + * It is normally called in their disconnect() methods, and only for + * drivers that bound to more than one interface in their probe(). + * + * When the USB subsystem disconnect()s a driver from some interface, + * it automatically invokes this method for that interface. That + * means that even drivers that used usb_driver_claim_interface() + * usually won't need to call this. */ void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface) { @@ -923,9 +991,15 @@ } } -/* - * Only HC's should call usb_alloc_dev and usb_free_dev directly - * Anybody may use usb_inc_dev_use or usb_dec_dev_use +/** + * usb_alloc_dev - allocate a usb device structure (usbcore-internal) + * @parent: hub to which device is connected + * @bus: bus used to access the device + * + * Only hub drivers (including virtual root hub drivers for host + * controllers) should ever call this. + * + * This call is synchronous, and may not be used in an interrupt context. */ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus) { @@ -952,6 +1026,8 @@ return dev; } +// usbcore-internal ... +// but usb_dec_dev_use() is #defined to this, and that's public!! void usb_free_dev(struct usb_device *dev) { if (atomic_dec_and_test(&dev->refcnt)) { @@ -964,14 +1040,25 @@ } } +/** + * usb_inc_dev_use - record another reference to a device + * @dev: the device being referenced + * + * Each live reference to a device should be refcounted. + * + * Device drivers should normally record such references in their + * open() methods. + * Drivers should then release them, using usb_dec_dev_use(), in their + * close() methods. + */ void usb_inc_dev_use(struct usb_device *dev) { atomic_inc(&dev->refcnt); } -/* ------------------------------------------------------------------------------------- +/* ---------------------------------------------------------------------- * New USB Core Functions - * -------------------------------------------------------------------------------------*/ + * ----------------------------------------------------------------------*/ /** * usb_alloc_urb - creates a new urb for a USB driver to use @@ -1017,6 +1104,61 @@ kfree(urb); } /*-------------------------------------------------------------------*/ + +/** + * usb_submit_urb - asynchronously issue a transfer request for an endpoint + * @urb: pointer to the urb describing the request + * + * This submits a transfer request, and transfers control of the URB + * describing that request to the USB subsystem. Request completion will + * indicated later, asynchronously, by calling the completion handler. + * This call may be issued in interrupt context. + * + * The caller must have correctly initialized the URB before submitting + * it. Macros such as FILL_BULK_URB() and FILL_CONTROL_URB() are + * available to ensure that most fields are correctly initialized, for + * the particular kind of transfer, although they will not initialize + * any transfer flags. + * + * Successful submissions return 0; otherwise this routine returns a + * negative error number. If the submission is successful, the complete + * fuction of the urb will be called when the USB host driver is + * finished with the urb (either a successful transmission, or some + * error case.) + * + * Unreserved Bandwidth Transfers: + * + * Bulk or control requests complete only once. When the completion + * function is called, control of the URB is returned to the device + * driver which issued the request. The completion handler may then + * immediately free or reuse that URB. + * + * Bulk URBs will be queued if the USB_QUEUE_BULK transfer flag is set + * in the URB. This can be used to maximize bandwidth utilization by + * letting the USB controller start work on the next URB without any + * delay to report completion (scheduling and processing an interrupt) + * and then submit that next request. + * + * For control endpoints, the synchronous usb_control_msg() call is + * often used (in non-interrupt context) instead of this call. + * + * Reserved Bandwidth Transfers: + * + * Periodic URBs (interrupt or isochronous) are completed repeatedly, + * until the original request is aborted. When the completion callback + * indicates the URB has been unlinked (with a special status code), + * control of that URB returns to the device driver. Otherwise, the + * completion handler does not control the URB, and should not change + * any of its fields. + * + * Note that isochronous URBs should be submitted in a "ring" data + * structure (using urb->next) to ensure that they are resubmitted + * appropriately. + * + * If the USB subsystem can't reserve sufficient bandwidth to perform + * the periodic request, and bandwidth reservation is being done for + * this controller, submitting such a periodic request will fail. + */ int usb_submit_urb(urb_t *urb) { if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op) @@ -1026,6 +1168,31 @@ } /*-------------------------------------------------------------------*/ + +/** + * usb_unlink_urb - abort/cancel a transfer request for an endpoint + * @urb: pointer to urb describing a previously submitted request + * + * This routine cancels an in-progress request. The requests's + * completion handler will be called with a status code indicating + * that the request has been canceled, and that control of the URB + * has been returned to that device driver. This is the only way + * to stop an interrupt transfer, so long as the device is connected. + * + * When the USB_ASYNC_UNLINK transfer flag for the URB is clear, this + * request is synchronous. Success is indicated by returning zero, + * at which time the urb will have been unlinked, + * and the completion function will see status -ENOENT. Failure is + * indicated by any other return value. This mode may not be used + * when unlinking an urb from an interrupt context, such as a bottom + * half or a completion handler, + * + * When the USB_ASYNC_UNLINK transfer flag for the URB is set, this + * request is asynchronous. Success is indicated by returning -EINPROGRESS, + * at which time the urb will normally not have been unlinked, + * and the completion function will see status -ECONNRESET. Failure is + * indicated by any other return value. + */ int usb_unlink_urb(urb_t *urb) { if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op) @@ -1034,12 +1201,14 @@ return -ENODEV; } /*-------------------------------------------------------------------* - * COMPLETION HANDLERS * + * SYNCHRONOUS CALLS * *-------------------------------------------------------------------*/ -/*-------------------------------------------------------------------* - * completion handler for compatibility wrappers (sync control/bulk) * - *-------------------------------------------------------------------*/ +struct usb_api_data { + wait_queue_head_t wqh; + int done; +}; + static void usb_api_blocking_completion(urb_t *urb) { struct usb_api_data *awd = (struct usb_api_data *)urb->context; @@ -1049,10 +1218,6 @@ wake_up(&awd->wqh); } -/*-------------------------------------------------------------------* - * COMPATIBILITY STUFF * - *-------------------------------------------------------------------*/ - // Starts urb and waits for completion or timeout static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length) { @@ -1145,7 +1310,7 @@ * This function sends a simple control message to a specified endpoint * and waits for the message to complete, or timeout. * - * If successful, it returns 0, othwise a negative error number. + * If successful, it returns 0, otherwise a negative error number. * * Don't use this function from within an interrupt context, like a * bottom half handler. If you need a asyncronous message, or need to send @@ -1188,9 +1353,9 @@ * This function sends a simple bulk message to a specified endpoint * and waits for the message to complete, or timeout. * - * If successful, it returns 0, othwise a negative error number. - * The number of actual bytes transferred will be plaed in the - * actual_timeout paramater. + * If successful, it returns 0, otherwise a negative error number. + * The number of actual bytes transferred will be stored in the + * actual_length paramater. * * Don't use this function from within an interrupt context, like a * bottom half handler. If you need a asyncronous message, or need to @@ -1214,16 +1379,19 @@ return usb_start_wait_urb(urb,timeout,actual_length); } -/* - * usb_get_current_frame_number() +/** + * usb_get_current_frame_number - return current bus frame number + * @dev: the device whose bus is being queried * - * returns the current frame number for the parent USB bus/controller - * of the given USB device. + * Returns the current frame number for the USB host controller + * used with the given USB device. This can be used when scheduling + * isochronous requests. */ -int usb_get_current_frame_number(struct usb_device *usb_dev) +int usb_get_current_frame_number(struct usb_device *dev) { - return usb_dev->bus->op->get_frame_number (usb_dev); + return dev->bus->op->get_frame_number (dev); } + /*-------------------------------------------------------------------*/ static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char *buffer, int size) @@ -1556,6 +1724,8 @@ return size; } +// hub-only!! ... and only exported for reset/reinit path. +// otherwise used internally on disconnect/destroy path void usb_destroy_configuration(struct usb_device *dev) { int c, i, j, k; @@ -1685,8 +1855,16 @@ return -1; } -/* +/** + * usb_disconnect - disconnect a device (usbcore-internal) + * @pdev: pointer to device being disconnected + * * Something got disconnected. Get rid of it, and all of its children. + * + * Only hub drivers (including virtual root hub drivers for host + * controllers) should ever call this. + * + * This call is synchronous, and may not be used in an interrupt context. */ void usb_disconnect(struct usb_device **pdev) { @@ -1735,11 +1913,17 @@ usb_free_dev(dev); } -/* +/** + * usb_connect - connects a new device during enumeration (usbcore-internal) + * @dev: partially enumerated device + * * Connect a new USB device. This basically just initializes * the USB device information and sets up the topology - it's * up to the low-level driver to reset the port and actually * do the setup (the upper levels don't know how to do that). + * + * Only hub drivers (including virtual root hub drivers for host + * controllers) should ever call this. */ void usb_connect(struct usb_device *dev) { @@ -1747,6 +1931,9 @@ // FIXME needs locking for SMP!! /* why? this is called only from the hub thread, * which hopefully doesn't run on multiple CPU's simultaneously 8-) + * ... it's also called from modprobe/rmmod/apmd threads as part + * of virtual root hub init/reinit. In the init case, the hub code + * won't have seen this, but not so for reinit ... */ dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */ #ifndef DEVNUM_ROUND_ROBIN @@ -1770,19 +1957,38 @@ * These are the actual routines to send * and receive control messages. */ -#ifdef CONFIG_USB_LONG_TIMEOUT -#define GET_TIMEOUT 4 -#else -#define GET_TIMEOUT 3 -#endif -#define SET_TIMEOUT 3 +// hub-only!! ... and only exported for reset/reinit path. +// otherwise used internally, for usb_new_device() int usb_set_address(struct usb_device *dev) { return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS, - 0, dev->devnum, 0, NULL, 0, HZ * GET_TIMEOUT); + // FIXME USB_CTRL_SET_TIMEOUT + 0, dev->devnum, 0, NULL, 0, HZ * USB_CTRL_GET_TIMEOUT); } +/** + * usb_get_descriptor - issues a generic GET_DESCRIPTOR request + * @dev: the device whose descriptor is being retrieved + * @type: the descriptor type (USB_DT_*) + * @index: the number of the descriptor + * @buf: where to put the descriptor + * @size: how big is "buf"? + * + * Gets a USB descriptor. Convenience functions exist to simplify + * getting some types of descriptors. Use + * usb_get_device_descriptor() for USB_DT_DEVICE, + * and usb_get_string() or usb_string() for USB_DT_STRING. + * Configuration descriptors (USB_DT_CONFIG) are part of the device + * structure, at least for the current configuration. + * In addition to a number of USB-standard descriptors, some + * devices also use class-specific or vendor-specific descriptors. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Returns zero on success, or else the status code returned by the + * underlying usb_control_msg() call. + */ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size) { int i = 5; @@ -1791,30 +1997,64 @@ memset(buf,0,size); // Make sure we parse really received data while (i--) { + /* retries if the returned length was 0; flakey device */ if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (type << 8) + index, 0, buf, size, HZ * GET_TIMEOUT)) > 0 || - result == -EPIPE) - break; /* retry if the returned length was 0; flaky device */ + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + (type << 8) + index, 0, buf, size, + HZ * USB_CTRL_GET_TIMEOUT)) > 0 + || result == -EPIPE) + break; } return result; } -int usb_get_class_descriptor(struct usb_device *dev, int ifnum, - unsigned char type, unsigned char id, void *buf, int size) -{ - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT); -} - +/** + * usb_get_string - gets a string descriptor + * @dev: the device whose string descriptor is being retrieved + * @langid: code for language chosen (from string descriptor zero) + * @index: the number of the descriptor + * @buf: where to put the string + * @size: how big is "buf"? + * + * Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character, + * in little-endian byte order). + * The usb_string() function will often be a convenient way to turn + * these strings into kernel-printable form. + * + * Strings may be referenced in device, configuration, interface, or other + * descriptors, and could also be used in vendor-specific ways. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Returns zero on success, or else the status code returned by the + * underlying usb_control_msg() call. + */ int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (USB_DT_STRING << 8) + index, langid, buf, size, HZ * GET_TIMEOUT); + (USB_DT_STRING << 8) + index, langid, buf, size, + HZ * USB_CTRL_GET_TIMEOUT); } +/** + * usb_get_device_descriptor - (re)reads the device descriptor + * @dev: the device whose device descriptor is being updated + * + * Updates the copy of the device descriptor stored in the device structure, + * which dedicates space for this purpose. Note that several fields are + * converted to the host CPU's byte order: the USB version (bcdUSB), and + * vendors product and version fields (idVendor, idProduct, and bcdDevice). + * That lets device drivers compare against non-byteswapped constants. + * + * There's normally no need to use this call, although some devices + * will change their descriptors after events like updating firmware. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Returns zero on success, or else the status code returned by the + * underlying usb_control_msg() call. + */ int usb_get_device_descriptor(struct usb_device *dev) { int ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, @@ -1828,39 +2068,37 @@ return ret; } +/** + * usb_get_status - issues a GET_STATUS call + * @dev: the device whose status is being checked + * @type: USB_RECIP_*; for device, interface, or endpoint + * @target: zero (for device), else interface or endpoint number + * @data: pointer to two bytes of bitmap data + * + * Returns device, interface, or endpoint status. Normally only of + * interest to see if the device is self powered, or has enabled the + * remote wakeup facility; or whether a bulk or interrupt endpoint + * is halted ("stalled"). + * + * Bits in these status bitmaps are set using the SET_FEATURE request, + * and cleared using the CLEAR_FEATURE request. The usb_clear_halt() + * function should be used to clear halt ("stall") status. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Returns zero on success, or else the status code returned by the + * underlying usb_control_msg() call. + */ int usb_get_status(struct usb_device *dev, int type, int target, void *data) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, HZ * GET_TIMEOUT); + USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, + HZ * USB_CTRL_GET_TIMEOUT); } -int usb_get_protocol(struct usb_device *dev, int ifnum) -{ - unsigned char type; - int ret; - - if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, ifnum, &type, 1, HZ * GET_TIMEOUT)) < 0) - return ret; - - return type; -} - -int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - protocol, ifnum, NULL, 0, HZ * SET_TIMEOUT); -} - -int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (duration << 8) | report_id, ifnum, NULL, 0, HZ * SET_TIMEOUT); -} +// hub-only!! ... and only exported for reset/reinit path. +// otherwise used internally, for config/altsetting reconfig. void usb_set_maxpacket(struct usb_device *dev) { int i, b; @@ -1890,9 +2128,26 @@ } } -/* - * endp: endpoint number in bits 0-3; - * direction flag in bit 7 (1 = IN, 0 = OUT) +/** + * usb_clear_halt - tells device to clear endpoint halt/stall condition + * @dev: device whose endpoint is halted + * @pipe: endpoint "pipe" being cleared + * + * This is used to clear halt conditions for bulk and interrupt endpoints, + * as reported by URB completion status. Endpoints that are halted are + * sometimes referred to as being "stalled". Such endpoints are unable + * to transmit or receive data until the halt status is cleared. Any URBs + * queued queued for such an endpoint should normally be unlinked before + * clearing the halt condition. + * + * Note that control and isochronous endpoints don't halt, although control + * endpoints report "protocol stall" (for unsupported requests) using the + * same status code used to report a true stall. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Returns zero on success, or else the status code returned by the + * underlying usb_control_msg() call. */ int usb_clear_halt(struct usb_device *dev, int pipe) { @@ -1907,7 +2162,8 @@ */ result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, HZ * SET_TIMEOUT); + USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, + HZ * USB_CTRL_SET_TIMEOUT); /* don't clear if failed */ if (result < 0) @@ -1921,7 +2177,8 @@ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp, - buffer, sizeof(status), HZ * SET_TIMEOUT); + // FIXME USB_CTRL_GET_TIMEOUT, yes? why not usb_get_status() ? + buffer, sizeof(status), HZ * USB_CTRL_SET_TIMEOUT); memcpy(&status, buffer, sizeof(status)); kfree(buffer); @@ -1941,6 +2198,33 @@ return 0; } +/** + * usb_set_interface - Makes a particular alternate setting be current + * @dev: the device whose interface is being updated + * @interface: the interface being updated + * @alternate: the setting being chosen. + * + * This is used to enable data transfers on interfaces that may not + * be enabled by default. Not all devices support such configurability. + * + * Within any given configuration, each interface may have several + * alternative settings. These are often used to control levels of + * bandwidth consumption. For example, the default setting for a high + * speed interrupt endpoint may not send more than about 4KBytes per + * microframe, and isochronous endpoints may never be part of a an + * interface's default setting. To access such bandwidth, alternate + * interface setting must be made current. + * + * Note that in the Linux USB subsystem, bandwidth associated with + * an endpoint in a given alternate setting is not reserved until an + * is submitted that needs that bandwidth. Some other operating systems + * allocate bandwidth early, when a configuration is chosen. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Returns zero on success, or else the status code returned by the + * underlying usb_control_msg() call. + */ int usb_set_interface(struct usb_device *dev, int interface, int alternate) { struct usb_interface *iface; @@ -1964,6 +2248,35 @@ return 0; } +/** + * usb_set_configuration - Makes a particular device setting be current + * @dev: the device whose configuration is being updated + * @configuration: the configuration being chosen. + * + * This is used to enable non-default device modes. Not all devices + * support this kind of configurability. By default, configuration + * zero is selected after enumeration; many devices only have a single + * configuration. + * + * USB devices may support one or more configurations, which affect + * power consumption and the functionality available. For example, + * the default configuration is limited to using 100mA of bus power, + * so that when certain device functionality requires more power, + * and the device is bus powered, that functionality will be in some + * non-default device configuration. Other device modes may also be + * reflected as configuration options, such as whether two ISDN + * channels are presented as independent 64Kb/s interfaces or as one + * bonded 128Kb/s interface. + * + * Note that USB has an additional level of device configurability, + * associated with interfaces. That configurability is accessed using + * usb_set_interface(). + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Returns zero on success, or else the status code returned by the + * underlying usb_control_msg() call. + */ int usb_set_configuration(struct usb_device *dev, int configuration) { int i, ret; @@ -1981,7 +2294,8 @@ } if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_CONFIGURATION, 0, configuration, 0, NULL, 0, HZ * SET_TIMEOUT)) < 0) + USB_REQ_SET_CONFIGURATION, 0, configuration, 0, + NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0) return ret; dev->actconfig = cp; @@ -1992,20 +2306,8 @@ return 0; } -int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size) -{ - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT); -} - -int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, ifnum, buf, size, HZ); -} - +// hub-only!! ... and only in reset path, or usb_new_device() +// (used by real hubs and virtual root hubs) int usb_get_configuration(struct usb_device *dev) { int result; @@ -2106,9 +2408,28 @@ return result; } -/* - * usb_string: - * returns string length (> 0) or error (< 0) +/** + * usb_string - returns ISO 8859-1 version of a string descriptor + * @dev: the device whose string descriptor is being retrieved + * @index: the number of the descriptor + * @buf: where to put the string + * @size: how big is "buf"? + * + * This converts the UTF-16LE encoded strings returned by devices, from + * usb_get_string_descriptor(), to null-terminated ISO-8859-1 encoded ones + * that are more usable in most kernel contexts. Note that all characters + * in the chosen descriptor that can't be encoded using ISO-8859-1 + * are converted to the question mark ("?") character, and this function + * chooses strings in the first language supported by the device. + * + * The ASCII (or, redundantly, "US-ASCII") character set is the seven-bit + * subset of ISO 8859-1. ISO-8859-1 is the eight-bit subset of Unicode, + * and is appropriate for use many uses of English and several other + * Western European languages. (But it doesn't include the "Euro" symbol.) + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Returns length of the string (>= 0) or usb_control_msg status (< 0). */ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) { @@ -2155,7 +2476,7 @@ if (idx >= size) break; if (tbuf[u+1]) /* high byte */ - buf[idx++] = '?'; /* non-ASCII character */ + buf[idx++] = '?'; /* non ISO-8859-1 character */ else buf[idx++] = tbuf[u]; } @@ -2173,6 +2494,11 @@ * get the ball rolling.. * * Returns 0 for success, != 0 for error. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Only hub drivers (including virtual root hub drivers for host + * controllers) should ever call this. */ int usb_new_device(struct usb_device *dev) { @@ -2388,33 +2714,28 @@ EXPORT_SYMBOL(usb_claim_bandwidth); EXPORT_SYMBOL(usb_release_bandwidth); -EXPORT_SYMBOL(usb_set_address); -EXPORT_SYMBOL(usb_get_descriptor); -EXPORT_SYMBOL(usb_get_class_descriptor); EXPORT_SYMBOL(__usb_get_extra_descriptor); -EXPORT_SYMBOL(usb_get_device_descriptor); -EXPORT_SYMBOL(usb_get_string); -EXPORT_SYMBOL(usb_string); -EXPORT_SYMBOL(usb_get_protocol); -EXPORT_SYMBOL(usb_set_protocol); -EXPORT_SYMBOL(usb_get_report); -EXPORT_SYMBOL(usb_set_report); -EXPORT_SYMBOL(usb_set_idle); -EXPORT_SYMBOL(usb_clear_halt); -EXPORT_SYMBOL(usb_set_interface); -EXPORT_SYMBOL(usb_get_configuration); -EXPORT_SYMBOL(usb_set_configuration); -EXPORT_SYMBOL(usb_get_status); EXPORT_SYMBOL(usb_get_current_frame_number); +// asynchronous request completion model EXPORT_SYMBOL(usb_alloc_urb); EXPORT_SYMBOL(usb_free_urb); EXPORT_SYMBOL(usb_submit_urb); EXPORT_SYMBOL(usb_unlink_urb); +// synchronous request completion model EXPORT_SYMBOL(usb_control_msg); EXPORT_SYMBOL(usb_bulk_msg); +// synchronous control message convenience routines +EXPORT_SYMBOL(usb_get_descriptor); +EXPORT_SYMBOL(usb_get_device_descriptor); +EXPORT_SYMBOL(usb_get_status); +EXPORT_SYMBOL(usb_get_string); +EXPORT_SYMBOL(usb_string); +EXPORT_SYMBOL(usb_clear_halt); +EXPORT_SYMBOL(usb_set_configuration); +EXPORT_SYMBOL(usb_set_interface); EXPORT_SYMBOL(usb_devfs_handle); MODULE_LICENSE("GPL"); diff -u --recursive --new-file v2.5.0/linux/drivers/usb/usbkbd.c linux/drivers/usb/usbkbd.c --- v2.5.0/linux/drivers/usb/usbkbd.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/usbkbd.c Sat Dec 8 20:28:45 2001 @@ -35,6 +35,9 @@ #include #include +#define _HID_BOOT_PROTOCOL +#include "hid.h" + /* * Version Information */ @@ -192,8 +195,8 @@ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - usb_set_protocol(dev, interface->bInterfaceNumber, 0); - usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); + hid_set_protocol(dev, interface->bInterfaceNumber, 0); + hid_set_idle(dev, interface->bInterfaceNumber, 0, 0); if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL; memset(kbd, 0, sizeof(struct usb_kbd)); @@ -216,7 +219,7 @@ usb_kbd_irq, kbd, endpoint->bInterval); kbd->dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE; - kbd->dr.request = USB_REQ_SET_REPORT; + kbd->dr.request = HID_REQ_SET_REPORT; kbd->dr.value = 0x200; kbd->dr.index = interface->bInterfaceNumber; kbd->dr.length = 1; diff -u --recursive --new-file v2.5.0/linux/drivers/usb/usbmouse.c linux/drivers/usb/usbmouse.c --- v2.5.0/linux/drivers/usb/usbmouse.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/usbmouse.c Sat Dec 8 20:28:45 2001 @@ -35,6 +35,9 @@ #include #include +#define _HID_BOOT_PROTOCOL +#include "hid.h" + /* * Version Information */ @@ -118,7 +121,7 @@ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); + hid_set_idle(dev, interface->bInterfaceNumber, 0, 0); if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL; memset(mouse, 0, sizeof(struct usb_mouse)); diff -u --recursive --new-file v2.5.0/linux/drivers/usb/usbnet.c linux/drivers/usb/usbnet.c --- v2.5.0/linux/drivers/usb/usbnet.c Wed Nov 21 09:51:08 2001 +++ linux/drivers/usb/usbnet.c Sat Dec 8 20:25:02 2001 @@ -1535,7 +1535,7 @@ struct skb_data *entry = (struct skb_data *) skb->cb; struct usbnet *dev = entry->dev; - if (urb->status == USB_ST_STALL) { + if (urb->status == -EPIPE) { if (dev->ctrl_task.sync == 0) { dev->ctrl_task.routine = tx_clear_halt; dev->ctrl_task.data = dev; @@ -1868,6 +1868,11 @@ #ifdef CONFIG_USB_AN2720 { USB_DEVICE (0x0547, 0x2720), // AnchorChips defaults + driver_info: (unsigned long) &an2720_info, +}, + +{ + USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET driver_info: (unsigned long) &an2720_info, }, #endif diff -u --recursive --new-file v2.5.0/linux/drivers/usb/uss720.c linux/drivers/usb/uss720.c --- v2.5.0/linux/drivers/usb/uss720.c Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/uss720.c Sat Dec 8 20:28:45 2001 @@ -193,7 +193,7 @@ struct parport *pp = (struct parport *)dev_id; struct parport_uss720_private *priv = pp->private_data; - if (usbstatus != USB_ST_NOERROR || len < 4 || !buffer) + if (usbstatus != 0 || len < 4 || !buffer) return 1; memcpy(priv->reg, buffer, 4); /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */ diff -u --recursive --new-file v2.5.0/linux/drivers/video/modedb.c linux/drivers/video/modedb.c --- v2.5.0/linux/drivers/video/modedb.c Fri Mar 2 18:38:39 2001 +++ linux/drivers/video/modedb.c Tue Nov 27 17:06:50 2001 @@ -14,9 +14,9 @@ #include #include #include -#include #include +#include