diff -u --recursive --new-file v2.3.0/linux/CREDITS linux/CREDITS --- v2.3.0/linux/CREDITS Tue May 11 09:57:14 1999 +++ linux/CREDITS Thu May 13 11:00:07 1999 @@ -91,6 +91,11 @@ S: Cambridge, Massachusetts 02139 S: USA +N: Michel Aubry +E: giovanni +D: Aladdin 1533/1543(C) chipset IDE +D: VIA MVP-3/TX Pro III chipset IDE + N: Jens Axboe E: axboe@image.dk D: Linux CD-ROM maintainer @@ -765,6 +770,17 @@ E: ajh@primag.co.uk D: Selection mechanism +N: Andre Hedrick +E: hedrick@astro.dyer.vanderbilt.edu +D: Uniform Multi-Platform E-IDE driver +D: Aladdin 1533/1543(C) chipset IDE +D: HighPoint HPT343/5 chipset IDE +D: PIIX chipset IDE +D: Promise Ultra/33 chipset IDE +D: Promise Ultra/66 chipset IDE +S: Nashville, TN +S: USA + N: Jochen Hein E: jochen.hein@delphi.central.de P: 1024/4A27F015 25 72 FB E3 85 9F DE 3B CB 0A DA DA 40 77 05 6C @@ -928,6 +944,10 @@ S: 160 00 Praha 6 S: Czech Republic +N: Andreas S. Krebs +E: akrebs@altavista.net +D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards + N: Niels Kristian Bech Jensen E: nkbj@image.dk W: http://www.image.dk/~nkbj @@ -938,6 +958,13 @@ S: DK-8230 Åbyhøj S: Denmark +N: Andrzej Krzysztofowicz +E: ankry@green.mif.pg.gda.pl +D: Aladdin 1533/1543(C) chipset IDE +D: PIIX chipset IDE +S: Faculty of Applied Phys. & Math. +S: Technical University of Gdansk + N: Michael K. Johnson E: johnsonm@redhat.com W: http://www.redhat.com/~johnsonm @@ -1729,6 +1756,10 @@ D: added PCI support to the serial driver S: Buckenhof, Germany +N: Michael Schmitz +E: +D: Macintosh IDE Driver + N: Martin Schulze E: joey@linux.de W: http://home.pages.de/~joey/ @@ -2015,6 +2046,9 @@ D: Frame buffer device and XF68_FBDev maintainer D: m68k IDE maintainer D: Amiga Zorro maintainer +D: Amiga Buddha and Catweasel chipset IDE +D: Atari Falcon chipset IDE +D: Amiga Gayle chipset IDE S: C. Huysmansstraat 12 S: B-3128 Baal S: Belgium diff -u --recursive --new-file v2.3.0/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.3.0/linux/Documentation/Configure.help Tue May 11 09:57:14 1999 +++ linux/Documentation/Configure.help Thu May 13 11:00:08 1999 @@ -289,9 +289,9 @@ Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support CONFIG_BLK_DEV_IDE If you say Y here, you will use the full-featured IDE driver to - control up to four IDE interfaces, each being able to serve a - "master" and a "slave" device, for a total of up to eight IDE - disk/cdrom/tape/floppy drives. People with SCSI-only systems + control up to eight IDE interfaces, each being able to serve a + "master" and a "slave" device, for a total of up to sixteen (16) + IDE disk/cdrom/tape/floppy drives. People with SCSI-only systems can say N here. Useful information about large (>540 MB) IDE disks, multiple @@ -370,6 +370,15 @@ root filesystem (the one containing the directory /) is located on the IDE disk. If unsure, say Y. +Use multi-mode by default +CONFIG_IDEDISK_MULTI_MODE + If you get this error, try to enable this option. + + hda: set_multmode: status=0x51 { DriveReady SeekComplete Error } + hda: set_multmode: error=0x04 { DriveStatusError } + + If in doubt, say N. + Include IDE/ATAPI CDROM support CONFIG_BLK_DEV_IDECD If you have a CDROM drive using the ATAPI protocol, say Y. ATAPI is @@ -396,6 +405,17 @@ say M here and read Documentation/modules.txt. The module will be called ide-cd.o. +Include CD-Changer Reporting +CONFIG_IDECD_SLOTS + If you have an IDE/ATAPI multi-slot cd-changer and you want + to report which slots have disk-present, say Y. If you say Y + and there is not a multi-slot cdrom present, this code is skipped. + + This could be the bases of multi-disk access based on multi-mounts. + This is still pie-in-the-sky. + + If unsure, say N. + Include IDE/ATAPI TAPE support CONFIG_BLK_DEV_IDETAPE If you have an IDE tape drive using the ATAPI protocol, say Y. @@ -638,14 +658,28 @@ Please read the comments at the top of drivers/block/ns87415.c. +CY82C693 chipset support (EXPERIMENTAL) +CONFIG_BLK_DEV_CY82C693 + + This driver adds detection and support for the CY82C693 chipset + used on Digital's PC-Alpha 164SX boards. + + This requires CONFIG_IDEDMA_AUTO to be enabled. + + Please read the comments at the top of drivers/block/cy82c693.c + VIA82C586 chipset support (EXPERIMENTAL) CONFIG_BLK_DEV_VIA82C586 - This adds initial timing settings for VIA (U)DMA onboard ide - controllers that are ATA3 compliant. May work with ATA4 systems, but - not tested to date. + This allows you to to configure your chipset for a better use while + running (U)DMA: it will allow you to enable efficiently the second + channel dma usage, as it is may not be set by BIOS. It allows you to + run a kernel command line at boot time in order to set fifo config. + If no command line is provided, it will try to set fifo configuration + at its best. It will allow you to get a proc/ide/via display + (while running a "cat") provided you enabled "proc" support and + set DISPLAY_APOLLO_TIMINGS in via82c586.c - If you say Y here, you also need to say Y to "Use DMA by default - when available", above. + This requires CONFIG_IDEDMA_AUTO to be enabled. If unsure, say N. @@ -653,6 +687,81 @@ CONFIG_BLK_DEV_CMD646 Say Y here if you have an IDE controller like this. +ALI M15x3 chipset support (EXPERIMENTAL) +CONFIG_BLK_DEV_ALI15X3 + This driver ensures (U)DMA support for ALI 1533, 1543 and 1543C + onboard chipsets. It also tests for Simplex mode and enables + normal dual channel support. + + This requires CONFIG_IDEDMA_AUTO to be enabled. + + Please read the comments at the top of drivers/block/alim15x3.c + + If unsure, say N. + +PROMISE PDC20246 support (EXPERIMENTAL) +CONFIG_BLK_DEV_PDC20246 + This driver adds up to 4 more eide devices sharing a single interrupt. + This add-on card is a bootable PCI UDMA controller. + Since multiple cards can be installed and there are BIOS ROM problems + that happen if the BIOS revisions of all installed cards (three-max) + do not match. Should you be unable to make new BIOS chips with a burner, + the driver attempts to dynamic tuning of the chipset at boot-time + for max-speed. Ultra33 BIOS 1.25 or new required for more than one card. + + This requires CONFIG_IDEDMA_AUTO to be enabled. + + Please read the comments at the top of drivers/block/pdc202xx.c + + If unsure, say N. + +PROMISE PDC20262 support (EXPERIMENTAL) +CONFIG_BLK_DEV_PDC20262 + This driver adds up to 4 more eide devices sharing a single interrupt. + This add-on card is a bootable PCI UDMA ATA-66 controller. + The driver attempts to dynamic tuning of the chipset at boot-time + for max-speed. Note tested limits are UDMA-2. + Ultra66 BIOS 1.11 or newer required. + + This requires CONFIG_IDEDMA_AUTO to be enabled. + + Please read the comments at the top of drivers/block/pdc202xx.c + + If unsure, say N. + +AEC6210 chipset support +CONFIG_BLK_DEV_AEC6210 + This driver adds up to 4 more eide devices sharing a single interrupt. + This add-on card is a bootable PCI UDMA controller. In order to get this + card to initialize correctly in some cases, you should include this driver. + + This prefers CONFIG_IDEDMA_AUTO to be enabled, regardless. + + Please read the comments at the top of drivers/block/aec6210.c + +Intel PIIXn chipsets support (EXPERIMENTAL) +CONFIG_BLK_DEV_PIIX + This driver adds PIO mode setting and tuning for all PIIX IDE + controllers by Intel. Since the BIOS can sometimes improperly tune + PIO 0-4 mode settings, this allows dynamic tuning of the chipset + via the standard end-user tool 'hdparm'. + + Please read the comments at the top of drivers/block/piix.c + + If unsure, say N. + +HPT343 chipset support (EXPERIMENTAL) +CONFIG_BLK_DEV_HPT343 + This driver adds up to 4 more EIDE devices sharing a single + interrupt. The HPT343 chipset in its current form is a non-bootable + PCI UDMA controller. This driver requires dynamic tuning of the + chipset during the ide-probe at boot. It is reported to support DVD + II drives, by the manufacturer. + + This requires CONFIG_IDEDMA_AUTO to be enabled. + + Please read the comments at the top of drivers/block/hpt343.c + QDI QD6580 support CONFIG_BLK_DEV_QD6580 This driver is enabled at runtime using the "ide0=qd6580" kernel @@ -675,6 +784,68 @@ of the ALI M1439/1443/1445/1487/1489 chipsets, and permits faster I/O speeds to be set as well. See the files Documentation/ide.txt and drivers/block/ali14xx.c for more info. + +Amiga builtin Gayle IDE interface support +CONFIG_BLK_DEV_GAYLE + This is the IDE driver for the builtin IDE interface on some Amiga + models. It supports both the `A1200 style' (used in A600 and A1200) + and `A4000 style' (used in A4000 and A4000T) of the Gayle IDE interface. + Say Y if you have such an Amiga model and want to use IDE devices + (hard disks, CD-ROM drives, etc.) that are connected to the builtin + IDE interface. + +Falcon IDE interface support +CONFIG_BLK_DEV_FALCON_IDE + This is the IDE driver for the builtin IDE interface on the Atari Falcon. + Say Y if you have a Falcon and want to use IDE devices (hard disks, + CD-ROM drives, etc.) that are connected to the builtin IDE interface. + +Amiga Buddha/Catweasel IDE interface support (EXPERIMENTAL) +CONFIG_BLK_DEV_BUDDHA + This is the IDE driver for the IDE interfaces on the Buddha and + Catweasel expansion boards. It supports up to two interfaces on the + Buddha and three on the Catweasel. + Say Y if you have a Buddha or Catweasel expansion board and want to + use IDE devices (hard disks, CD-ROM drives, etc.) that are connected + to one of its IDE interfaces. + +Amiga IDE Doubler support (EXPERIMENTAL) +CONFIG_BLK_DEV_IDEDOUBLER + This driver provides support for the so called `IDE doublers' (made by + various manufacturers, e.g. Eyetech) that can be connected to the + builtin IDE interface of some Amiga models. Using such an IDE doubler, + you can connect up to four instead of two IDE devices on the Amiga's + builtin IDE interface. + Note that the normal Amiga Gayle IDE driver may not work correctly if + you have an IDE doubler and don't enable this driver! + Say Y if you have an IDE doubler. The driver is enabled at kernel + runtime using the "ide=doubler" kernel boot parameter. + + Support for PowerMac IDE devices (must also enable IDE) + CONFIG_BLK_DEV_IDE_PMAC + No help for CONFIG_BLK_DEV_IDE_PMAC + + PowerMac IDE DMA support + CONFIG_BLK_DEV_IDEDMA_PMAC + No help for CONFIG_BLK_DEV_IDEDMA_PMAC + + Use DMA by default + CONFIG_PMAC_IDEDMA_AUTO + No help for CONFIG_PMAC_IDEDMA_AUTO + +Macintosh Quadra/Powerbook IDE interface support +CONFIG_BLK_DEV_MAC_IDE + This is the IDE driver for the builtin IDE interface on the some m68k + Macintosh models. It supports both the `Quadra style' (used in Quadra/ + Centris 630 and Performa 588 models) and `Powerbook style' (used in the + Powerbook 150 and 190 models) IDE interface. + Say Y if you have such an Macintosh model and want to use IDE devices + (hard disks, CD-ROM drives, etc.) that are connected to the builtin + IDE interface. + + RapIDE interface support + CONFIG_BLK_DEV_IDE_RAPIDE + No help for CONFIG_BLK_DEV_IDE_RAPIDE XT hard disk support CONFIG_BLK_DEV_XD diff -u --recursive --new-file v2.3.0/linux/Documentation/devices.tex linux/Documentation/devices.tex --- v2.3.0/linux/Documentation/devices.tex Sun Aug 16 11:35:51 1998 +++ linux/Documentation/devices.tex Thu May 13 11:00:08 1999 @@ -254,7 +254,9 @@ \major{86}{}{char }{SCSI media changer} \major{87}{}{char }{Sony Control-A1 stereo control bus} \major{88}{}{char }{COMX synchronous serial card} +\major{ }{}{block}{Sixth IDE hard disk/CD-ROM interface} \major{89}{}{char }{I$^2$C bus interface} +\major{ }{}{block}{Seventh IDE hard disk/CD-ROM interface} \major{90}{}{char }{Memory Technology Device (RAM, ROM, Flash)} \major{91}{}{char }{CAN-Bus controller} \major{92}{}{char }{Reserved for ith Kommunikationstechnik MIC ISDN card} @@ -1746,11 +1748,31 @@ \end{devicelist} \begin{devicelist} +\major{ }{}{block}{Sixth IDE hard disk/CD-ROM interface} + \minor{0}{/dev/hdm}{Master: whole disk (or CD-ROM)} + \minor{64}{/dev/hdn}{Slave: whole disk (or CD-ROM)} +\end{devicelist} + +\noindent +Partitions are handled the same way as for the first interface (see +major number 3). + +\begin{devicelist} \major{89}{}{char }{I$^2$C bus interface} \minor{0}{/dev/i2c0}{First I$^2$C adapter} \minor{1}{/dev/i2c1}{Second I$^2$C adapter} \minordots \end{devicelist} + +\begin{devicelist} +\major{ }{}{block}{Seventh IDE hard disk/CD-ROM interface} + \minor{0}{/dev/hdo}{Master: whole disk (or CD-ROM)} + \minor{64}{/dev/hdp}{Slave: whole disk (or CD-ROM)} +\end{devicelist} + +\noindent +Partitions are handled the same way as for the first interface (see +major number 3). \begin{devicelist} \major{90}{}{char }{Memory Technology Device (RAM, ROM, Flash)} diff -u --recursive --new-file v2.3.0/linux/Documentation/devices.txt linux/Documentation/devices.txt --- v2.3.0/linux/Documentation/devices.txt Wed Dec 16 12:52:00 1998 +++ linux/Documentation/devices.txt Thu May 13 11:00:08 1999 @@ -1215,10 +1215,24 @@ 1 = /dev/comx1 COMX channel 1 ... + block Sixth IDE hard disk/CD-ROM interface + 0 = /dev/hdm Master: whole disk (or CD-ROM) + 64 = /dev/hdn Slave: whole disk (or CD-ROM) + + Partitions are handled the same way as for the first + interface (see major number 3). + 89 char I2C bus interface 0 = /dev/i2c0 First I2C adapter 1 = /dev/i2c1 Second I2C adapter ... + + block Seventh IDE hard disk/CD-ROM interface + 0 = /dev/hdo Master: whole disk (or CD-ROM) + 64 = /dev/hdp Slave: whole disk (or CD-ROM) + + Partitions are handled the same way as for the first + interface (see major number 3). 90 char Memory Technology Device (RAM, ROM, Flash) 0 = /dev/mtd0 First MTD (rw) diff -u --recursive --new-file v2.3.0/linux/Makefile linux/Makefile --- v2.3.0/linux/Makefile Tue May 11 13:03:06 1999 +++ linux/Makefile Tue May 11 14:37:31 1999 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 3 -SUBLEVEL = 0 +SUBLEVEL = 1 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff -u --recursive --new-file v2.3.0/linux/README linux/README --- v2.3.0/linux/README Thu Jan 7 08:41:55 1999 +++ linux/README Thu May 13 10:56:25 1999 @@ -1,9 +1,23 @@ - Linux kernel release 2.2.xx + Linux kernel release 2.3.xx -These are the release notes for Linux version 2.2. Read them carefully, +These are the release notes for Linux version 2.3. 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. +Linux version 2.3 is a DEVELOPMENT kernel, and not intended for general +public use. Different releases may have various and sometimes severe +bugs. It is *strongly* recommended that you back up the previous kernel +before installing any new 2.3.xx release. + +If you need to use a proven and stable Linux kernel, please use 1.2.13, +2.0.36 or 2.2.xx. All features which will be in the 2.3.xx releases will +be contained in 2.4.xx when the code base has stabilized again. + +If you decide to use 2.3, it is recommended that you join the kernel mailing +list. To do this, e-mail majordomo@vger.rutgers.edu, and put in the body +of the message "subscribe linux-kernel" or "subscribe linux-kernel-digest" +for a daily digest of the mailing list (it is a high-traffic list.) + However, please make sure you don't ask questions which are already answered in various files in the Documentation directory. See DOCUMENTATION below. @@ -48,12 +62,12 @@ - If you install the full sources, do a cd /usr/src - gzip -cd linux-2.2.XX.tar.gz | tar xfv - + gzip -cd linux-2.3.XX.tar.gz | tar xfv - to get it all put in place. Replace "XX" with the version number of the latest kernel. - - You can also upgrade between 2.2.xx releases by patching. Patches are + - You can also upgrade between 2.3.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 and do @@ -91,7 +105,7 @@ SOFTWARE REQUIREMENTS - Compiling and running the 2.2.x kernels requires up-to-date + Compiling and running the 2.3.x 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 diff -u --recursive --new-file v2.3.0/linux/arch/i386/config.in linux/arch/i386/config.in --- v2.3.0/linux/arch/i386/config.in Mon Apr 26 13:49:17 1999 +++ linux/arch/i386/config.in Thu May 13 14:11:52 1999 @@ -168,7 +168,7 @@ source drivers/char/Config.in -# source drivers/usb/Config.in +source drivers/usb/Config.in source fs/Config.in diff -u --recursive --new-file v2.3.0/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.3.0/linux/arch/i386/defconfig Mon Apr 12 13:12:57 1999 +++ linux/arch/i386/defconfig Thu May 13 14:14:40 1999 @@ -73,7 +73,9 @@ # # CONFIG_BLK_DEV_HD_IDE is not set CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set CONFIG_BLK_DEV_IDECD=y +# CONFIG_IDECD_SLOTS is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set @@ -83,6 +85,7 @@ CONFIG_BLK_DEV_IDEPCI=y CONFIG_BLK_DEV_IDEDMA=y # CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_AEC6210 is not set CONFIG_IDEDMA_AUTO=y # CONFIG_IDE_CHIPSETS is not set @@ -96,6 +99,7 @@ # CONFIG_BLK_DEV_XD is not set CONFIG_PARIDE_PARPORT=y # CONFIG_PARIDE is not set +CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_HD is not set # @@ -290,6 +294,17 @@ # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set + +# +# USB drivers - not for the faint of heart +# +CONFIG_USB=y +CONFIG_USB_UHCI=y +# CONFIG_USB_OHCI is not set +# CONFIG_USB_OHCI_HCD is not set +CONFIG_USB_MOUSE=y +CONFIG_USB_KBD=y +# CONFIG_USB_AUDIO is not set # # Filesystems diff -u --recursive --new-file v2.3.0/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c --- v2.3.0/linux/arch/i386/kernel/apm.c Thu Jan 14 22:57:25 1999 +++ linux/arch/i386/kernel/apm.c Wed May 12 08:31:44 1999 @@ -1017,7 +1017,7 @@ struct apm_bios_struct * as; int i; apm_event_t event; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); as = fp->private_data; if (check_apm_bios_struct(as, "read")) diff -u --recursive --new-file v2.3.0/linux/arch/i386/kernel/init_task.c linux/arch/i386/kernel/init_task.c --- v2.3.0/linux/arch/i386/kernel/init_task.c Sun Sep 13 12:16:22 1998 +++ linux/arch/i386/kernel/init_task.c Tue May 11 14:37:40 1999 @@ -10,7 +10,7 @@ static struct file * init_fd_array[NR_OPEN] = { NULL, }; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS; -struct mm_struct init_mm = INIT_MM; +struct mm_struct init_mm = INIT_MM(init_mm); /* * Initial task structure. @@ -20,5 +20,6 @@ * "init_task" linker map entry.. */ union task_union init_task_union - __attribute__((__section__(".data.init_task"))) = { INIT_TASK }; + __attribute__((__section__(".data.init_task"))) = + { INIT_TASK(init_task_union.task) }; diff -u --recursive --new-file v2.3.0/linux/arch/m68k/kernel/ints.c linux/arch/m68k/kernel/ints.c --- v2.3.0/linux/arch/m68k/kernel/ints.c Tue May 11 09:57:14 1999 +++ linux/arch/m68k/kernel/ints.c Wed May 12 08:50:00 1999 @@ -25,6 +25,7 @@ * which must be served /Roman Zippel */ +#include #include #include #include diff -u --recursive --new-file v2.3.0/linux/arch/m68k/mm/kmap.c linux/arch/m68k/mm/kmap.c --- v2.3.0/linux/arch/m68k/mm/kmap.c Tue May 11 09:57:14 1999 +++ linux/arch/m68k/mm/kmap.c Wed May 12 08:50:00 1999 @@ -7,6 +7,7 @@ * used by other architectures /Roman Zippel */ +#include #include #include #include diff -u --recursive --new-file v2.3.0/linux/arch/m68k/mvme147/config.c linux/arch/m68k/mvme147/config.c --- v2.3.0/linux/arch/m68k/mvme147/config.c Tue May 11 09:57:14 1999 +++ linux/arch/m68k/mvme147/config.c Wed May 12 08:50:00 1999 @@ -13,7 +13,6 @@ * for more details. */ -#include #include #include #include diff -u --recursive --new-file v2.3.0/linux/arch/m68k/q40/config.c linux/arch/m68k/q40/config.c --- v2.3.0/linux/arch/m68k/q40/config.c Tue May 11 09:57:14 1999 +++ linux/arch/m68k/q40/config.c Wed May 12 08:50:00 1999 @@ -13,6 +13,7 @@ */ #include +#include #include #include #include diff -u --recursive --new-file v2.3.0/linux/arch/m68k/sun3x/time.c linux/arch/m68k/sun3x/time.c --- v2.3.0/linux/arch/m68k/sun3x/time.c Tue May 11 09:57:14 1999 +++ linux/arch/m68k/sun3x/time.c Wed May 12 08:50:00 1999 @@ -4,7 +4,6 @@ * Sun3x-specific time handling */ -#include #include #include #include diff -u --recursive --new-file v2.3.0/linux/arch/mips/lib/ide-no.c linux/arch/mips/lib/ide-no.c --- v2.3.0/linux/arch/mips/lib/ide-no.c Tue Oct 20 13:52:54 1998 +++ linux/arch/mips/lib/ide-no.c Thu May 13 11:00:08 1999 @@ -11,6 +11,7 @@ */ #include #include +#include #include #include @@ -24,8 +25,10 @@ return 0; } -static void no_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, - int *irq) +static void no_ide_init_hwif_ports ( hw_regs_t *hw, + ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, + int *irq) { } diff -u --recursive --new-file v2.3.0/linux/arch/mips/lib/ide-std.c linux/arch/mips/lib/ide-std.c --- v2.3.0/linux/arch/mips/lib/ide-std.c Tue Aug 4 16:06:57 1998 +++ linux/arch/mips/lib/ide-std.c Thu May 13 11:00:08 1999 @@ -11,6 +11,7 @@ */ #include #include +#include #include static int std_ide_default_irq(ide_ioreg_t base) @@ -41,15 +42,23 @@ } } -static void std_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, - int *irq) +static void std_ide_init_hwif_ports ( hw_regs_t *hw, + ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, + int *irq) { - ide_ioreg_t port = base; - int i = 8; + ide_ioreg_t reg = data_port; + int i; - while (i--) - *p++ = port++; - *p++ = base + 0x206; + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } if (irq != NULL) *irq = 0; } diff -u --recursive --new-file v2.3.0/linux/arch/ppc/kernel/apus_setup.c linux/arch/ppc/kernel/apus_setup.c --- v2.3.0/linux/arch/ppc/kernel/apus_setup.c Thu Apr 29 12:39:01 1999 +++ linux/arch/ppc/kernel/apus_setup.c Thu May 13 11:00:08 1999 @@ -561,9 +561,9 @@ } __initfunc(void -apus_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq)) +apus_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)) { - m68k_ide_init_hwif_ports(p, base, irq); + m68k_ide_init_hwif_ports(hw, data_port, ctrl_port, irq); } #endif diff -u --recursive --new-file v2.3.0/linux/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c --- v2.3.0/linux/arch/ppc/kernel/chrp_setup.c Tue May 11 08:24:32 1999 +++ linux/arch/ppc/kernel/chrp_setup.c Thu May 13 11:00:08 1999 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -561,16 +562,23 @@ ppc_generic_ide_fix_driveid(id); } -void chrp_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) +void +chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) { - ide_ioreg_t port = base; - int i = 8; + ide_ioreg_t reg = data_port; + int i; - while (i--) - *p++ = port++; - *p++ = port; - if (irq != NULL) - *irq = chrp_ide_irq; + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = 0; + } + if (irq != NULL) + hw->irq = chrp_ide_irq; } EXPORT_SYMBOL(chrp_ide_irq); diff -u --recursive --new-file v2.3.0/linux/arch/ppc/kernel/mbx_setup.c linux/arch/ppc/kernel/mbx_setup.c --- v2.3.0/linux/arch/ppc/kernel/mbx_setup.c Thu Apr 29 12:39:01 1999 +++ linux/arch/ppc/kernel/mbx_setup.c Thu May 13 11:00:08 1999 @@ -380,23 +380,35 @@ ppc_generic_ide_fix_driveid(id); } -void __init mbx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq) +void +mbx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) { - ide_ioreg_t port = base; - int i = 8; + ide_ioreg_t reg = data_port; + int i; + + *irq = 0; + + if (data_port != 0) /* Only map the first ATA flash drive */ + return; - while (i--) - *p++ = port++; - *p++ = base + 0x206; - if (irq != NULL) - *irq = 0; #ifdef ATA_FLASH - base = (unsigned long) ioremap(PCMCIA_MEM_ADDR, 0x200); - for (i = 0; i < 8; ++i) - *p++ = base++; - *p = ++base; /* Does not matter */ + + reg = (ide_ioreg_t) ioremap(PCMCIA_MEM_ADDR, 0x200); + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + + /* Does not matter */ + + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = reg; + } if (irq) - *irq = 13; + hw->irq = 13; #endif } #endif diff -u --recursive --new-file v2.3.0/linux/arch/ppc/kernel/pmac_pic.c linux/arch/ppc/kernel/pmac_pic.c --- v2.3.0/linux/arch/ppc/kernel/pmac_pic.c Tue May 11 08:24:32 1999 +++ linux/arch/ppc/kernel/pmac_pic.c Wed May 12 08:50:00 1999 @@ -1,4 +1,4 @@ - +#include #include #include #include diff -u --recursive --new-file v2.3.0/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c --- v2.3.0/linux/arch/ppc/kernel/pmac_setup.c Tue May 11 08:24:32 1999 +++ linux/arch/ppc/kernel/pmac_setup.c Thu May 13 11:00:08 1999 @@ -365,7 +365,7 @@ #ifdef CONFIG_BLK_DEV_IDE_PMAC extern int pmac_ide_count; extern struct device_node *pmac_ide_node[]; -static int ide_majors[] = { 3, 22, 33, 34, 56, 57 }; +static int ide_majors[] = { 3, 22, 33, 34, 56, 57, 88, 89 }; __initfunc(kdev_t find_ide_boot(void)) { @@ -544,7 +544,16 @@ } /* This is declared in drivers/block/ide-pmac.c */ -void pmac_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq); +void pmac_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq); + +/* + * This registers the standard ports for this architecture with the IDE + * driver. + */ +void +ide_init_default_hwifs(void) +{ +} #endif __initfunc(void diff -u --recursive --new-file v2.3.0/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c --- v2.3.0/linux/arch/ppc/kernel/ppc_ksyms.c Thu Apr 29 12:39:01 1999 +++ linux/arch/ppc/kernel/ppc_ksyms.c Thu May 13 11:00:08 1999 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff -u --recursive --new-file v2.3.0/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c --- v2.3.0/linux/arch/ppc/kernel/prep_setup.c Tue May 11 08:24:32 1999 +++ linux/arch/ppc/kernel/prep_setup.c Thu May 13 11:00:08 1999 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -691,14 +692,20 @@ } __initfunc(void -prep_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq)) +prep_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)) { - ide_ioreg_t port = base; - int i = 8; + ide_ioreg_t reg = data_port; + int i; - while (i--) - *p++ = port++; - *p++ = base + 0x206; + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } if (irq != NULL) *irq = 0; } diff -u --recursive --new-file v2.3.0/linux/arch/ppc/kernel/residual.c linux/arch/ppc/kernel/residual.c --- v2.3.0/linux/arch/ppc/kernel/residual.c Sun Nov 15 10:51:44 1998 +++ linux/arch/ppc/kernel/residual.c Thu May 13 11:00:08 1999 @@ -46,6 +46,7 @@ #include #include #include +#include #include diff -u --recursive --new-file v2.3.0/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c --- v2.3.0/linux/arch/ppc/kernel/setup.c Thu Apr 29 12:39:01 1999 +++ linux/arch/ppc/kernel/setup.c Thu May 13 11:00:08 1999 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -160,10 +161,10 @@ } #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) -void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) +void ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) { if (ppc_ide_md.ide_init_hwif != NULL) { - ppc_ide_md.ide_init_hwif(p, base, irq); + ppc_ide_md.ide_init_hwif(hw, data_port, ctrl_port, irq); } } #endif diff -u --recursive --new-file v2.3.0/linux/arch/sparc/ap1000/util.c linux/arch/sparc/ap1000/util.c --- v2.3.0/linux/arch/sparc/ap1000/util.c Wed Dec 23 09:44:40 1998 +++ linux/arch/sparc/ap1000/util.c Wed May 12 08:41:12 1999 @@ -355,7 +355,7 @@ } -static struct wait_queue *timer_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(timer_wait); static void wait_callback(unsigned long _ignored) { diff -u --recursive --new-file v2.3.0/linux/arch/sparc/kernel/init_task.c linux/arch/sparc/kernel/init_task.c --- v2.3.0/linux/arch/sparc/kernel/init_task.c Tue Oct 27 09:52:20 1998 +++ linux/arch/sparc/kernel/init_task.c Wed May 12 08:41:12 1999 @@ -9,11 +9,13 @@ static struct file * init_fd_array[NR_OPEN] = { NULL, }; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS; -struct mm_struct init_mm = INIT_MM; +struct mm_struct init_mm = INIT_MM(init_mm); /* .text section in head.S is aligned at 8k boundry and this gets linked * right after that so that the init_task_union is aligned properly as well. * If this is not aligned on a 8k boundry, then you should change code * in etrap.S which assumes it. */ -union task_union init_task_union __attribute__((__section__(".text"))) = { INIT_TASK }; +union task_union init_task_union + __attribute__((__section__(".text"))) = + { INIT_TASK(init_task_union.task) }; diff -u --recursive --new-file v2.3.0/linux/arch/sparc/mm/asyncd.c linux/arch/sparc/mm/asyncd.c --- v2.3.0/linux/arch/sparc/mm/asyncd.c Sun Oct 4 10:22:42 1998 +++ linux/arch/sparc/mm/asyncd.c Wed May 12 08:41:12 1999 @@ -1,4 +1,4 @@ -/* $Id: asyncd.c,v 1.12 1998/09/13 04:30:30 davem Exp $ +/* $Id: asyncd.c,v 1.13 1999/05/12 11:11:34 davem Exp $ * The asyncd kernel daemon. This handles paging on behalf of * processes that receive page faults due to remote (async) memory * accesses. @@ -39,7 +39,7 @@ /* * The wait queue for waking up the async daemon: */ -static struct wait_queue * asyncd_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(asyncd_wait); struct async_job { volatile struct async_job *next; diff -u --recursive --new-file v2.3.0/linux/arch/sparc64/kernel/init_task.c linux/arch/sparc64/kernel/init_task.c --- v2.3.0/linux/arch/sparc64/kernel/init_task.c Tue Apr 14 17:44:20 1998 +++ linux/arch/sparc64/kernel/init_task.c Wed May 12 08:41:12 1999 @@ -9,11 +9,13 @@ static struct file * init_fd_array[NR_OPEN] = { NULL, }; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS; -struct mm_struct init_mm = INIT_MM; +struct mm_struct init_mm = INIT_MM(init_mm); /* .text section in head.S is aligned at 2 page boundry and this gets linked * right after that so that the init_task_union is aligned properly as well. * We really don't need this special alignment like the Intel does, but * I do it anyways for completeness. */ -union task_union init_task_union __attribute__((__section__(".text"))) = { INIT_TASK }; +union task_union init_task_union + __attribute__((__section__(".text"))) = + { INIT_TASK(init_task_union.task) }; diff -u --recursive --new-file v2.3.0/linux/arch/sparc64/mm/asyncd.c linux/arch/sparc64/mm/asyncd.c --- v2.3.0/linux/arch/sparc64/mm/asyncd.c Sun Oct 4 10:22:43 1998 +++ linux/arch/sparc64/mm/asyncd.c Wed May 12 08:41:12 1999 @@ -1,4 +1,4 @@ -/* $Id: asyncd.c,v 1.5 1998/09/13 04:30:33 davem Exp $ +/* $Id: asyncd.c,v 1.6 1999/05/12 11:11:48 davem Exp $ * The asyncd kernel daemon. This handles paging on behalf of * processes that receive page faults due to remote (async) memory * accesses. @@ -39,7 +39,7 @@ /* * The wait queue for waking up the async daemon: */ -static struct wait_queue * asyncd_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(asyncd_wait); struct async_job { volatile struct async_job *next; diff -u --recursive --new-file v2.3.0/linux/arch/sparc64/solaris/fs.c linux/arch/sparc64/solaris/fs.c --- v2.3.0/linux/arch/sparc64/solaris/fs.c Wed Mar 10 16:53:37 1999 +++ linux/arch/sparc64/solaris/fs.c Thu May 13 10:53:58 1999 @@ -410,7 +410,11 @@ mm_segment_t old_fs = get_fs(); int error; struct sol_statvfs *ss = (struct sol_statvfs *)A(buf); - + + if (!inode->i_sb) + return -ENODEV; + if (!inode->i_sb->s_op->statfs) + return -ENOSYS; set_fs (KERNEL_DS); error = inode->i_sb->s_op->statfs(inode->i_sb, &s, sizeof(struct statfs)); set_fs (old_fs); @@ -448,6 +452,10 @@ int error; struct sol_statvfs64 *ss = (struct sol_statvfs64 *)A(buf); + if (!inode->i_sb) + return -ENODEV; + if (!inode->i_sb->s_op->statfs) + return -ENOSYS; set_fs (KERNEL_DS); error = inode->i_sb->s_op->statfs(inode->i_sb, &s, sizeof(struct statfs)); set_fs (old_fs); @@ -489,9 +497,7 @@ if (!IS_ERR(dentry)) { struct inode * inode = dentry->d_inode; - error = -ENOSYS; - if (inode->i_sb->s_op->statfs) - error = report_statvfs(inode, buf); + error = report_statvfs(inode, buf); dput(dentry); } unlock_kernel(); @@ -515,10 +521,6 @@ error = -ENOENT; else if (!(inode = dentry->d_inode)) error = -ENOENT; - else if (!inode->i_sb) - error = -ENODEV; - else if (!inode->i_sb->s_op->statfs) - error = -ENOSYS; else error = report_statvfs(inode, buf); fput(file); @@ -538,9 +540,7 @@ if (!IS_ERR(dentry)) { struct inode * inode = dentry->d_inode; - error = -ENOSYS; - if (inode->i_sb->s_op->statfs) - error = report_statvfs64(inode, buf); + error = report_statvfs64(inode, buf); dput(dentry); } unlock_kernel(); @@ -564,10 +564,6 @@ error = -ENOENT; else if (!(inode = dentry->d_inode)) error = -ENOENT; - else if (!inode->i_sb) - error = -ENODEV; - else if (!inode->i_sb->s_op->statfs) - error = -ENOSYS; else error = report_statvfs64(inode, buf); fput(file); diff -u --recursive --new-file v2.3.0/linux/arch/sparc64/solaris/timod.c linux/arch/sparc64/solaris/timod.c --- v2.3.0/linux/arch/sparc64/solaris/timod.c Tue Apr 14 17:44:21 1998 +++ linux/arch/sparc64/solaris/timod.c Wed May 12 08:41:12 1999 @@ -1,4 +1,4 @@ -/* $Id: timod.c,v 1.1 1998/03/26 08:46:18 jj Exp $ +/* $Id: timod.c,v 1.2 1999/05/12 11:11:55 davem Exp $ * timod.c: timod emulation. * * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz) @@ -76,7 +76,7 @@ #define BUF_SIZE PAGE_SIZE #define PUT_MAGIC(a,m) -#define CHECK_MAGIC(a,m) +#define SCHECK_MAGIC(a,m) #define BUF_OFFSET 0 #define MKCTL_TRAILER 0 @@ -86,7 +86,7 @@ #define BUFPAGE_MAGIC 0xBADC0DEDDEADBABEL #define MKCTL_MAGIC 0xDEADBABEBADC0DEDL #define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0) -#define CHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\ +#define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\ __FILE__,__LINE__,__FUNCTION__,(m),(a));}while(0) #define BUF_OFFSET sizeof(u64) #define MKCTL_TRAILER sizeof(u64) @@ -117,8 +117,8 @@ { SOLD("putting page"); p = p - BUF_OFFSET; - CHECK_MAGIC(p,BUFPAGE_MAGIC); - CHECK_MAGIC(p+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC); + SCHECK_MAGIC(p,BUFPAGE_MAGIC); + SCHECK_MAGIC(p+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC); spin_lock(&timod_pagelock); if (page) { spin_unlock(&timod_pagelock); @@ -721,7 +721,7 @@ #define min(a,b) ((a)<(b)?(a):(b)) #endif int l = min(ctl_maxlen, it->length); - CHECK_MAGIC((char*)((u64)(((char *)&it->type)+sock->offset+it->length+7)&~7),MKCTL_MAGIC); + SCHECK_MAGIC((char*)((u64)(((char *)&it->type)+sock->offset+it->length+7)&~7),MKCTL_MAGIC); SOLD("purting ctl data"); if(copy_to_user(ctl_buf, (char*)&it->type + sock->offset, l)) diff -u --recursive --new-file v2.3.0/linux/drivers/block/Config.in linux/drivers/block/Config.in --- v2.3.0/linux/drivers/block/Config.in Thu Apr 29 12:53:48 1999 +++ linux/drivers/block/Config.in Thu May 13 11:00:08 1999 @@ -19,7 +19,13 @@ else bool ' Use old disk-only driver on primary interface' CONFIG_BLK_DEV_HD_IDE dep_tristate ' Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE + if [ "$CONFIG_BLK_DEV_IDEDISK" != "n" ]; then + bool ' Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE + fi dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE + if [ "$CONFIG_BLK_DEV_IDECD" = "y" ]; then + bool ' Include CD-Changer Reporting' CONFIG_IDECD_SLOTS + fi dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE @@ -34,16 +40,29 @@ if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA bool ' Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD + bool ' AEC6210 chipset support' CONFIG_BLK_DEV_AEC6210 if [ "$CONFIG_BLK_DEV_IDEDMA" = "y" ]; then bool ' Use DMA by default when available' CONFIG_IDEDMA_AUTO fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 + bool ' Intel PIIXn chipsets support (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX if [ "$CONFIG_BLK_DEV_IDEDMA" = "y" ]; then bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 bool ' NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415 bool ' VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586 bool ' CMD646 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CMD646 + bool ' ALI M15x3 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_ALI15X3 + bool ' CY82C693 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CY82C693 + bool ' PDC20246 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC20246 + bool ' PDC20262 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC20262 + if [ "$CONFIG_BLK_DEV_PDC20246" = "y" -o \ + "$CONFIG_BLK_DEV_PDC20262" = "y" ]; then + define_bool CONFIG_BLK_DEV_PDC202XX y + else + define_bool CONFIG_BLK_DEV_PDC202XX n + fi + bool ' HPT343 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_HPT343 fi fi fi @@ -72,10 +91,25 @@ bool ' UMC-8672 support' CONFIG_BLK_DEV_UMC8672 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" ]; then - bool ' PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030 - fi + bool ' PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030 + fi fi fi + if [ "$CONFIG_AMIGA" = "y" ]; then + bool ' Amiga Gayle IDE interface support' CONFIG_BLK_DEV_GAYLE + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' Amiga IDE Doubler support' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE + fi + fi + if [ "$CONFIG_ZORRO" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' Buddha/Catweasel IDE interface support' CONFIG_BLK_DEV_BUDDHA + fi + if [ "$CONFIG_ATARI" = "y" ]; then + bool ' Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE + fi + if [ "$CONFIG_MAC" = "y" ]; then + bool ' Macintosh Quadra/Powerbook IDE interface support' CONFIG_BLK_DEV_MAC_IDE + fi fi fi if [ "$CONFIG_MCA" = "y" ]; then @@ -127,6 +161,19 @@ dep_tristate 'Parallel port IDE device support' CONFIG_PARIDE $CONFIG_PARIDE_PARPORT if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then source drivers/block/paride/Config.in +fi + + +if [ "$CONFIG_BLK_DEV_CMD640" = "y" -o \ + "$CONFIG_IDE_CHIPSETS" = "y" -o \ + "$CONFIG_BLK_DEV_OPTI621" = "y" -o \ + "$CONFIG_BLK_DEV_IDE_PMAC" = "y" -o \ + "$CONFIG_BLK_DEV_CY82C693" = "y" -o \ + "$CONFIG_BLK_DEV_HPT343" = "y" -o \ + "$CONFIG_BLK_DEV_PIIX" = "y" ]; then + define_bool CONFIG_BLK_DEV_IDE_MODES y +else + define_bool CONFIG_BLK_DEV_IDE_MODES n fi if [ "$CONFIG_BLK_DEV_HD_IDE" = "y" -o "$CONFIG_BLK_DEV_HD_ONLY" = "y" ]; then diff -u --recursive --new-file v2.3.0/linux/drivers/block/MAKEDEV-IDE45 linux/drivers/block/MAKEDEV-IDE45 --- v2.3.0/linux/drivers/block/MAKEDEV-IDE45 Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/MAKEDEV-IDE45 Thu May 13 11:00:08 1999 @@ -0,0 +1,99 @@ +#!/bin/sh +# +# Andre Hedrick +# +# The song goes, "I did it the hard way..........." +# + +if [ ! -f /dev/hdi ]; then \ + echo "Making IDE4 Primary Devices hdi's"; \ + mknod /dev/hdi b 56 0; \ + mknod /dev/hdi1 b 56 1; \ + mknod /dev/hdi2 b 56 2; \ + mknod /dev/hdi3 b 56 3; \ + mknod /dev/hdi4 b 56 4; \ + mknod /dev/hdi5 b 56 5; \ + mknod /dev/hdi6 b 56 6; \ + mknod /dev/hdi7 b 56 7; \ + mknod /dev/hdi8 b 56 8; \ + mknod /dev/hdi9 b 56 9; \ + mknod /dev/hdi10 b 56 10; \ + mknod /dev/hdi11 b 56 11; \ + mknod /dev/hdi12 b 56 12; \ + mknod /dev/hdi13 b 56 13; \ + mknod /dev/hdi14 b 56 14; \ + mknod /dev/hdi15 b 56 15; \ + mknod /dev/hdi16 b 56 16; \ + chown root.disk /dev/hdi*; \ + chmod 660 /dev/hdi*; \ +fi + +if [ ! -f /dev/hdj ]; then \ + echo "Making IDE4 Secondary Devices hdj's"; \ + mknod /dev/hdj b 56 64; \ + mknod /dev/hdj1 b 56 65; \ + mknod /dev/hdj2 b 56 66; \ + mknod /dev/hdj3 b 56 67; \ + mknod /dev/hdj4 b 56 68; \ + mknod /dev/hdj5 b 56 69; \ + mknod /dev/hdj6 b 56 70; \ + mknod /dev/hdj7 b 56 71; \ + mknod /dev/hdj8 b 56 72; \ + mknod /dev/hdj9 b 56 73; \ + mknod /dev/hdj10 b 56 74; \ + mknod /dev/hdj11 b 56 75; \ + mknod /dev/hdj12 b 56 76; \ + mknod /dev/hdj13 b 56 77; \ + mknod /dev/hdj14 b 56 78; \ + mknod /dev/hdj15 b 56 79; \ + mknod /dev/hdj16 b 56 80; \ + chown root.disk /dev/hdj*; \ + chmod 660 /dev/hdj*; \ +fi + +if [ ! -f /dev/hdk ]; then \ + echo "Making IDE5 Primary Devices hdk's"; \ + mknod /dev/hdk b 57 0; \ + mknod /dev/hdk1 b 57 1; \ + mknod /dev/hdk2 b 57 2; \ + mknod /dev/hdk3 b 57 3; \ + mknod /dev/hdk4 b 57 4; \ + mknod /dev/hdk5 b 57 5; \ + mknod /dev/hdk6 b 57 6; \ + mknod /dev/hdk7 b 57 7; \ + mknod /dev/hdk8 b 57 8; \ + mknod /dev/hdk9 b 57 9; \ + mknod /dev/hdk10 b 57 10; \ + mknod /dev/hdk11 b 57 11; \ + mknod /dev/hdk12 b 57 12; \ + mknod /dev/hdk13 b 57 13; \ + mknod /dev/hdk14 b 57 14; \ + mknod /dev/hdk15 b 57 15; \ + mknod /dev/hdk16 b 57 16; \ + chown root.disk /dev/hdk*; \ + chmod 660 /dev/hdk*; \ +fi + +if [ ! -f /dev/hdl ]; then \ + echo "Making IDE5 Secondary Devices hdl's"; \ + mknod /dev/hdl b 57 64; \ + mknod /dev/hdl1 b 57 65; \ + mknod /dev/hdl2 b 57 66; \ + mknod /dev/hdl3 b 57 67; \ + mknod /dev/hdl4 b 57 68; \ + mknod /dev/hdl5 b 57 69; \ + mknod /dev/hdl6 b 57 70; \ + mknod /dev/hdl7 b 57 71; \ + mknod /dev/hdl8 b 57 72; \ + mknod /dev/hdl9 b 57 73; \ + mknod /dev/hdl10 b 57 74; \ + mknod /dev/hdl11 b 57 75; \ + mknod /dev/hdl12 b 57 76; \ + mknod /dev/hdl13 b 57 77; \ + mknod /dev/hdl14 b 57 78; \ + mknod /dev/hdl15 b 57 79; \ + mknod /dev/hdl16 b 57 80; \ + chown root.disk /dev/hdl*; \ + chmod 660 /dev/hdl*; \ +fi + diff -u --recursive --new-file v2.3.0/linux/drivers/block/MAKEDEV-IDE67 linux/drivers/block/MAKEDEV-IDE67 --- v2.3.0/linux/drivers/block/MAKEDEV-IDE67 Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/MAKEDEV-IDE67 Thu May 13 11:00:08 1999 @@ -0,0 +1,99 @@ +#!/bin/sh +# +# Andre Hedrick +# +# The song goes, "I did it the hard way..........." +# + +if [ ! -f /dev/hdm ]; then \ + echo "Making IDE6 Primary Devices hdm's"; \ + mknod /dev/hdm b 88 0; \ + mknod /dev/hdm1 b 88 1; \ + mknod /dev/hdm2 b 88 2; \ + mknod /dev/hdm3 b 88 3; \ + mknod /dev/hdm4 b 88 4; \ + mknod /dev/hdm5 b 88 5; \ + mknod /dev/hdm6 b 88 6; \ + mknod /dev/hdm7 b 88 7; \ + mknod /dev/hdm8 b 88 8; \ + mknod /dev/hdm9 b 88 9; \ + mknod /dev/hdm10 b 88 10; \ + mknod /dev/hdm11 b 88 11; \ + mknod /dev/hdm12 b 88 12; \ + mknod /dev/hdm13 b 88 13; \ + mknod /dev/hdm14 b 88 14; \ + mknod /dev/hdm15 b 88 15; \ + mknod /dev/hdm16 b 88 16; \ + chown root.disk /dev/hdm*; \ + chmod 660 /dev/hdm*; \ +fi + +if [ ! -f /dev/hdn ]; then \ + echo "Making IDE6 Secondary Devices hdn's"; \ + mknod /dev/hdn b 88 64; \ + mknod /dev/hdn1 b 88 65; \ + mknod /dev/hdn2 b 88 66; \ + mknod /dev/hdn3 b 88 67; \ + mknod /dev/hdn4 b 88 68; \ + mknod /dev/hdn5 b 88 69; \ + mknod /dev/hdn6 b 88 70; \ + mknod /dev/hdn7 b 88 71; \ + mknod /dev/hdn8 b 88 72; \ + mknod /dev/hdn9 b 88 73; \ + mknod /dev/hdn10 b 88 74; \ + mknod /dev/hdn11 b 88 75; \ + mknod /dev/hdn12 b 88 76; \ + mknod /dev/hdn13 b 88 77; \ + mknod /dev/hdn14 b 88 78; \ + mknod /dev/hdn15 b 88 79; \ + mknod /dev/hdn16 b 88 80; \ + chown root.disk /dev/hdn*; \ + chmod 660 /dev/hdn*; \ +fi + +if [ ! -f /dev/hdo ]; then \ + echo "Making IDE7 Primary Devices hdo's"; \ + mknod /dev/hdo b 89 0; \ + mknod /dev/hdo1 b 89 1; \ + mknod /dev/hdo2 b 89 2; \ + mknod /dev/hdo3 b 89 3; \ + mknod /dev/hdo4 b 89 4; \ + mknod /dev/hdo5 b 89 5; \ + mknod /dev/hdo6 b 89 6; \ + mknod /dev/hdo7 b 89 7; \ + mknod /dev/hdo8 b 89 8; \ + mknod /dev/hdo9 b 89 9; \ + mknod /dev/hdo10 b 89 10; \ + mknod /dev/hdo11 b 89 11; \ + mknod /dev/hdo12 b 89 12; \ + mknod /dev/hdo13 b 89 13; \ + mknod /dev/hdo14 b 89 14; \ + mknod /dev/hdo15 b 89 15; \ + mknod /dev/hdo16 b 89 16; \ + chown root.disk /dev/hdo*; \ + chmod 660 /dev/hdo*; \ +fi + +if [ ! -f /dev/hdp ]; then \ + echo "Making IDE7 Secondary Devices hdp's"; \ + mknod /dev/hdp b 89 64; \ + mknod /dev/hdp1 b 89 65; \ + mknod /dev/hdp2 b 89 66; \ + mknod /dev/hdp3 b 89 67; \ + mknod /dev/hdp4 b 89 68; \ + mknod /dev/hdp5 b 89 69; \ + mknod /dev/hdp6 b 89 70; \ + mknod /dev/hdp7 b 89 71; \ + mknod /dev/hdp8 b 89 72; \ + mknod /dev/hdp9 b 89 73; \ + mknod /dev/hdp10 b 89 74; \ + mknod /dev/hdp11 b 89 75; \ + mknod /dev/hdp12 b 89 76; \ + mknod /dev/hdp13 b 89 77; \ + mknod /dev/hdp14 b 89 78; \ + mknod /dev/hdp15 b 89 79; \ + mknod /dev/hdp16 b 89 80; \ + chown root.disk /dev/hdp*; \ + chmod 660 /dev/hdp*; \ +fi + diff -u --recursive --new-file v2.3.0/linux/drivers/block/Makefile linux/drivers/block/Makefile --- v2.3.0/linux/drivers/block/Makefile Mon Apr 12 16:18:27 1999 +++ linux/drivers/block/Makefile Thu May 13 11:00:08 1999 @@ -158,12 +158,52 @@ IDE_OBJS += via82c586.o endif +ifeq ($(CONFIG_BLK_DEV_GAYLE),y) +IDE_OBJS += gayle.o +endif + +ifeq ($(CONFIG_BLK_DEV_FALCON_IDE),y) +IDE_OBJS += falconide.o +endif + +ifeq ($(CONFIG_BLK_DEV_MAC_IDE),y) +IDE_OBJS += macide.o +endif + +ifeq ($(CONFIG_BLK_DEV_BUDDHA),y) +IDE_OBJS += buddha.o +endif + ifeq ($(CONFIG_BLK_DEV_CMD646),y) IDE_OBJS += cmd646.o endif ifeq ($(CONFIG_BLK_DEV_SL82C105),y) IDE_OBJS += sl82c105.o +endif + +ifeq ($(CONFIG_BLK_DEV_ALI15X3),y) +IDE_OBJS += alim15x3.o +endif + +ifeq ($(CONFIG_BLK_DEV_CY82C693),y) +IDE_OBJS += cy82c693.o +endif + +ifeq ($(CONFIG_BLK_DEV_PIIX),y) +IDE_OBJS += piix.o +endif + +ifeq ($(CONFIG_BLK_DEV_PDC202XX),y) +IDE_OBJS += pdc202xx.o +endif + +ifeq ($(CONFIG_BLK_DEV_AEC6210),y) +IDE_OBJS += aec6210.o +endif + +ifeq ($(CONFIG_BLK_DEV_HPT343),y) +IDE_OBJS += hpt343.o endif ### if CONFIG_BLK_DEV_IDE is n, IDE_OBJS will be ignored diff -u --recursive --new-file v2.3.0/linux/drivers/block/acsi.c linux/drivers/block/acsi.c --- v2.3.0/linux/drivers/block/acsi.c Tue Dec 29 11:23:59 1998 +++ linux/drivers/block/acsi.c Tue May 11 23:32:31 1999 @@ -245,7 +245,7 @@ static struct hd_struct acsi_part[MAX_DEV<<4] = { {0,0}, }; static int access_count[MAX_DEV] = { 0, }; static char busy[MAX_DEV] = { 0, }; -static struct wait_queue *busy_wait; +static DECLARE_WAIT_QUEUE_HEAD(busy_wait); static int CurrentNReq; static int CurrentNSect; diff -u --recursive --new-file v2.3.0/linux/drivers/block/acsi_slm.c linux/drivers/block/acsi_slm.c --- v2.3.0/linux/drivers/block/acsi_slm.c Tue Dec 29 11:23:59 1998 +++ linux/drivers/block/acsi_slm.c Tue May 11 23:33:00 1999 @@ -143,8 +143,8 @@ static int SLMError; /* wait queues */ -static struct wait_queue *slm_wait; /* waiting for buffer */ -static struct wait_queue *print_wait; /* waiting for printing finished */ +static DECLARE_WAIT_QUEUE_HEAD(slm_wait); /* waiting for buffer */ +static DECLARE_WAIT_QUEUE_HEAD(print_wait); /* waiting for printing finished */ /* status codes */ #define SLMSTAT_OK 0x00 diff -u --recursive --new-file v2.3.0/linux/drivers/block/aec6210.c linux/drivers/block/aec6210.c --- v2.3.0/linux/drivers/block/aec6210.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/aec6210.c Thu May 13 11:04:54 1999 @@ -0,0 +1,64 @@ +/* + * linux/drivers/block/aec6210.c Version 0.01 Nov 17, 1998 + * + * Copyright (C) 1998 Andre Hedrick (hedrick@astro.dyer.vanderbilt.edu) + * + * pio 0 :: 40: 00 07 00 00 00 00 00 00 02 07 a6 04 00 02 00 02 + * pio 1 :: 40: 0a 07 00 00 00 00 00 00 02 07 a6 05 00 02 00 02 + * pio 2 :: 40: 08 07 00 00 00 00 00 00 02 07 a6 05 00 02 00 02 + * pio 3 :: 40: 03 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 + * pio 4 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 + * dma 0 :: 40: 0a 07 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 + * dma 1 :: 40: 02 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 + * dma 2 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 + * 50: ff ff ff ff 00 06 04 00 00 00 00 00 00 00 00 00 + * + * udma 0 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 + * 50: ff ff ff ff 01 06 04 00 00 00 00 00 00 00 00 00 + * + * udma 1 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 + * 50: ff ff ff ff 01 06 04 00 00 00 00 00 00 00 00 00 + * + * udma 2 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 + * 50: ff ff ff ff 02 06 04 00 00 00 00 00 00 00 00 00 + * + * auto :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 + * 50: ff ff ff ff 02 06 04 00 00 00 00 00 00 00 00 00 + * + * auto :: 40: 01 04 01 04 01 04 01 04 02 05 a6 cf 00 02 00 02 + * 50: ff ff ff ff aa 06 04 00 00 00 00 00 00 00 00 00 + * + * NO-Devices + * 40: 00 00 00 00 00 00 00 00 02 05 a6 00 00 02 00 02 + * 50: ff ff ff ff 00 06 00 00 00 00 00 00 00 00 00 00 + + */ + +#include /* for CONFIG_BLK_DEV_IDEPCI */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +__initfunc(unsigned int pci_init_aec6210 (struct pci_dev *dev, const char *name)) +{ + if (dev->rom_address) { + pci_write_config_dword(dev, PCI_ROM_ADDRESS, + dev->rom_address | PCI_ROM_ADDRESS_ENABLE); + printk("%s: ROM enabled at 0x%08lx\n", + name, dev->rom_address); + } + return dev->irq; +} diff -u --recursive --new-file v2.3.0/linux/drivers/block/ali14xx.c linux/drivers/block/ali14xx.c --- v2.3.0/linux/drivers/block/ali14xx.c Wed May 6 14:42:53 1998 +++ linux/drivers/block/ali14xx.c Thu May 13 11:04:54 1999 @@ -47,8 +47,10 @@ #include #include #include +#include + #include -#include "ide.h" + #include "ide_modes.h" /* port addresses for auto-detection */ diff -u --recursive --new-file v2.3.0/linux/drivers/block/alim15x3.c linux/drivers/block/alim15x3.c --- v2.3.0/linux/drivers/block/alim15x3.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/alim15x3.c Thu May 13 11:04:54 1999 @@ -0,0 +1,347 @@ +/* + * linux/drivers/block/alim15x3.c Version 0.04 Feb. 8, 1999 + * + * Copyright (C) 1998-99 Michel Aubry, Maintainer + * Copyright (C) 1998-99 Andrzej Krzysztofowicz, Maintainer + * Copyright (C) 1998-99 Andre Hedrick, Integrater and Maintainer + * + * (U)DMA capable version of ali 1533/1543(C) + * + * Default disable (U)DMA on all devices execpt hard disks. + * This measure of overkill is needed to stablize the chipset code. + * + */ + +#include +#include +#include +#include + +#include + +#define DISPLAY_ALI_TIMINGS + +#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) +#include +#include + +static int ali_get_info(char *buffer, char **addr, off_t offset, int count, int dummy); +extern int (*ali_display_info)(char *, char **, off_t, int, int); /* ide-proc.c */ +struct pci_dev *bmide_dev; + +char *fifo[4] = { + "FIFO Off", + "FIFO On ", + "DMA mode", + "PIO mode" }; + +char *udmaT[8] = { + "1.5T", + " 2T", + "2.5T", + " 3T", + "3.5T", + " 4T", + " 6T", + " 8T" +}; + +char *channel_status[8] = { + "OK ", + "busy ", + "DRQ ", + "DRQ busy ", + "error ", + "error busy ", + "error DRQ ", + "error DRQ busy" +}; +#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */ + +__initfunc(unsigned int pci_init_ali15x3 (struct pci_dev *dev, const char *name)) +{ + byte confreg0 = 0, confreg1 =0, progif = 0; + int errors = 0; + + if (pci_read_config_byte(dev, 0x50, &confreg1)) + goto veryspecialsettingserror; + if (!(confreg1 & 0x02)) + if (pci_write_config_byte(dev, 0x50, confreg1 | 0x02)) + goto veryspecialsettingserror; + + if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif)) + goto veryspecialsettingserror; + if (!(progif & 0x40)) { + /* + * The way to enable them is to set progif + * writable at 0x4Dh register, and set bit 6 + * of progif to 1: + */ + if (pci_read_config_byte(dev, 0x4d, &confreg0)) + goto veryspecialsettingserror; + if (confreg0 & 0x80) + if (pci_write_config_byte(dev, 0x4d, confreg0 & ~0x80)) + goto veryspecialsettingserror; + if (pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x40)) + goto veryspecialsettingserror; + if (confreg0 & 0x80) + if (pci_write_config_byte(dev, 0x4d, confreg0)) + errors++; + } + + if ((pci_read_config_byte(dev, PCI_CLASS_PROG, &progif)) || (!(progif & 0x40))) + goto veryspecialsettingserror; + + printk("%s: enabled read of IDE channels state (en/dis-abled) %s.\n", + name, errors ? "with Error(s)" : "Succeeded" ); + return 0; + +veryspecialsettingserror: + printk("%s: impossible to enable read of IDE channels state (en/dis-abled)!\n", name); + return 0; +} + +int ali15x3_dmaproc (ide_dma_action_t func, ide_drive_t *drive) +{ + switch (func) { + case ide_dma_check: + if (drive->media == ide_cdrom) { + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + struct hd_driveid *id = drive->id; + byte cd_dma_fifo = 0; + + pci_read_config_byte(dev, 0x53, &cd_dma_fifo); + + if (((id->field_valid & 4) || (id->field_valid & 2)) && + (id->capability & 1) && hwif->autodma) { + unsigned long dma_set_bit = hwif->dma_base + 2; +#if 0 + if (cd_dma_fifo & 0x02) + pci_write_config_byte(dev, 0x53, cd_dma_fifo & ~0x02); + pci_write_config_byte(dev, 0x53, cd_dma_fifo|0x01); +#else + pci_write_config_byte(dev, 0x53, cd_dma_fifo|0x01|0x02); +#endif + if (drive->select.b.unit & 0x01) { + outb(inb(dma_set_bit)|0x40, dma_set_bit); + } else { + outb(inb(dma_set_bit)|0x20, dma_set_bit); + } + } else { + if (cd_dma_fifo & 0x01) + pci_write_config_byte(dev, 0x53, cd_dma_fifo & ~0x01); + pci_write_config_byte(dev, 0x53, cd_dma_fifo|0x02); + } + } else if (drive->media != ide_disk) { + return ide_dmaproc(ide_dma_off_quietly, drive); + } + default: + break; + } + return ide_dmaproc(func, drive); /* use standard DMA stuff */ +} + +__initfunc(void ide_init_ali15x3 (ide_hwif_t *hwif)) +{ + struct pci_dev *dev; + byte ideic, inmir; + byte irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6, + 1, 11, 0, 12, 0, 14, 0, 15 }; + hwif->irq = hwif->channel ? 15 : 14; + for (dev = pci_devices; dev; dev=dev->next) /* look for ISA bridge */ + if (dev->vendor==PCI_VENDOR_ID_AL && + dev->device==PCI_DEVICE_ID_AL_M1533) + break; + if (dev) { + pci_read_config_byte(dev, 0x58, &ideic); + ideic = ideic & 0x03; + if ((hwif->channel && ideic == 0x03) || + (!hwif->channel && !ideic)) { + pci_read_config_byte(dev, 0x44, &inmir); + inmir = inmir & 0x0f; + hwif->irq = irq_routing_table[inmir]; + } else + if (hwif->channel && !(ideic & 0x01)) { + pci_read_config_byte(dev, 0x75, &inmir); + inmir = inmir & 0x0f; + hwif->irq = irq_routing_table[inmir]; + } + } +#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) + bmide_dev = hwif->pci_dev; + ali_display_info = &ali_get_info; +#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */ + + if (hwif->dma_base) + hwif->dmaproc = &ali15x3_dmaproc; + return; +} + +#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) +static int ali_get_info(char *buffer, char **addr, off_t offset, int count, int dummy) +{ + byte reg53h, reg5xh, reg5yh, reg5xh1, reg5yh1; + unsigned int bibma; + byte c0, c1; + byte rev, tmp; + char *p = buffer; + char *q; + + /* fetch rev. */ + pci_read_config_byte(bmide_dev, 0x08, &rev); + if (rev >= 0xc1) /* M1543C or newer */ + udmaT[7] = " ???"; + else + fifo[3] = " ??? "; + + /* first fetch bibma: */ + pci_read_config_dword(bmide_dev, 0x20, &bibma); + bibma = (bibma & 0xfff0) ; + /* + * at that point bibma+0x2 et bibma+0xa are byte + * registers to investigate: + */ + c0 = inb((unsigned short)bibma + 0x02); + c1 = inb((unsigned short)bibma + 0x0a); + + p += sprintf(p, + "\n Ali M15x3 Chipset.\n"); + p += sprintf(p, + " ------------------\n"); + pci_read_config_byte(bmide_dev, 0x78, ®53h); + p += sprintf(p, "PCI Clock: %d.\n", reg53h); + + pci_read_config_byte(bmide_dev, 0x53, ®53h); + p += sprintf(p, + "CD_ROM FIFO:%s, CD_ROM DMA:%s\n", + (reg53h & 0x02) ? "Yes" : "No ", + (reg53h & 0x01) ? "Yes" : "No " ); + pci_read_config_byte(bmide_dev, 0x74, ®53h); + p += sprintf(p, + "FIFO Status: contains %d Words, runs%s%s\n\n", + (reg53h & 0x3f), + (reg53h & 0x40) ? " OVERWR" : "", + (reg53h & 0x80) ? " OVERRD." : "." ); + + p += sprintf(p, + "-------------------primary channel-------------------secondary channel---------\n\n"); + + pci_read_config_byte(bmide_dev, 0x09, ®53h); + p += sprintf(p, + "channel status: %s %s\n", + (reg53h & 0x20) ? "On " : "Off", + (reg53h & 0x10) ? "On " : "Off" ); + + p += sprintf(p, + "both channels togth: %s %s\n", + (c0&0x80) ? "No " : "Yes", + (c1&0x80) ? "No " : "Yes" ); + + pci_read_config_byte(bmide_dev, 0x76, ®53h); + p += sprintf(p, + "Channel state: %s %s\n", + channel_status[reg53h & 0x07], + channel_status[(reg53h & 0x70) >> 4] ); + + pci_read_config_byte(bmide_dev, 0x58, ®5xh); + pci_read_config_byte(bmide_dev, 0x5c, ®5yh); + p += sprintf(p, + "Add. Setup Timing: %dT %dT\n", + (reg5xh & 0x07) ? (reg5xh & 0x07) : 8, + (reg5yh & 0x07) ? (reg5yh & 0x07) : 8 ); + + pci_read_config_byte(bmide_dev, 0x59, ®5xh); + pci_read_config_byte(bmide_dev, 0x5d, ®5yh); + p += sprintf(p, + "Command Act. Count: %dT %dT\n" + "Command Rec. Count: %dT %dT\n\n", + (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8, + (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8, + (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16, + (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16 ); + + p += sprintf(p, + "----------------drive0-----------drive1------------drive0-----------drive1------\n\n"); + p += sprintf(p, + "DMA enabled: %s %s %s %s\n", + (c0&0x20) ? "Yes" : "No ", + (c0&0x40) ? "Yes" : "No ", + (c1&0x20) ? "Yes" : "No ", + (c1&0x40) ? "Yes" : "No " ); + + pci_read_config_byte(bmide_dev, 0x54, ®5xh); + pci_read_config_byte(bmide_dev, 0x55, ®5yh); + q = "FIFO threshold: %2d Words %2d Words %2d Words %2d Words\n"; + if (rev < 0xc1) { + if ((rev == 0x20) && (pci_read_config_byte(bmide_dev, 0x4f, &tmp), (tmp &= 0x20))) { + p += sprintf(p, q, 8, 8, 8, 8); + } else { + p += sprintf(p, q, + (reg5xh & 0x03) + 12, + ((reg5xh & 0x30)>>4) + 12, + (reg5yh & 0x03) + 12, + ((reg5yh & 0x30)>>4) + 12 ); + } + } else { + p += sprintf(p, q, + (tmp = (reg5xh & 0x03)) ? (tmp << 3) : 4, + (tmp = ((reg5xh & 0x30)>>4)) ? (tmp << 3) : 4, + (tmp = (reg5yh & 0x03)) ? (tmp << 3) : 4, + (tmp = ((reg5yh & 0x30)>>4)) ? (tmp << 3) : 4 ); + } + +#if 0 + p += sprintf(p, + "FIFO threshold: %2d Words %2d Words %2d Words %2d Words\n", + (reg5xh & 0x03) + 12, + ((reg5xh & 0x30)>>4) + 12, + (reg5yh & 0x03) + 12, + ((reg5yh & 0x30)>>4) + 12 ); +#endif + + p += sprintf(p, + "FIFO mode: %s %s %s %s\n", + fifo[((reg5xh & 0x0c) >> 2)], + fifo[((reg5xh & 0xc0) >> 6)], + fifo[((reg5yh & 0x0c) >> 2)], + fifo[((reg5yh & 0xc0) >> 6)] ); + + pci_read_config_byte(bmide_dev, 0x5a, ®5xh); + pci_read_config_byte(bmide_dev, 0x5b, ®5xh1); + pci_read_config_byte(bmide_dev, 0x5e, ®5yh); + pci_read_config_byte(bmide_dev, 0x5f, ®5yh1); + + p += sprintf(p,/* + "------------------drive0-----------drive1------------drive0-----------drive1------\n")*/ + "Dt RW act. Cnt %2dT %2dT %2dT %2dT\n" + "Dt RW rec. Cnt %2dT %2dT %2dT %2dT\n\n", + (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8, + (reg5xh1 & 0x70) ? ((reg5xh1 & 0x70) >> 4) : 8, + (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8, + (reg5yh1 & 0x70) ? ((reg5yh1 & 0x70) >> 4) : 8, + (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16, + (reg5xh1 & 0x0f) ? (reg5xh1 & 0x0f) : 16, + (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16, + (reg5yh1 & 0x0f) ? (reg5yh1 & 0x0f) : 16 ); + + p += sprintf(p, + "-----------------------------------UDMA Timings--------------------------------\n\n"); + + pci_read_config_byte(bmide_dev, 0x56, ®5xh); + pci_read_config_byte(bmide_dev, 0x57, ®5yh); + p += sprintf(p, + "UDMA: %s %s %s %s\n" + "UDMA timings: %s %s %s %s\n\n", + (reg5xh & 0x08) ? "OK" : "No", + (reg5xh & 0x80) ? "OK" : "No", + (reg5yh & 0x08) ? "OK" : "No", + (reg5yh & 0x80) ? "OK" : "No", + udmaT[(reg5xh & 0x07)], + udmaT[(reg5xh & 0x70) >> 4], + udmaT[reg5yh & 0x07], + udmaT[(reg5yh & 0x70) >> 4] ); + + return p-buffer; /* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */ diff -u --recursive --new-file v2.3.0/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c --- v2.3.0/linux/drivers/block/amiflop.c Sun Nov 15 11:23:08 1998 +++ linux/drivers/block/amiflop.c Tue May 11 23:33:42 1999 @@ -167,9 +167,9 @@ /* request loop (trackbuffer) */ static volatile int fdc_busy = -1; static volatile int fdc_nested = 0; -static struct wait_queue *fdc_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); -static struct wait_queue *motor_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(motor_wait); static volatile int selected = -1; /* currently selected drive */ @@ -185,7 +185,7 @@ * request. */ static volatile char block_flag = 0; -static struct wait_queue *wait_fd_block = NULL; +static DECLARE_WAIT_QUEUE_HEAD(wait_fd_block); /* MS-Dos MFM Coding tables (should go quick and easy) */ static unsigned char mfmencode[16]={ @@ -196,7 +196,7 @@ /* floppy internal millisecond timer stuff */ static volatile int ms_busy = -1; -static struct wait_queue *ms_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(ms_wait); #define MS_TICKS ((amiga_eclock+50)/1000) /* diff -u --recursive --new-file v2.3.0/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c --- v2.3.0/linux/drivers/block/ataflop.c Tue Dec 29 11:23:59 1998 +++ linux/drivers/block/ataflop.c Tue May 11 23:34:07 1999 @@ -314,8 +314,8 @@ /* Synchronization of FDC access. */ static volatile int fdc_busy = 0; -static struct wait_queue *fdc_wait = NULL; -static struct wait_queue *format_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); +static DECLARE_WAIT_QUEUE_HEAD(format_wait); static unsigned int changed_floppies = 0xff, fake_change = 0; #define CHECK_CHANGE_DELAY HZ/2 diff -u --recursive --new-file v2.3.0/linux/drivers/block/buddha.c linux/drivers/block/buddha.c --- v2.3.0/linux/drivers/block/buddha.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/buddha.c Thu May 13 11:04:54 1999 @@ -0,0 +1,161 @@ +/* + * linux/drivers/block/buddha.c -- Amiga Buddha and Catweasel IDE Driver + * + * Copyright (C) 1997 by Geert Uytterhoeven + * + * This driver was written by based on the specifications in README.buddha. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * TODO: + * - test it :-) + * - tune the timings using the speed-register + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + + /* + * The Buddha has 2 IDE interfaces, the Catweasel has 3 + */ + +#define BUDDHA_NUM_HWIFS 2 +#define CATWEASEL_NUM_HWIFS 3 + + + /* + * Bases of the IDE interfaces (relative to the board address) + */ + +#define BUDDHA_BASE1 0x800 +#define BUDDHA_BASE2 0xa00 +#define BUDDHA_BASE3 0xc00 + +static const u_int buddha_bases[CATWEASEL_NUM_HWIFS] = { + BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3 +}; + + + /* + * Offsets from one of the above bases + */ + +#define BUDDHA_DATA 0x00 +#define BUDDHA_ERROR 0x06 /* see err-bits */ +#define BUDDHA_NSECTOR 0x0a /* nr of sectors to read/write */ +#define BUDDHA_SECTOR 0x0e /* starting sector */ +#define BUDDHA_LCYL 0x12 /* starting cylinder */ +#define BUDDHA_HCYL 0x16 /* high byte of starting cyl */ +#define BUDDHA_SELECT 0x1a /* 101dhhhh , d=drive, hhhh=head */ +#define BUDDHA_STATUS 0x1e /* see status-bits */ +#define BUDDHA_CONTROL 0x11a + +static int buddha_offsets[IDE_NR_PORTS] = { + BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL, + BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, BUDDHA_CONTROL +}; + + + /* + * Other registers + */ + +#define BUDDHA_IRQ1 0xf00 /* MSB = 1, Harddisk is source of */ +#define BUDDHA_IRQ2 0xf40 /* interrupt */ +#define BUDDHA_IRQ3 0xf80 + +static const int buddha_irqports[CATWEASEL_NUM_HWIFS] = { + BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3 +}; + +#define BUDDHA_IRQ_MR 0xfc0 /* master interrupt enable */ + + + /* + * Board information + */ + +static u_long buddha_board = 0; +static int buddha_num_hwifs = -1; + + + /* + * Check and acknowledge the interrupt status + */ + +static int buddha_ack_intr(ide_hwif_t *hwif) +{ + unsigned char ch; + + ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]); + if (!(ch & 0x80)) + return 0; + return 1; +} + + + /* + * Any Buddha or Catweasel boards present? + */ + +static int find_buddha(void) +{ + u_int key; + const struct ConfigDev *cd; + + buddha_num_hwifs = 0; + if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA, 0, 0))) + buddha_num_hwifs = BUDDHA_NUM_HWIFS; + else if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL, 0, + 0))) + buddha_num_hwifs = CATWEASEL_NUM_HWIFS; + if (key) { + cd = zorro_get_board(key); + buddha_board = (u_long)cd->cd_BoardAddr; + if (buddha_board) { + buddha_board = ZTWO_VADDR(buddha_board); + /* write to BUDDHA_IRQ_MR to enable the board IRQ */ + *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0; + zorro_config_board(key, 0); + } + } + return buddha_num_hwifs; +} + + + /* + * Probe for a Buddha or Catweasel IDE interface + * We support only _one_ of them, no multiple boards! + */ + +void buddha_init(void) +{ + hw_regs_t hw; + int i, index; + + if (buddha_num_hwifs < 0 && !find_buddha()) + return; + + for (i = 0; i < buddha_num_hwifs; i++) { + ide_setup_ports(&hw, (ide_ioreg_t)(buddha_board+buddha_bases[i]), + buddha_offsets, 0, + (ide_ioreg_t)(buddha_board+buddha_irqports[i]), + buddha_ack_intr, IRQ_AMIGA_PORTS); + index = ide_register_hw(&hw, NULL); + if (index != -1) + printk("ide%d: %s IDE interface\n", index, + buddha_num_hwifs == BUDDHA_NUM_HWIFS ? "Buddha" : + "Catweasel"); + } +} diff -u --recursive --new-file v2.3.0/linux/drivers/block/cmd640.c linux/drivers/block/cmd640.c --- v2.3.0/linux/drivers/block/cmd640.c Mon Jan 4 15:07:27 1999 +++ linux/drivers/block/cmd640.c Thu May 13 11:04:54 1999 @@ -110,8 +110,10 @@ #include #include #include +#include + #include -#include "ide.h" + #include "ide_modes.h" /* diff -u --recursive --new-file v2.3.0/linux/drivers/block/cmd646.c linux/drivers/block/cmd646.c --- v2.3.0/linux/drivers/block/cmd646.c Mon Mar 15 16:11:29 1999 +++ linux/drivers/block/cmd646.c Thu May 13 11:04:54 1999 @@ -12,8 +12,10 @@ #include #include #include +#include +#include + #include -#include "ide.h" static int cmd646_config_drive_for_dma(ide_drive_t *drive) { @@ -43,14 +45,14 @@ } /* This is fun. -DaveM */ -#define IDE_SETXFER 0x03 -#define IDE_SETFEATURE 0xef -#define IDE_DMA2_ENABLE 0x22 -#define IDE_DMA1_ENABLE 0x21 -#define IDE_DMA0_ENABLE 0x20 -#define IDE_UDMA2_ENABLE 0x42 -#define IDE_UDMA1_ENABLE 0x41 -#define IDE_UDMA0_ENABLE 0x40 +#define IDE_SETXFER SETFEATURES_XFER +#define IDE_SETFEATURE WIN_SETFEATURES +#define IDE_DMA2_ENABLE XFER_MW_DMA_2 +#define IDE_DMA1_ENABLE XFER_MW_DMA_1 +#define IDE_DMA0_ENABLE XFER_MW_DMA_0 +#define IDE_UDMA2_ENABLE XFER_UDMA_2 +#define IDE_UDMA1_ENABLE XFER_UDMA_1 +#define IDE_UDMA0_ENABLE XFER_UDMA_0 static __inline__ unsigned char dma2_bits_to_command(unsigned char bits) { @@ -212,10 +214,36 @@ return ide_dmaproc(func, drive); } +/* + * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old + * event order for DMA transfers. + */ +static int cmd646_1_dmaproc(ide_dma_action_t func, ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + unsigned long dma_base = hwif->dma_base; + byte dma_stat; + + if (func == ide_dma_end) { + drive->waiting_for_dma = 0; + dma_stat = inb(dma_base+2); /* get DMA status */ + outb(inb(dma_base)&~1, dma_base); /* stop DMA */ + outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ + return (dma_stat & 7) != 4; /* verify good DMA status */ + } + + /* Other cases are done by generic IDE-DMA code. */ + return cmd646_dmaproc(func, drive); +} + __initfunc(void ide_init_cmd646 (ide_hwif_t *hwif)) { struct pci_dev *dev = hwif->pci_dev; unsigned char mrdmode; + unsigned int class_rev; + + pci_read_config_dword(hwif->pci_dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; hwif->chipset = ide_cmd646; @@ -247,5 +275,9 @@ (void) pci_write_config_byte(dev, 0x58, 0x3f); (void) pci_write_config_byte(dev, 0x5b, 0x3f); - hwif->dmaproc = &cmd646_dmaproc; + if (class_rev == 0x01) { + hwif->dmaproc = &cmd646_1_dmaproc; + } else { + hwif->dmaproc = &cmd646_dmaproc; + } } diff -u --recursive --new-file v2.3.0/linux/drivers/block/cy82c693.c linux/drivers/block/cy82c693.c --- v2.3.0/linux/drivers/block/cy82c693.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/cy82c693.c Thu May 13 11:04:54 1999 @@ -0,0 +1,431 @@ +/* + * linux/drivers/block/cy82c693.c Version 0.33 Jan. 23, 1999 + * + * Copyright (C) 1998, 1999 Andreas S. Krebs (akrebs@altavista.net), Maintainer + * Copyright (C) 1998 Andre Hedrick, Integrater + * + * CYPRESS CY82C693 chipset IDE controller + * + * The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards. + * Writting the driver was quite simple, since most of the job is + * done by the generic pci-ide support. + * The hard part was finding the CY82C693's datasheet on Cypress's + * web page :-(. But Altavista solved this problem :-). + * + * + * Notes: + * - I recently got a 16.8G IBM DTTA, so I was able to test it with + * a large and fast disk - the results look great, so I'd say the + * driver is working fine :-) + * hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA + * - this is my first linux driver, so there's probably a lot of room + * for optimizations and bug fixing, so fell free to do it. + * - use idebus=xx parameter to set PCI bus speed - needed to calc + * timings for PIO modes (default will be 40) + * - if using PIO mode it's a good idea to set the PIO mode and + * 32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda + * - I had some problems with my IBM DHEA with PIO modes < 2 + * (lost interrupts) ????? + * - first tests with DMA look okay, they seem to work, but there is a + * problem with sound - the BusMaster IDE TimeOut should fixed this + * + * + * History: + * ASK@1999-01-23: v0.33 made a few minor code clean ups + * removed DMA clock speed setting by default + * added boot message + * ASK@1998-11-01: v0.32 added support to set BusMaster IDE TimeOut + * added support to set DMA Controller Clock Speed + * ASK@1998-10-31: v0.31 fixed problem with setting to high DMA modes on some drive + * ASK@1998-10-29: v0.3 added support to set DMA modes + * ASK@1998-10-28: v0.2 added support to set PIO modes + * ASK@1998-10-27: v0.1 first version - chipset detection + * + */ + +#include +#include +#include +#include + +#include + +#include "ide_modes.h" + +/* the current version */ +#define CY82_VERSION "CY82C693U driver v0.33 99-01-23 Andreas S. Krebs (akrebs@altavista.net)" + +/* + * The following are used to debug the driver. + */ +#define CY82C693_DEBUG_LOGS 0 +#define CY82C693_DEBUG_INFO 0 + +/* define CY82C693_SETDMA_CLOCK to set DMA Controller Clock Speed to ATCLK */ +#undef CY82C693_SETDMA_CLOCK + +/* + * note: the value for busmaster timeout is tricky and i got it by trial and error ! + * using a to low value will cause DMA timeouts and drop IDE performance + * using a to high value will cause audio playback to scatter + * if you know a better value or how to calc it, please let me know + */ +#define BUSMASTER_TIMEOUT 0x50 /* twice the value written in cy82c693ub datasheet */ +/* + * the value above was tested on my machine and it seems to work okay + */ + +/* here are the offset definitions for the registers */ +#define CY82_IDE_CMDREG 0x04 +#define CY82_IDE_ADDRSETUP 0x48 +#define CY82_IDE_MASTER_IOR 0x4C +#define CY82_IDE_MASTER_IOW 0x4D +#define CY82_IDE_SLAVE_IOR 0x4E +#define CY82_IDE_SLAVE_IOW 0x4F +#define CY82_IDE_MASTER_8BIT 0x50 +#define CY82_IDE_SLAVE_8BIT 0x51 + +#define CY82_INDEX_PORT 0x22 +#define CY82_DATA_PORT 0x23 + +#define CY82_INDEX_CTRLREG1 0x01 +#define CY82_INDEX_CHANNEL0 0x30 +#define CY82_INDEX_CHANNEL1 0x31 +#define CY82_INDEX_TIMEOUT 0x32 + +/* the max PIO mode - from datasheet */ +#define CY82C693_MAX_PIO 4 + +/* the min and max PCI bus speed in MHz - from datasheet */ +#define CY82C963_MIN_BUS_SPEED 25 +#define CY82C963_MAX_BUS_SPEED 33 + +/* the struct for the PIO mode timings */ +typedef struct pio_clocks_s { + byte address_time; /* Address setup (clocks) */ + byte time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */ + byte time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */ + byte time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */ +} pio_clocks_t; + +/* + * calc clocks using bus_speed + * returns (rounded up) time in bus clocks for time in ns + */ +static int calc_clk (int time, int bus_speed) +{ + int clocks; + + clocks = (time*bus_speed+999)/1000 -1; + + if (clocks < 0) + clocks = 0; + + if (clocks > 0x0F) + clocks = 0x0F; + + return clocks; +} + +/* + * compute the values for the clock registers for PIO + * mode and pci_clk [MHz] speed + * + * NOTE: for mode 0,1 and 2 drives 8-bit IDE command control registers are used + * for mode 3 and 4 drives 8 and 16-bit timings are the same + * + */ +static void compute_clocks (byte pio, pio_clocks_t *p_pclk) +{ + int clk1, clk2; + int bus_speed; + + bus_speed = ide_system_bus_speed(); /* get speed of PCI bus */ + /* we don't check against CY82C693's min and max speed, + * so you can play with the idebus=xx parameter + */ + + if (pio > CY82C693_MAX_PIO) + pio = CY82C693_MAX_PIO; + + /* let's calc the address setup time clocks */ + p_pclk->address_time = (byte)calc_clk(ide_pio_timings[pio].setup_time, bus_speed); + + /* let's calc the active and recovery time clocks */ + clk1 = calc_clk(ide_pio_timings[pio].active_time, bus_speed); + + /* calc recovery timing */ + clk2 = ide_pio_timings[pio].cycle_time - + ide_pio_timings[pio].active_time - + ide_pio_timings[pio].setup_time; + + clk2 = calc_clk(clk2, bus_speed); + + clk1 = (clk1<<4)|clk2; /* combine active and recovery clocks */ + + /* note: we use the same values for 16bit IOR and IOW + * those are all the same, since I don't have other + * timings than those from ide_modes.h + */ + + p_pclk->time_16r = (byte)clk1; + p_pclk->time_16w = (byte)clk1; + + /* what are good values for 8bit ?? */ + p_pclk->time_8 = (byte)clk1; +} + +/* + * set DMA mode a specific channel for CY82C693 + */ +static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) +{ + byte index; + byte data; + + if (mode>2) /* make sure we set a valid mode */ + mode = 2; + + if (mode > drive->id->tDMA) /* to be absolutly sure we have a valid mode */ + mode = drive->id->tDMA; + + index = (HWIF(drive)->channel==0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1; + +#if CY82C693_DEBUG_LOGS + /* for debug let's show the previous values */ + + OUT_BYTE(index, CY82_INDEX_PORT); + data = IN_BYTE(CY82_DATA_PORT); + + printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", drive->name, HWIF(drive)->channel, drive->select.b.unit, (data&0x3), ((data>>2)&1)); +#endif /* CY82C693_DEBUG_LOGS */ + + data = (byte)mode|(byte)(single<<2); + + OUT_BYTE(index, CY82_INDEX_PORT); + OUT_BYTE(data, CY82_DATA_PORT); + +#if CY82C693_DEBUG_INFO + printk (KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", drive->name, HWIF(drive)->channel, drive->select.b.unit, mode, single); +#endif /* CY82C693_DEBUG_INFO */ + + /* + * note: below we set the value for Bus Master IDE TimeOut Register + * I'm not absolutly sure what this does, but it solved my problem + * with IDE DMA and sound, so I now can play sound and work with + * my IDE driver at the same time :-) + * + * If you know the correct (best) value for this register please + * let me know - ASK + */ + + data = BUSMASTER_TIMEOUT; + OUT_BYTE(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT); + OUT_BYTE(data, CY82_DATA_PORT); + +#if CY82C693_DEBUG_INFO + printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n", drive->name, data); +#endif /* CY82C693_DEBUG_INFO */ +} + +/* + * used to set DMA mode for CY82C693 (single and multi modes) + */ +static int cy82c693_dmaproc(ide_dma_action_t func, ide_drive_t *drive) +{ + /* + * if the function is dma on, set dma mode for drive everything + * else is done by the defaul func + */ + if (func == ide_dma_on) { + struct hd_driveid *id = drive->id; + +#if CY82C693_DEBUG_INFO + printk (KERN_INFO "dma_on: %s\n", drive->name); +#endif /* CY82C693_DEBUG_INFO */ + + if (id != NULL) { + /* Enable DMA on any drive that has DMA (multi or single) enabled */ + if (id->field_valid & 2) { /* regular DMA */ + int mmode, smode; + + mmode = id->dma_mword & (id->dma_mword >> 8); + smode = id->dma_1word & (id->dma_1word >> 8); + + if (mmode != 0) + cy82c693_dma_enable(drive, (mmode >> 1), 0); /* enable multi */ + else if (smode != 0) + cy82c693_dma_enable(drive, (smode >> 1), 1); /* enable single */ + } + } + } + return ide_dmaproc(func, drive); +} + +/* + * tune ide drive - set PIO mode + */ +static void cy82c693_tune_drive (ide_drive_t *drive, byte pio) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + pio_clocks_t pclk; + unsigned int addrCtrl; + + /* select primary or secondary channel */ + if (hwif->index > 0) /* drive is on the secondary channel */ + dev = dev->next; + +#if CY82C693_DEBUG_LOGS + /* for debug let's show the register values */ + + if (drive->select.b.unit == 0) { + /* + * get master drive registers + * address setup control register + * is 32 bit !!! + */ + pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); + addrCtrl &= 0x0F; + + /* now let's get the remaining registers */ + pci_read_config_byte(dev, CY82_IDE_MASTER_IOR, &pclk.time_16r); + pci_read_config_byte(dev, CY82_IDE_MASTER_IOW, &pclk.time_16w); + pci_read_config_byte(dev, CY82_IDE_MASTER_8BIT, &pclk.time_8); + } else { + /* + * set slave drive registers + * address setup control register + * is 32 bit !!! + */ + pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); + + addrCtrl &= 0xF0; + addrCtrl >>= 4; + + /* now let's get the remaining registers */ + pci_read_config_byte(dev, CY82_IDE_SLAVE_IOR, &pclk.time_16r); + pci_read_config_byte(dev, CY82_IDE_SLAVE_IOW, &pclk.time_16w); + pci_read_config_byte(dev, CY82_IDE_SLAVE_8BIT, &pclk.time_8); + } + + printk (KERN_INFO "%s (ch=%d, dev=%d): PIO timing is (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->channel, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); +#endif /* CY82C693_DEBUG_LOGS */ + + /* first let's calc the pio modes */ + pio = ide_get_best_pio_mode(drive, pio, CY82C693_MAX_PIO, NULL); + +#if CY82C693_DEBUG_INFO + printk (KERN_INFO "%s: Selected PIO mode %d\n", drive->name, pio); +#endif /* CY82C693_DEBUG_INFO */ + + compute_clocks(pio, &pclk); /* let's calc the values for this PIO mode */ + + /* now let's write the clocks registers */ + if (drive->select.b.unit == 0) { + /* + * set master drive + * address setup control register + * is 32 bit !!! + */ + pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); + + addrCtrl &= (~0xF); + addrCtrl |= (unsigned int)pclk.address_time; + pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); + + /* now let's set the remaining registers */ + pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r); + pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w); + pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8); + + addrCtrl &= 0xF; + } else { + /* + * set slave drive + * address setup control register + * is 32 bit !!! + */ + pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); + + addrCtrl &= (~0xF0); + addrCtrl |= ((unsigned int)pclk.address_time<<4); + pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); + + /* now let's set the remaining registers */ + pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r); + pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w); + pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8); + + addrCtrl >>= 4; + addrCtrl &= 0xF; + } + +#if CY82C693_DEBUG_INFO + printk (KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->channel, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); +#endif /* CY82C693_DEBUG_INFO */ +} + +/* + * this function is called during init and is used to setup the cy82c693 chip + */ +static void init_cy82c693_chip (struct pci_dev *dev) +{ + static int initDone = 0; +#ifdef CY82C693_SETDMA_CLOCK + byte data; +#endif /* CY82C693_SETDMA_CLOCK */ + + if (initDone != 0) /* only perform setup once */ + return; + initDone = 1; + + /* write info about this verion of the driver */ + printk (KERN_INFO CY82_VERSION "\n"); + +#ifdef CY82C693_SETDMA_CLOCK + /* okay let's set the DMA clock speed */ + + OUT_BYTE(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); + data = IN_BYTE(CY82_DATA_PORT); + +#if CY82C693_DEBUG_INFO + printk (KERN_INFO "CY82U693: Peripheral Configuration Register: 0x%X\n", data); +#endif /* CY82C693_DEBUG_INFO */ + + /* + * for some reason sometimes the DMA controller + * speed is set to ATCLK/2 ???? - we fix this here + * + * note: i don't know what causes this strange behaviour, + * but even changing the dma speed doesn't solve it :-( + * the ide performance is still only half the normal speed + * + * if anybody knows what goes wrong with my machine, please + * let me know - ASK + */ + + data |= 0x03; + + OUT_BYTE(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); + OUT_BYTE(data, CY82_DATA_PORT); + +#if CY82C693_DEBUG_INFO + printk (KERN_INFO "CY82U693: New Peripheral Configuration Register: 0x%X\n", data); +#endif /* CY82C693_DEBUG_INFO */ + +#endif /* CY82C693_SETDMA_CLOCK */ +} + +/* + * the init function - called for each ide channel once + */ +__initfunc(void ide_init_cy82c693(ide_hwif_t *hwif)) +{ + hwif->chipset = ide_cy82c693; + hwif->dmaproc = &cy82c693_dmaproc; + hwif->tuneproc = &cy82c693_tune_drive; + + init_cy82c693_chip(hwif->pci_dev); +} + diff -u --recursive --new-file v2.3.0/linux/drivers/block/dtc2278.c linux/drivers/block/dtc2278.c --- v2.3.0/linux/drivers/block/dtc2278.c Wed May 6 14:42:53 1998 +++ linux/drivers/block/dtc2278.c Thu May 13 11:04:54 1999 @@ -14,8 +14,10 @@ #include #include #include +#include + #include -#include "ide.h" + #include "ide_modes.h" /* diff -u --recursive --new-file v2.3.0/linux/drivers/block/falconide.c linux/drivers/block/falconide.c --- v2.3.0/linux/drivers/block/falconide.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/falconide.c Thu May 13 11:04:54 1999 @@ -0,0 +1,66 @@ +/* + * linux/drivers/block/falconide.c -- Atari Falcon IDE Driver + * + * Created 12 Jul 1997 by Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + + /* + * Base of the IDE interface + */ + +#define ATA_HD_BASE 0xfff00000 + + /* + * Offsets from the above base + */ + +#define ATA_HD_DATA 0x00 +#define ATA_HD_ERROR 0x05 /* see err-bits */ +#define ATA_HD_NSECTOR 0x09 /* nr of sectors to read/write */ +#define ATA_HD_SECTOR 0x0d /* starting sector */ +#define ATA_HD_LCYL 0x11 /* starting cylinder */ +#define ATA_HD_HCYL 0x15 /* high byte of starting cyl */ +#define ATA_HD_SELECT 0x19 /* 101dhhhh , d=drive, hhhh=head */ +#define ATA_HD_STATUS 0x1d /* see status-bits */ +#define ATA_HD_CONTROL 0x39 + +static int falconide_offsets[IDE_NR_PORTS] = { + ATA_HD_DATA, ATA_HD_ERROR, ATA_HD_NSECTOR, ATA_HD_SECTOR, ATA_HD_LCYL, + ATA_HD_HCYL, ATA_HD_SELECT, ATA_HD_STATUS, ATA_HD_CONTROL, -1 +}; + + + /* + * Probe for a Falcon IDE interface + */ + +void falconide_init(void) +{ + if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) { + hw_regs_t hw; + int index; + + ide_setup_ports(&hw, (ide_ioreg_t)ATA_HD_BASE, falconide_offsets, + 0, 0, NULL, IRQ_MFP_IDE); + index = ide_register_hw(&hw, NULL); + + if (index != -1) + printk("ide%d: Falcon IDE interface\n", index); + } +} diff -u --recursive --new-file v2.3.0/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v2.3.0/linux/drivers/block/floppy.c Fri Mar 26 13:29:14 1999 +++ linux/drivers/block/floppy.c Tue May 11 14:48:07 1999 @@ -466,7 +466,9 @@ #define FD_COMMAND_OKAY 3 static volatile int command_status = FD_COMMAND_NONE, fdc_busy = 0; -static struct wait_queue *fdc_wait = NULL, *command_done = NULL; +static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); +static DECLARE_WAIT_QUEUE_HEAD(command_done); + #define NO_SIGNAL (!interruptible || !signal_pending(current)) #define CALL(x) if ((x) == -EINTR) return -EINTR #define ECALL(x) if ((ret = (x))) return ret; diff -u --recursive --new-file v2.3.0/linux/drivers/block/gayle.c linux/drivers/block/gayle.c --- v2.3.0/linux/drivers/block/gayle.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/gayle.c Thu May 13 11:04:54 1999 @@ -0,0 +1,169 @@ +/* + * linux/drivers/block/gayle.c -- Amiga Gayle IDE Driver + * + * Created 9 Jul 1997 by Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + + /* + * Bases of the IDE interfaces + */ + +#define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */ +#define GAYLE_BASE_1200 0xda0000 /* A1200/A600 */ + + /* + * Offsets from one of the above bases + */ + +#define GAYLE_DATA 0x00 +#define GAYLE_ERROR 0x06 /* see err-bits */ +#define GAYLE_NSECTOR 0x0a /* nr of sectors to read/write */ +#define GAYLE_SECTOR 0x0e /* starting sector */ +#define GAYLE_LCYL 0x12 /* starting cylinder */ +#define GAYLE_HCYL 0x16 /* high byte of starting cyl */ +#define GAYLE_SELECT 0x1a /* 101dhhhh , d=drive, hhhh=head */ +#define GAYLE_STATUS 0x1e /* see status-bits */ +#define GAYLE_CONTROL 0x101a + +static int gayle_offsets[IDE_NR_PORTS] = { + GAYLE_DATA, GAYLE_ERROR, GAYLE_NSECTOR, GAYLE_SECTOR, GAYLE_LCYL, + GAYLE_HCYL, GAYLE_SELECT, GAYLE_STATUS, -1, -1 +}; + + + /* + * These are at different offsets from the base + */ + +#define GAYLE_IRQ_4000 0xdd3020 /* MSB = 1, Harddisk is source of */ +#define GAYLE_IRQ_1200 0xda9000 /* interrupt */ + + + /* + * Offset of the secondary port for IDE doublers + * Note that GAYLE_CONTROL is NOT available then! + */ + +#define GAYLE_NEXT_PORT 0x1000 + +#ifndef CONFIG_BLK_DEV_IDEDOUBLER +#define GAYLE_NUM_HWIFS 1 +#define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS +#define GAYLE_HAS_CONTROL_REG 1 +#else /* CONFIG_BLK_DEV_IDEDOUBLER */ +#define GAYLE_NUM_HWIFS 2 +#define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \ + GAYLE_NUM_HWIFS-1) +#define GAYLE_HAS_CONTROL_REG (!ide_doubler) +int ide_doubler = 0; /* support IDE doublers? */ +#endif /* CONFIG_BLK_DEV_IDEDOUBLER */ + + + /* + * Check and acknowledge the interrupt status + */ + +static int gayle_ack_intr_a4000(ide_hwif_t *hwif) +{ + unsigned char ch; + + ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]); + if (!(ch & 0x80)) + return 0; + return 1; +} + +static int gayle_ack_intr_a1200(ide_hwif_t *hwif) +{ + unsigned char ch; + + ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]); + if (!(ch & 0x80)) + return 0; + (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]); + outb(0x7c | (ch & 0x03), hwif->io_ports[IDE_IRQ_OFFSET]); + return 1; +} + + /* + * Probe for a Gayle IDE interface (and optionally for an IDE doubler) + */ + +void gayle_init(void) +{ + int a4000, i; + + if (!MACH_IS_AMIGA) + return; + + if (!(a4000 = AMIGAHW_PRESENT(A4000_IDE)) && !AMIGAHW_PRESENT(A1200_IDE)) + return; + + for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { + ide_ioreg_t base, ctrlport, irqport; + ide_ack_intr_t *ack_intr; + hw_regs_t hw; + int index; + + if (a4000) { + base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_4000); + irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_4000); + ack_intr = gayle_ack_intr_a4000; + } else { + base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_1200); + irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_1200); + ack_intr = gayle_ack_intr_a1200; + } + + if (GAYLE_HAS_CONTROL_REG) + ctrlport = base + GAYLE_CONTROL; + else + ctrlport = 0; + + base += i*GAYLE_NEXT_PORT; + + ide_setup_ports(&hw, base, gayle_offsets, + ctrlport, irqport, ack_intr, IRQ_AMIGA_PORTS); + + index = ide_register_hw(&hw, NULL); + if (index != -1) { + switch (i) { + case 0: + printk("ide%d: Gayle IDE interface (A%d style)\n", index, + a4000 ? 4000 : 1200); + break; +#ifdef CONFIG_BLK_DEV_IDEDOUBLER + case 1: + printk("ide%d: IDE doubler\n", index); + break; +#endif /* CONFIG_BLK_DEV_IDEDOUBLER */ + } + } +#if 1 /* TESTING */ + if (i == 1) { + volatile u_short *addr = (u_short *)base; + u_short data; + printk("+++ Probing for IDE doubler... "); + *addr = 0xffff; + data = *addr; + printk("probe returned 0x%02x (PLEASE REPORT THIS!!)\n", data); + } +#endif /* TESTING */ + } +} diff -u --recursive --new-file v2.3.0/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.3.0/linux/drivers/block/genhd.c Mon Apr 12 16:18:27 1999 +++ linux/drivers/block/genhd.c Thu May 13 11:00:08 1999 @@ -83,6 +83,10 @@ * This requires special handling here. */ switch (hd->major) { + case IDE7_MAJOR: + unit += 2; + case IDE6_MAJOR: + unit += 2; case IDE5_MAJOR: unit += 2; case IDE4_MAJOR: diff -u --recursive --new-file v2.3.0/linux/drivers/block/hd.c linux/drivers/block/hd.c --- v2.3.0/linux/drivers/block/hd.c Wed Feb 24 16:27:53 1999 +++ linux/drivers/block/hd.c Tue May 11 15:22:57 1999 @@ -68,7 +68,7 @@ static char special_op[MAX_HD] = { 0, }; static int access_count[MAX_HD] = {0, }; static char busy[MAX_HD] = {0, }; -static struct wait_queue * busy_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(busy_wait); static int reset = 0; static int hd_error = 0; diff -u --recursive --new-file v2.3.0/linux/drivers/block/hpt343.c linux/drivers/block/hpt343.c --- v2.3.0/linux/drivers/block/hpt343.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/hpt343.c Thu May 13 11:04:54 1999 @@ -0,0 +1,394 @@ +/* + * linux/drivers/block/hpt343.c Version 0.23 May 12, 1999 + * + * Copyright (C) 1998-99 Andre Hedrick + * (hedrick@astro.dyer.vanderbilt.edu) + * + * 00:12.0 Unknown mass storage controller: + * Triones Technologies, Inc. + * Unknown device 0003 (rev 01) + * + * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010) + * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030) + * hde: DMA 2 (0x0000 0x0002) (0x0000 0x0010) + * hdf: DMA 2 (0x0002 0x0012) (0x0010 0x0030) + * hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070) + * hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0) + * + * drive_number + * = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); + * = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); + */ + +#include /* for CONFIG_BLK_DEV_IDEPCI */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "ide_modes.h" + +#ifndef SPLIT_BYTE +#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4))) +#endif + +#define HPT343_DEBUG_DRIVE_INFO 0 +#define HPT343_DISABLE_ALL_DMAING 0 +#define HPT343_DMA_DISK_ONLY 0 + +extern char *ide_xfer_verbose (byte xfer_rate); + +static void hpt343_clear_chipset (ide_drive_t *drive) +{ + int drive_number = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); + unsigned int reg1 = 0, tmp1 = 0; + unsigned int reg2 = 0, tmp2 = 0; + + pci_read_config_dword(HWIF(drive)->pci_dev, 0x44, ®1); + pci_read_config_dword(HWIF(drive)->pci_dev, 0x48, ®2); + tmp1 = ((0x00 << (3*drive_number)) | (reg1 & ~(7 << (3*drive_number)))); + tmp2 = ((0x00 << drive_number) | reg2); + pci_write_config_dword(HWIF(drive)->pci_dev, 0x44, tmp1); + pci_write_config_dword(HWIF(drive)->pci_dev, 0x48, tmp2); +} + +static int hpt343_tune_chipset (ide_drive_t *drive, byte speed) +{ + int err; + byte hi_speed, lo_speed; + int drive_number = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); + unsigned int reg1 = 0, tmp1 = 0; + unsigned int reg2 = 0, tmp2 = 0; + + SPLIT_BYTE(speed, hi_speed, lo_speed); + + if (hi_speed & 7) { + hi_speed = (hi_speed & 4) ? 0x01 : 0x10; + } else { + lo_speed <<= 5; + lo_speed >>= 5; + } + + pci_read_config_dword(HWIF(drive)->pci_dev, 0x44, ®1); + pci_read_config_dword(HWIF(drive)->pci_dev, 0x48, ®2); + tmp1 = ((lo_speed << (3*drive_number)) | (reg1 & ~(7 << (3*drive_number)))); + tmp2 = ((hi_speed << drive_number) | reg2); + err = ide_wait_cmd(drive, WIN_SETFEATURES, speed, SETFEATURES_XFER, 0, NULL); + pci_write_config_dword(HWIF(drive)->pci_dev, 0x44, tmp1); + pci_write_config_dword(HWIF(drive)->pci_dev, 0x48, tmp2); + +#if HPT343_DEBUG_DRIVE_INFO + printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \ + " (0x%02x 0x%02x) 0x%04x\n", + drive->name, ide_xfer_verbose(speed), + drive_number, reg1, tmp1, reg2, tmp2, + hi_speed, lo_speed, err); +#endif /* HPT343_DEBUG_DRIVE_INFO */ + + return(err); +} + +/* + * This allows the configuration of ide_pci chipset registers + * for cards that learn about the drive's UDMA, DMA, PIO capabilities + * after the drive is reported by the OS. Initally for designed for + * HPT343 UDMA chipset by HighPoint|Triones Technologies, Inc. + */ +static int config_chipset_for_dma (ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + byte speed = 0x00; + +#if HPT343_DISABLE_ALL_DMAING + return ((int) ide_dma_off); +#elif HPT343_DMA_DISK_ONLY + if (drive->media != ide_disk) + return ((int) ide_dma_off_quietly); +#endif /* HPT343_DISABLE_ALL_DMAING */ + + if (id->dma_ultra & 0x0004) { + if (!((id->dma_ultra >> 8) & 4)) { + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_ultra |= 0x0404; + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + } + speed = XFER_UDMA_2; + } else if (id->dma_ultra & 0x0002) { + if (!((id->dma_ultra >> 8) & 2)) { + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_ultra |= 0x0202; + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + } + speed = XFER_UDMA_1; + } else if (id->dma_ultra & 0x0001) { + if (!((id->dma_ultra >> 8) & 1)) { + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_ultra |= 0x0101; + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + } + speed = XFER_UDMA_0; + } else if (id->dma_mword & 0x0004) { + if (!((id->dma_mword >> 8) & 4)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_mword |= 0x0404; + drive->id->dma_1word &= ~0x0F00; + } + speed = XFER_MW_DMA_2; + } else if (id->dma_mword & 0x0002) { + if (!((id->dma_mword >> 8) & 2)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_mword |= 0x0202; + drive->id->dma_1word &= ~0x0F00; + } + speed = XFER_MW_DMA_1; + } else if (id->dma_mword & 0x0001) { + if (!((id->dma_mword >> 8) & 1)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_mword |= 0x0101; + drive->id->dma_1word &= ~0x0F00; + } + speed = XFER_MW_DMA_0; + } else if (id->dma_1word & 0x0004) { + if (!((id->dma_1word >> 8) & 4)) { + drive->id->dma_1word &= ~0x0F00; + drive->id->dma_1word |= 0x0404; + drive->id->dma_mword &= ~0x0F00; + } + speed = XFER_SW_DMA_2; + } else if (id->dma_1word & 0x0002) { + if (!((id->dma_1word >> 8) & 2)) { + drive->id->dma_1word &= ~0x0F00; + drive->id->dma_1word |= 0x0202; + drive->id->dma_mword &= ~0x0F00; + } + speed = XFER_SW_DMA_1; + } else if (id->dma_1word & 0x0001) { + if (!((id->dma_1word >> 8) & 1)) { + drive->id->dma_1word &= ~0x0F00; + drive->id->dma_1word |= 0x0101; + drive->id->dma_mword &= ~0x0F00; + } + speed = XFER_SW_DMA_0; + } else { + return ((int) ide_dma_off_quietly); + } + + (void) hpt343_tune_chipset(drive, speed); + + return ((int) ((id->dma_ultra >> 8) & 7) ? ide_dma_on : + ((id->dma_mword >> 8) & 7) ? ide_dma_on : + ((id->dma_1word >> 8) & 7) ? ide_dma_on : + ide_dma_off_quietly); +} + +static void config_chipset_for_pio (ide_drive_t *drive) +{ + unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; + unsigned short xfer_pio = drive->id->eide_pio_modes; + + byte timing, speed, pio; + + pio = ide_get_best_pio_mode(drive, 255, 5, NULL); + + if (xfer_pio> 4) + xfer_pio = 0; + + if (drive->id->eide_pio_iordy > 0) { + for (xfer_pio = 5; + xfer_pio>0 && + drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio]; + xfer_pio--); + } else { + xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : + (drive->id->eide_pio_modes & 2) ? 0x04 : + (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio; + } + + timing = (xfer_pio >= pio) ? xfer_pio : pio; + + switch(timing) { + case 4: speed = XFER_PIO_4;break; + case 3: speed = XFER_PIO_3;break; + case 2: speed = XFER_PIO_2;break; + case 1: speed = XFER_PIO_1;break; + default: + speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; + break; + } + + (void) hpt343_tune_chipset(drive, speed); +} + +#if 0 +static void hpt343_tune_drive (ide_drive_t *drive, byte pio) +{ +} +#endif + +static int config_drive_xfer_rate (ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + ide_dma_action_t dma_func = ide_dma_on; + + if (id && (id->capability & 1) && HWIF(drive)->autodma) { + /* Consult the list of known "bad" drives */ + if (ide_dmaproc(ide_dma_bad_drive, drive)) { + dma_func = ide_dma_off; + goto fast_ata_pio; + } + dma_func = ide_dma_off_quietly; + if (id->field_valid & 4) { + if (id->dma_ultra & 0x0007) { + /* Force if Capable UltraDMA */ + dma_func = config_chipset_for_dma(drive); + if ((id->field_valid & 2) && + (dma_func != ide_dma_on)) + goto try_dma_modes; + } + } else if (id->field_valid & 2) { +try_dma_modes: + if ((id->dma_mword & 0x0007) || + (id->dma_1word & 0x0007)) { + /* Force if Capable regular DMA modes */ + dma_func = config_chipset_for_dma(drive); + if (dma_func != ide_dma_on) + goto no_dma_set; + } + } else if (ide_dmaproc(ide_dma_good_drive, drive)) { + if (id->eide_dma_time > 150) { + goto no_dma_set; + } + /* Consult the list of known "good" drives */ + dma_func = config_chipset_for_dma(drive); + if (dma_func != ide_dma_on) + goto no_dma_set; + } else { + goto fast_ata_pio; + } + } else if ((id->capability & 8) || (id->field_valid & 2)) { +fast_ata_pio: + dma_func = ide_dma_off_quietly; +no_dma_set: + + config_chipset_for_pio(drive); + } + return HWIF(drive)->dmaproc(dma_func, drive); +} + +/* + * hpt343_dmaproc() initiates/aborts (U)DMA read/write operations on a drive. + * + * This is specific to the HPT343 UDMA bios-less chipset + * and HPT345 UDMA bios chipset (stamped HPT363) + * by HighPoint|Triones Technologies, Inc. + */ + +int hpt343_dmaproc (ide_dma_action_t func, ide_drive_t *drive) +{ + switch (func) { + case ide_dma_check: + hpt343_clear_chipset(drive); + return config_drive_xfer_rate(drive); +#if 0 + case ide_dma_off: + case ide_dma_off_quietly: + case ide_dma_on: + case ide_dma_check: + return config_drive_xfer_rate(drive); + case ide_dma_read: + case ide_dma_write: + case ide_dma_begin: + case ide_dma_end: + case ide_dma_test_irq: +#endif + default: + break; + } + return ide_dmaproc(func, drive); /* use standard DMA stuff */ +} + +/* + * If the BIOS does not set the IO base addaress to XX00, 343 will fail. + */ +#define HPT343_PCI_INIT_REG 0x80 + +__initfunc(unsigned int pci_init_hpt343 (struct pci_dev *dev, const char *name)) +{ + int i; + unsigned short cmd; + unsigned long hpt343IoBase = dev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK; +#if 0 + unsigned char misc10 = inb(hpt343IoBase + 0x0010); + unsigned char misc11 = inb(hpt343IoBase + 0x0011); +#endif + + pci_write_config_byte(dev, HPT343_PCI_INIT_REG, 0x00); + pci_read_config_word(dev, PCI_COMMAND, &cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO); + + dev->base_address[0] = (hpt343IoBase + 0x20); + dev->base_address[1] = (hpt343IoBase + 0x34); + dev->base_address[2] = (hpt343IoBase + 0x28); + dev->base_address[3] = (hpt343IoBase + 0x3c); + + for(i=0; i<4; i++) + dev->base_address[i] |= PCI_BASE_ADDRESS_SPACE_IO; + + /* + * Since 20-23 can be assigned and are R/W, we correct them. + */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, dev->base_address[0]); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->base_address[1]); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, dev->base_address[2]); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, dev->base_address[3]); + pci_write_config_word(dev, PCI_COMMAND, cmd); + +#if 0 + outb(misc10|0x78, (hpt343IoBase + 0x0010)); + outb(misc11, (hpt343IoBase + 0x0011)); +#endif + +#ifdef DEBUG + printk("%s: 0x%02x 0x%02x\n", + (pcicmd & PCI_COMMAND_MEMORY) ? "HPT345" : name, + inb(hpt343IoBase + 0x0010), + inb(hpt343IoBase + 0x0011)); +#endif + + pci_write_config_byte(dev, HPT343_PCI_INIT_REG, 0x80); + if (cmd & PCI_COMMAND_MEMORY) { + if (dev->rom_address) { + pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->rom_address | PCI_ROM_ADDRESS_ENABLE); + printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", dev->rom_address); + } + } else { + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); + } + return dev->irq; +} + +__initfunc(void ide_init_hpt343 (ide_hwif_t *hwif)) +{ + if (hwif->dma_base) { + unsigned short pcicmd = 0; + + pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd); + hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0; + hwif->dmaproc = &hpt343_dmaproc; + } +} diff -u --recursive --new-file v2.3.0/linux/drivers/block/ht6560b.c linux/drivers/block/ht6560b.c --- v2.3.0/linux/drivers/block/ht6560b.c Wed Jun 24 14:30:09 1998 +++ linux/drivers/block/ht6560b.c Thu May 13 11:04:54 1999 @@ -57,8 +57,10 @@ #include #include #include +#include + #include -#include "ide.h" + #include "ide_modes.h" /* diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c --- v2.3.0/linux/drivers/block/ide-cd.c Mon Apr 12 16:18:26 1999 +++ linux/drivers/block/ide-cd.c Thu May 13 11:04:54 1999 @@ -258,13 +258,14 @@ #include #include #include +#include + #include #include #include #include #include -#include "ide.h" #include "ide-cd.h" /**************************************************************************** @@ -670,7 +671,8 @@ OUT_BYTE (xferlen & 0xff, IDE_LCYL_REG); OUT_BYTE (xferlen >> 8 , IDE_HCYL_REG); - OUT_BYTE (drive->ctl, IDE_CONTROL_REG); + if (IDE_CONTROL_REG) + OUT_BYTE (drive->ctl, IDE_CONTROL_REG); if (info->dma) (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive)); @@ -2940,7 +2942,19 @@ else printk (" drive"); - printk (", %dkB Cache\n", ntohs(buf.cap.buffer_size)); + printk (", %dkB Cache", ntohs(buf.cap.buffer_size)); + + if (drive->using_dma) { + if ((drive->id->field_valid & 4) && + (drive->id->dma_ultra & (drive->id->dma_ultra >> 8) & 7)) { + printk(", UDMA"); /* UDMA BIOS-enabled! */ + } else if (drive->id->field_valid & 4) { + printk(", (U)DMA"); /* Can be BIOS-enabled! */ + } else { + printk(", DMA"); + } + } + printk("\n"); return nslots; } @@ -2956,6 +2970,53 @@ ide_add_setting(drive, "dsc_overlap", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL); } +#ifdef CONFIG_IDECD_SLOTS +static void ide_cdrom_slot_check (ide_drive_t *drive, int nslots) +{ + tracktype tracks; + struct cdrom_info *info = drive->driver_data; + struct cdrom_device_info *devinfo = &info->devinfo; + int slot_count = 0, drive_stat = 0, tmp; + + for (slot_count=0;slot_countis_changer) { + ide_cdrom_slot_check(drive, nslots); + } +#endif /* CONFIG_IDECD_SLOTS */ return 0; } diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide-disk.c linux/drivers/block/ide-disk.c --- v2.3.0/linux/drivers/block/ide-disk.c Wed Mar 10 17:49:43 1999 +++ linux/drivers/block/ide-disk.c Thu May 13 11:04:54 1999 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-disk.c Version 1.08 Dec 10, 1998 + * linux/drivers/block/ide-disk.c Version 1.09 April 23, 1999 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ @@ -25,12 +25,16 @@ * process of adding new ATA4 compliance. * fixed problems in allowing fdisk to see * the entire disk. + * Version 1.09 added increment of rq->sector in ide_multwrite + * added UDMA 3/4 reporting */ -#define IDEDISK_VERSION "1.08" +#define IDEDISK_VERSION "1.09" #undef REALLY_SLOW_IO /* most systems can safely undef this */ +#define _IDE_DISK_C /* Tell linux/hdsmart.h it's really us */ + #include #include #include @@ -44,14 +48,13 @@ #include #include #include +#include #include #include #include #include -#include "ide.h" - static void idedisk_bswap_data (void *buffer, int wcount) { u16 *p = buffer; @@ -101,6 +104,15 @@ id->cyls = lba_sects / (16 * 63); /* correct cyls */ return 1; /* lba_capacity is our only option */ } + /* + * ... and at least one TLA VBC has POS instead of brain and can't + * tell 16 from 15. + */ + if ((id->lba_capacity >= 15481935) && (id->cyls == 0x3fff) && + (id->heads == 15) && (id->sectors == 63)) { + id->cyls = lba_sects / (15 * 63); /* correct cyls */ + return 1; /* lba_capacity is our only option */ + } /* perform a rough sanity check on lba_sects: within 10% is "okay" */ if ((lba_sects - chs_sects) < _10_percent) { return 1; /* lba_capacity is good */ @@ -221,6 +233,9 @@ drive->name, rq->sector, (unsigned long) rq->buffer, nsect, rq->nr_sectors - nsect); #endif +#ifdef CONFIG_BLK_DEV_PDC4030 + rq->sector += nsect; +#endif if ((rq->nr_sectors -= nsect) <= 0) break; if ((rq->current_nr_sectors -= nsect) == 0) { @@ -279,7 +294,11 @@ { byte stat = GET_STAT(); +#if 0 + if (OK_STAT(stat,READY_STAT,BAD_STAT) || drive->mult_req == 0) { +#else if (OK_STAT(stat,READY_STAT,BAD_STAT)) { +#endif drive->mult_count = drive->mult_req; } else { drive->mult_req = drive->mult_count = 0; @@ -322,14 +341,21 @@ int use_pdc4030_io = 0; #endif /* CONFIG_BLK_DEV_PDC4030 */ - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); + if (IDE_CONTROL_REG) + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); OUT_BYTE(rq->nr_sectors,IDE_NSECTOR_REG); #ifdef CONFIG_BLK_DEV_PDC4030 +#ifdef CONFIG_BLK_DEV_PDC4030_TESTING + if (IS_PDC4030_DRIVE) { + use_pdc4030_io = 1; + } +#else if (IS_PDC4030_DRIVE) { if (hwif->channel != 0 || rq->cmd == READ) { use_pdc4030_io = 1; } } +#endif /* CONFIG_BLK_DEV_PDC4030_TESTING */ if (drive->select.b.lba || use_pdc4030_io) { #else /* !CONFIG_BLK_DEV_PDC4030 */ if (drive->select.b.lba) { @@ -760,9 +786,12 @@ drive->bios_cyl, drive->bios_head, drive->bios_sect); if (drive->using_dma) { - if ((id->field_valid & 4) && - (id->dma_ultra & (id->dma_ultra >> 8) & 7)) { - printk(", UDMA"); /* UDMA BIOS-enabled! */ + if ((id->field_valid & 4) && (id->word93 & 0x2000) && + (id->dma_ultra & (id->dma_ultra >> 11) & 3)) { + printk(", UDMA(66)"); /* UDMA BIOS-enabled! */ + } else if ((id->field_valid & 4) && + (id->dma_ultra & (id->dma_ultra >> 8) & 7)) { + printk(", UDMA(33)"); /* UDMA BIOS-enabled! */ } else if (id->field_valid & 4) { printk(", (U)DMA"); /* Can be BIOS-enabled! */ } else { @@ -786,17 +815,17 @@ drive->mult_count = 0; if (id->max_multsect) { -#if 1 /* original, pre IDE-NFG, per request of AC */ +#ifdef CONFIG_IDEDISK_MULTI_MODE + id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0; + id->multsect_valid = id->multsect ? 1 : 0; + drive->mult_req = id->multsect_valid ? id->max_multsect : INITIAL_MULT_COUNT; + drive->special.b.set_multmode = drive->mult_req ? 1 : 0; +#else /* original, pre IDE-NFG, per request of AC */ drive->mult_req = INITIAL_MULT_COUNT; if (drive->mult_req > id->max_multsect) drive->mult_req = id->max_multsect; if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect)) drive->special.b.set_multmode = 1; -#else - id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0; - id->multsect_valid = id->multsect ? 1 : 0; - drive->mult_req = id->multsect_valid ? id->max_multsect : INITIAL_MULT_COUNT; - drive->special.b.set_multmode = drive->mult_req ? 1 : 0; #endif } drive->no_io_32bit = id->dword_io ? 1 : 0; diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide-dma.c linux/drivers/block/ide-dma.c --- v2.3.0/linux/drivers/block/ide-dma.c Sun Jan 17 18:23:01 1999 +++ linux/drivers/block/ide-dma.c Thu May 13 11:04:54 1999 @@ -1,5 +1,12 @@ /* - * linux/drivers/block/ide-dma.c Version 4.08 December 31, 1997 + * linux/drivers/block/ide-dma.c Version 4.09 April 23, 1999 + * + * Copyright (c) 1999 Andre Hedrick + * May be copied or modified under the terms of the GNU General Public License + */ + +/* + * Special Thanks to Mark for his Six years of work. * * Copyright (c) 1995-1998 Mark Lord * May be copied or modified under the terms of the GNU General Public License @@ -24,7 +31,7 @@ * * Use "hdparm -i" to view modes supported by a given drive. * - * The hdparm-2.4 (or later) utility can be used for manually enabling/disabling + * The hdparm-3.5 (or later) utility can be used for manually enabling/disabling * DMA support, but must be (re-)compiled against this kernel version or later. * * To enable DMA, use "hdparm -d1 /dev/hd?" on a per-drive basis after booting. @@ -79,11 +86,51 @@ #include #include #include +#include #include #include -#include "ide.h" +#define IDE_DMA_NEW_LISTINGS 0 + +#if IDE_DMA_NEW_LISTINGS +struct drive_list_entry { + char * id_model; + char * id_firmware; +}; + +struct drive_list_entry drive_whitelist [] = { + + { "Micropolis 2112A" , "ALL" }, + { "CONNER CTMA 4000" , "ALL" }, + { "CONNER CTT8000-A" , "ALL" }, + { "ST34342A" , "ALL" }, + { 0 , 0 } +}; + +struct drive_list_entry drive_blacklist [] = { + + { "WDC AC11000H" , "ALL" }, + { "WDC AC22100H" , "ALL" }, + { "WDC AC32500H" , "ALL" }, + { "WDC AC33100H" , "ALL" }, + { "WDC AC31600H" , "ALL" }, + { "WDC AC32100H" , "24.09P07" }, + { "WDC AC23200L" , "21.10N21" }, + { 0 , 0 } + +}; + +int in_drive_list(struct hd_driveid *id, struct drive_list_entry * drive_table) +{ + for ( ; drive_table->id_model ; drive_table++) + if ((!strcmp(drive_table->id_model, id->model)) && + ((!strstr(drive_table->id_firmware, id->fw_rev)) || + (!strcmp(drive_table->id_firmware, "ALL")))) + return 1; + return 0; +} +#else /* !IDE_DMA_NEW_LISTINGS */ /* * good_dma_drives() lists the model names (from "hdparm -i") @@ -109,11 +156,14 @@ */ const char *bad_dma_drives[] = {"WDC AC11000H", "WDC AC22100H", + "WDC AC32100H", "WDC AC32500H", "WDC AC33100H", "WDC AC31600H", NULL}; +#endif /* IDE_DMA_NEW_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 @@ -164,11 +214,12 @@ * Returns 0 if all went okay, returns 1 otherwise. * May also be invoked from trm290.c */ -int ide_build_dmatable (ide_drive_t *drive) +int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func) { struct request *rq = HWGROUP(drive)->rq; struct buffer_head *bh = rq->bh; unsigned int size, addr, *table = (unsigned int *)HWIF(drive)->dmatable; + unsigned char *virt_addr; #ifdef CONFIG_BLK_DEV_TRM290 unsigned int is_trm290_chipset = (HWIF(drive)->chipset == ide_trm290); #else @@ -185,11 +236,13 @@ * than two possibly non-adjacent physical 4kB pages. */ if (bh == NULL) { /* paging requests have (rq->bh == NULL) */ - addr = virt_to_bus (rq->buffer); + virt_addr = rq->buffer; + addr = virt_to_bus (virt_addr); size = rq->nr_sectors << 9; } else { /* group sequential buffers into one large buffer */ - addr = virt_to_bus (bh->b_data); + virt_addr = bh->b_data; + addr = virt_to_bus (virt_addr); size = bh->b_size; while ((bh = bh->b_reqnext) != NULL) { if ((addr + size) != virt_to_bus (bh->b_data)) @@ -206,6 +259,20 @@ printk("%s: misaligned DMA buffer\n", drive->name); return 0; } + + /* + * Some CPUs without cache snooping need to invalidate/write + * back their caches before DMA transfers to guarantee correct + * data. -- rmk + */ + if (size) { + if (func == ide_dma_read) { + dma_cache_inv((unsigned int)virt_addr, size); + } else { + dma_cache_wback((unsigned int)virt_addr, size); + } + } + while (size) { if (++count >= PRD_ENTRIES) { printk("%s: DMA table too small\n", drive->name); @@ -224,10 +291,17 @@ } } } while (bh != NULL); - if (!count) + if (!count) { printk("%s: empty DMA table?\n", drive->name); - else if (!is_trm290_chipset) - *--table |= cpu_to_le32(0x80000000); /* set End-Of-Table (EOT) bit */ + } else { + if (!is_trm290_chipset) + *--table |= cpu_to_le32(0x80000000); /* set End-Of-Table (EOT) bit */ + /* + * Some CPUs need to flush the DMA table to physical RAM + * before DMA can start. -- rmk + */ + dma_cache_wback((unsigned long)HWIF(drive)->dmatable, count * sizeof(unsigned int) * 2); + } return count; } @@ -238,9 +312,22 @@ */ int check_drive_lists (ide_drive_t *drive, int good_bad) { - const char **list; struct hd_driveid *id = drive->id; +#if IDE_DMA_NEW_LISTINGS + + if (good_bad) { + return in_drive_list(id, drive_whitelist); + } else { + int blacklist = in_drive_list(id, drive_blacklist); + if (blacklist) + printk("%s: Disabling (U)DMA for %s\n", drive->name, id->model); + return(blacklist); + } +#else /* !IDE_DMA_NEW_LISTINGS */ + + const char **list; + if (good_bad) { /* Consult the list of known "good" drives */ list = good_dma_drives; @@ -259,6 +346,7 @@ } } } +#endif /* IDE_DMA_NEW_LISTINGS */ return 0; } @@ -269,18 +357,24 @@ if (id && (id->capability & 1) && hwif->autodma) { /* Consult the list of known "bad" drives */ - if (check_drive_lists(drive, BAD_DMA_DRIVE)) + if (ide_dmaproc(ide_dma_bad_drive, drive)) return hwif->dmaproc(ide_dma_off, drive); +#if 0 + /* Enable DMA on any drive that has UltraDMA (mode 3/4) enabled */ + if ((id->field_valid & 4) && (id->word93 & 0x2000)) + if ((id->dma_ultra & (id->dma_ultra >> 11) & 3)) + return hwif->dmaproc(ide_dma_on, drive); +#endif /* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */ if (id->field_valid & 4) /* UltraDMA */ - if ((id->dma_ultra & (id->dma_ultra >> 8) & 7)) + if ((id->dma_ultra & (id->dma_ultra >> 8) & 7)) return hwif->dmaproc(ide_dma_on, drive); /* Enable DMA on any drive that has mode2 DMA (multi or single) enabled */ if (id->field_valid & 2) /* regular DMA */ if ((id->dma_mword & 0x404) == 0x404 || (id->dma_1word & 0x404) == 0x404) return hwif->dmaproc(ide_dma_on, drive); /* Consult the list of known "good" drives */ - if (check_drive_lists(drive, GOOD_DMA_DRIVE)) + if (ide_dmaproc(ide_dma_good_drive, drive)) return hwif->dmaproc(ide_dma_on, drive); } return hwif->dmaproc(ide_dma_off_quietly, drive); @@ -321,7 +415,7 @@ case ide_dma_read: reading = 1 << 3; case ide_dma_write: - if (!(count = ide_build_dmatable(drive))) + if (!(count = ide_build_dmatable(drive, func))) return 1; /* try PIO instead of DMA */ outl(virt_to_bus(hwif->dmatable), dma_base + 4); /* PRD table */ outb(reading, dma_base); /* specify r/w */ @@ -348,6 +442,9 @@ case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ dma_stat = inb(dma_base+2); return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ + case ide_dma_bad_drive: + case ide_dma_good_drive: + return check_drive_lists(drive, (func == ide_dma_good_drive)); default: printk("ide_dmaproc: unsupported func: %d\n", func); return 1; @@ -425,7 +522,7 @@ } else { dma_base = dev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK; if (!dma_base || dma_base == PCI_BASE_ADDRESS_IO_MASK) { - printk("%s: dma_base is invalid (0x%04lx, BIOS problem), please report to \n", name, dma_base); + printk("%s: dma_base is invalid (0x%04lx)\n", name, dma_base); dma_base = 0; } } @@ -434,9 +531,29 @@ request_region(dma_base+16, extra, name); dma_base += hwif->channel ? 8 : 0; hwif->dma_extra = extra; - if (inb(dma_base+2) & 0x80) { - printk("%s: simplex device: DMA disabled\n", name); - dma_base = 0; + + switch(dev->device) { + case PCI_DEVICE_ID_CMD_643: + /* + * Lets attempt to use the same Ali tricks + * to fix CMD643..... + */ + case PCI_DEVICE_ID_AL_M5219: + case PCI_DEVICE_ID_AL_M5229: + outb(inb(dma_base+2) & 0x60, dma_base+2); + /* + * Ali 15x3 chipsets know as ALI IV and V report + * this as simplex, skip this test for them. + */ + if (inb(dma_base+2) & 0x80) { + printk("%s: simplex device: DMA forced\n", name); + } + break; + default: + if (inb(dma_base+2) & 0x80) { + printk("%s: simplex device: DMA disabled\n", name); + dma_base = 0; + } } } return dma_base; diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c --- v2.3.0/linux/drivers/block/ide-floppy.c Wed Dec 23 07:54:22 1998 +++ linux/drivers/block/ide-floppy.c Thu May 13 11:04:54 1999 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -53,11 +54,6 @@ #include /* - * Main Linux ide driver include file - */ -#include "ide.h" - -/* * The following are used to debug the driver. */ #define IDEFLOPPY_DEBUG_LOG 0 @@ -1011,7 +1007,8 @@ dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive); #endif /* CONFIG_BLK_DEV_IDEDMA */ - OUT_BYTE (drive->ctl,IDE_CONTROL_REG); + if (IDE_CONTROL_REG) + OUT_BYTE (drive->ctl,IDE_CONTROL_REG); OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */ OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG); OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG); diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide-pci.c linux/drivers/block/ide-pci.c --- v2.3.0/linux/drivers/block/ide-pci.c Sun Jan 24 21:54:35 1999 +++ linux/drivers/block/ide-pci.c Thu May 13 11:04:54 1999 @@ -1,5 +1,7 @@ /* - * linux/drivers/block/ide-pci.c Version 1.02 December 29, 1997 + * linux/drivers/block/ide-pci.c Version 1.03 May 1, 1999 + * + * Copyright (c) 1998-1999 Andre Hedrick * * Copyright (c) 1995-1998 Mark Lord * May be copied or modified under the terms of the GNU General Public License @@ -18,26 +20,28 @@ #include #include #include +#include #include #include -#include "ide.h" - #define DEVID_PIIXa ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0}) #define DEVID_PIIXb ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1}) #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_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1}) #define DEVID_PDC20246 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246}) +#define DEVID_PDC20262 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262}) #define DEVID_RZ1000 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000}) #define DEVID_RZ1001 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001}) +#define DEVID_SAMURAI ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE}) #define DEVID_CMD640 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640}) +#define DEVID_CMD643 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643}) #define DEVID_CMD646 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646}) #define DEVID_SIS5513 ((ide_pci_devid_t){PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513}) #define DEVID_OPTI621 ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621}) #define DEVID_OPTI621V ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558}) -#define DEVID_OPTI621X ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, 0xd568}) /* from datasheets */ +#define DEVID_OPTI621X ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C825}) #define DEVID_TRM290 ((ide_pci_devid_t){PCI_VENDOR_ID_TEKRAM, PCI_DEVICE_ID_TEKRAM_DC290}) #define DEVID_NS87410 ((ide_pci_devid_t){PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410}) #define DEVID_NS87415 ((ide_pci_devid_t){PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415}) @@ -47,6 +51,10 @@ #define DEVID_UM8886A ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A}) #define DEVID_UM8886BF ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF}) #define DEVID_HPT343 ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343}) +#define DEVID_ALI15X3 ((ide_pci_devid_t){PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229}) +#define DEVID_CY82C693 ((ide_pci_devid_t){PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693}) +#define DEVID_HINT ((ide_pci_devid_t){0x3388, 0x8013}) +#define DEVID_CX5530 ((ide_pci_devid_t){PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE}) #define IDE_IGNORE ((void *)-1) @@ -98,11 +106,68 @@ #ifdef CONFIG_BLK_DEV_VIA82C586 extern void ide_init_via82c586(ide_hwif_t *); +extern void ide_dmacapable_via82c586(ide_hwif_t *, unsigned long dmabase); #define INIT_VIA82C586 &ide_init_via82c586 +#define DMA_VIA82C586 &ide_dmacapable_via82c586 #else #define INIT_VIA82C586 NULL +#define DMA_VIA82C586 NULL +#endif + +#ifdef CONFIG_BLK_DEV_ALI15X3 +extern unsigned int pci_init_ali15x3(struct pci_dev *, const char *); +extern void ide_init_ali15x3(ide_hwif_t *); +#define PCI_ALI15X3 &pci_init_ali15x3 +#define INIT_ALI15X3 &ide_init_ali15x3 +#else +#define PCI_ALI15X3 NULL +#define INIT_ALI15X3 NULL +#endif + +#ifdef CONFIG_BLK_DEV_CY82C693 +extern void ide_init_cy82c693(ide_hwif_t *); +#define INIT_CY82C693 &ide_init_cy82c693 +#else +#define INIT_CY82C693 NULL +#endif + +#ifdef CONFIG_BLK_DEV_PDC202XX +extern unsigned int pci_init_pdc202xx(struct pci_dev *, const char *); +extern void ide_init_pdc202xx(ide_hwif_t *); +#define PCI_PDC202XX &pci_init_pdc202xx +#define INIT_PDC202XX &ide_init_pdc202xx +#else +#define PCI_PDC202XX NULL +#define INIT_PDC202XX NULL +#endif + +#ifdef CONFIG_BLK_DEV_PIIX +extern void ide_init_piix(ide_hwif_t *); +#define INIT_PIIX &ide_init_piix +#else +#define INIT_PIIX NULL +#endif + +#ifdef CONFIG_BLK_DEV_AEC6210 +extern unsigned int pci_init_aec6210(struct pci_dev *, const char *); +#define PCI_AEC6210 &pci_init_aec6210 +#else +#define PCI_AEC6210 NULL +#endif + +#ifdef CONFIG_BLK_DEV_HPT343 +extern unsigned int pci_init_hpt343(struct pci_dev *, const char *); +extern void ide_init_hpt343(ide_hwif_t *); +#define PCI_HPT343 &pci_init_hpt343 +#define INIT_HPT343 &ide_init_hpt343 +#else +#define PCI_HPT343 NULL +#define INIT_HPT343 NULL #endif +#define INIT_SAMURAI NULL +#define INIT_CX5530 NULL + typedef struct ide_pci_enablebit_s { byte reg; /* byte pci reg holding the enable-bit */ byte mask; /* mask to isolate the enable-bit */ @@ -112,36 +177,45 @@ typedef struct ide_pci_device_s { ide_pci_devid_t devid; const char *name; + unsigned int (*init_chipset)(struct pci_dev *dev, const char *name); void (*init_hwif)(ide_hwif_t *hwif); + void (*dma_init)(ide_hwif_t *hwif, unsigned long dmabase); ide_pci_enablebit_t enablebits[2]; byte bootable; unsigned int extra; } ide_pci_device_t; static ide_pci_device_t ide_pci_chipsets[] __initdata = { - {DEVID_PIIXa, "PIIX", NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, - {DEVID_PIIXb, "PIIX", NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, - {DEVID_PIIX3, "PIIX3", NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, - {DEVID_PIIX4, "PIIX4", NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, - {DEVID_VP_IDE, "VP_IDE", INIT_VIA82C586, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, - {DEVID_PDC20246,"PDC20246", NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 }, - {DEVID_RZ1000, "RZ1000", INIT_RZ1000, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, - {DEVID_RZ1001, "RZ1001", INIT_RZ1000, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, - {DEVID_CMD640, "CMD640", IDE_IGNORE, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, - {DEVID_NS87410, "NS87410", NULL, {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, ON_BOARD, 0 }, - {DEVID_SIS5513, "SIS5513", NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, ON_BOARD, 0 }, - {DEVID_CMD646, "CMD646", INIT_CMD646, {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, ON_BOARD, 0 }, - {DEVID_HT6565, "HT6565", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, - {DEVID_OPTI621, "OPTI621", INIT_OPTI621, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, - {DEVID_OPTI621X,"OPTI621X", INIT_OPTI621, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, - {DEVID_TRM290, "TRM290", INIT_TRM290, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, - {DEVID_NS87415, "NS87415", INIT_NS87415, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, - {DEVID_AEC6210, "AEC6210", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, - {DEVID_W82C105, "W82C105", INIT_W82C105, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 }, - {DEVID_UM8886A, "UM8886A", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, - {DEVID_UM8886BF,"UM8886BF", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, - {DEVID_HPT343, "HPT343", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 16 }, - {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }}; + {DEVID_PIIXa, "PIIX", NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_PIIXb, "PIIX", NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_PIIX3, "PIIX3", NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_PIIX4, "PIIX4", NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_VP_IDE, "VP_IDE", NULL, INIT_VIA82C586, DMA_VIA82C586, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, + {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 }, + {DEVID_PDC20262,"PDC20262", PCI_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, + {DEVID_RZ1000, "RZ1000", NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_RZ1001, "RZ1001", NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_SAMURAI, "SAMURAI", NULL, INIT_SAMURAI, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_CMD640, "CMD640", NULL, IDE_IGNORE, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_NS87410, "NS87410", NULL, NULL, NULL, {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, ON_BOARD, 0 }, + {DEVID_SIS5513, "SIS5513", NULL, NULL, NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, ON_BOARD, 0 }, + {DEVID_CMD643, "CMD643", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_CMD646, "CMD646", NULL, INIT_CMD646, NULL, {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_HT6565, "HT6565", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_OPTI621, "OPTI621", NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, + {DEVID_OPTI621X,"OPTI621X", NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, + {DEVID_TRM290, "TRM290", NULL, INIT_TRM290, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_NS87415, "NS87415", NULL, INIT_NS87415, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_AEC6210, "AEC6210", PCI_AEC6210, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, + {DEVID_W82C105, "W82C105", NULL, INIT_W82C105, NULL, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 }, + {DEVID_UM8886A, "UM8886A", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_UM8886BF,"UM8886BF", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_HPT343, "HPT343", PCI_HPT343, INIT_HPT343, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 16 }, + {DEVID_ALI15X3, "ALI15X3", PCI_ALI15X3, INIT_ALI15X3, NULL, {{0x09,0x20,0x20}, {0x09,0x10,0x10}}, ON_BOARD, 0 }, + {DEVID_CY82C693,"CY82C693", NULL, INIT_CY82C693, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_HINT, "HINT_IDE", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_CX5530, "CX5530", NULL, INIT_CX5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }}; /* * This allows offboard ide-pci cards the enable a BIOS, verify interrupt @@ -151,27 +225,28 @@ __initfunc(static unsigned int ide_special_settings (struct pci_dev *dev, const char *name)) { switch(dev->device) { - case PCI_DEVICE_ID_ARTOP_ATP850UF: - case PCI_DEVICE_ID_PROMISE_20246: - if (dev->rom_address) { - pci_write_config_byte(dev, PCI_ROM_ADDRESS, - dev->rom_address | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->rom_address); - } - - if ((dev->class >> 8) == PCI_CLASS_STORAGE_RAID) { - unsigned char irq1 = 0, irq2 = 0; - - pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq1); - pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); /* 0xbc */ - if (irq1 != irq2) { - printk("%s: IRQ1 %d IRQ2 %d\n", - name, irq1, irq2); - pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq1); /* 0xbc */ - } - } - return dev->irq; case PCI_DEVICE_ID_TTI_HPT343: + { + int i; + unsigned short pcicmd = 0; + unsigned long hpt343IoBase = dev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK; + + pci_write_config_byte(dev, 0x80, 0x00); + dev->base_address[0] = (hpt343IoBase + 0x20); + dev->base_address[1] = (hpt343IoBase + 0x34); + dev->base_address[2] = (hpt343IoBase + 0x28); + dev->base_address[3] = (hpt343IoBase + 0x3c); + for(i=0; i<4; i++) + dev->base_address[i] |= PCI_BASE_ADDRESS_SPACE_IO; + + pci_read_config_word(dev, PCI_COMMAND, &pcicmd); + pci_write_config_byte(dev, 0x80, 0x80); + if (!(pcicmd & PCI_COMMAND_MEMORY)) + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); + } + case PCI_DEVICE_ID_PROMISE_20246: + case PCI_DEVICE_ID_PROMISE_20262: + case PCI_DEVICE_ID_ARTOP_ATP850UF: return dev->irq; default: break; @@ -269,7 +344,7 @@ */ for (reg = 0; reg < 4; reg++) if (!dev->base_address[reg]) { - printk("%s: Missing I/O address #%d, please report to \n", name, reg); + printk("%s: Missing I/O address #%d\n", name, reg); return 1; } return 0; @@ -325,7 +400,13 @@ pciirq = dev->irq; if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) { printk("%s: not 100%% native mode: will probe irqs later\n", d->name); - pciirq = ide_special_settings(dev, d->name); + /* + * This allows offboard ide-pci cards the enable a BIOS, + * verify interrupt settings of split-mirror pci-config + * space, place chipset into init-mode, and/or preserve + * an interrupt if the card is not native ide support. + */ + pciirq = (d->init_chipset) ? d->init_chipset(dev, d->name) : ide_special_settings(dev, d->name); } else if (tried_config) { printk("%s: will probe irqs later\n", d->name); pciirq = 0; @@ -340,6 +421,19 @@ printk("%s: 100%% native mode on irq %d\n", d->name, pciirq); #endif } + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT343)) { + /* + * Since there are two cards that report almost identically, + * the only discernable difference is the values + * reported in pcicmd. + * Booting-BIOS card or HPT363 :: pcicmd == 0x07 + * Non-bootable card or HPT343 :: pcicmd == 0x05 + */ + if (pcicmd & PCI_COMMAND_MEMORY) { + printk("%s: is IDE Express HPT363.\n", d->name); + d->bootable = OFF_BOARD; + } + } /* * Set up the IDE ports */ @@ -363,8 +457,8 @@ if ((hwif = ide_match_hwif(base, d->bootable, d->name)) == NULL) continue; /* no room in ide_hwifs[] */ if (hwif->io_ports[IDE_DATA_OFFSET] != base) { - ide_init_hwif_ports(hwif->io_ports, base, NULL); - hwif->io_ports[IDE_CONTROL_OFFSET] = ctl + 2; + ide_init_hwif_ports(&hwif->hw, base, (ctl + 2), NULL); + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; } hwif->chipset = ide_pci; @@ -382,8 +476,10 @@ } } if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) || - IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886BF)) + IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886BF)) { hwif->irq = hwif->channel ? 15 : 14; + goto bypass_umc_dma; + } #ifdef CONFIG_BLK_DEV_IDEDMA if (IDE_PCI_DEVID_EQ(d->devid, DEVID_SIS5513)) @@ -391,8 +487,12 @@ if (autodma) hwif->autodma = 1; if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) || +#ifdef CONFIG_BLK_DEV_HPT343 IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT343) || +#endif + IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) { unsigned long dma_base = ide_get_or_set_dma_base(hwif, (!mate && d->extra) ? d->extra : 0, d->name); if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) { @@ -406,12 +506,18 @@ dma_base = 0; } } - if (dma_base) - ide_setup_dma(hwif, dma_base, 8); - else + if (dma_base) { + if (d->dma_init) { + d->dma_init(hwif, dma_base); + } else { + ide_setup_dma(hwif, dma_base, 8); + } + } else { printk("%s: %s Bus-Master DMA disabled (BIOS)\n", hwif->name, d->name); + } } #endif /* CONFIG_BLK_DEV_IDEDMA */ +bypass_umc_dma: if (d->init_hwif) /* Call chipset-specific routine for each enabled hwif */ d->init_hwif(hwif); mate = hwif; @@ -441,6 +547,8 @@ printk("%s: ignored by ide_scan_pci_device() (uses own driver)\n", d->name); else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_OPTI621V) && !(PCI_FUNC(dev->devfn) & 1)) continue; /* OPTI Viper-M uses same devid for functions 0 and 1 */ + else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))) + continue; /* CY82C693 is more than only a IDE controller */ 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", diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide-pmac.c linux/drivers/block/ide-pmac.c --- v2.3.0/linux/drivers/block/ide-pmac.c Wed Mar 10 21:48:46 1999 +++ linux/drivers/block/ide-pmac.c Thu May 13 11:04:54 1999 @@ -21,6 +21,8 @@ #include #include #include +#include + #include #include #include @@ -31,9 +33,9 @@ #include #include #endif -#include "ide.h" #include "ide_modes.h" +int pmac_ide_ports_known; ide_ioreg_t pmac_ide_regbase[MAX_HWIFS]; int pmac_ide_irq[MAX_HWIFS]; int pmac_ide_count; @@ -58,24 +60,32 @@ * N.B. this can't be an initfunc, because the media-bay task can * call ide_[un]register at any time. */ -void -pmac_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq) +void pmac_ide_init_hwif_ports ( hw_regs_t *hw, + ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, + int *irq) { + ide_ioreg_t reg = ide_ioreg_t data_port; int i, r; - *p = 0; - if (base == 0) + if (data_port == 0) return; /* we check only for -EINVAL meaning that we have found a matching bay but with the wrong device type */ - r = check_media_bay_by_base(base, MB_CD); + r = check_media_bay_by_base(data_port, MB_CD); if (r == -EINVAL) return; - for (i = 0; i < 8; ++i) - *p++ = base + i * 0x10; - *p = base + 0x160; + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg * 0x10; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x160; + } if (irq != NULL) { *irq = 0; for (i = 0; i < MAX_HWIFS; ++i) { @@ -104,8 +114,7 @@ } } -__initfunc(void -pmac_ide_probe(void)) +__initfunc(void pmac_ide_probe(void)) { struct device_node *np; int i; @@ -172,7 +181,8 @@ feature_set(np, FEATURE_IDE_enable); hwif = &ide_hwifs[i]; - pmac_ide_init_hwif_ports(hwif->io_ports, base, &hwif->irq); + pmac_ide_init_hwif_ports(&hwif->hw, base, 0, &hwif->irq); + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->chipset = ide_generic; hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; hwif->tuneproc = pmac_ide_tuneproc; diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c --- v2.3.0/linux/drivers/block/ide-probe.c Mon Mar 22 12:44:18 1999 +++ linux/drivers/block/ide-probe.c Thu May 13 11:04:54 1999 @@ -18,6 +18,8 @@ * by Andrea Arcangeli * Version 1.03 fix for (hwif->chipset == ide_4drives) * Version 1.04 fixed buggy treatments of known flash memory cards + * fix for (hwif->chipset == ide_pdc4030) + * added ide6/7 */ #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -35,14 +37,14 @@ #include #include #include +#include + #include #include #include #include -#include "ide.h" - static inline void do_identify (ide_drive_t *drive, byte cmd) { int bswap = 1; @@ -148,17 +150,6 @@ } /* - * Delay for *at least* 50ms. As we don't know how much time is left - * until the next tick occurs, we wait an extra tick to be safe. - * This is used only during the probing/polling for drives at boot time. - */ -static void delay_50ms (void) -{ - unsigned long timeout = jiffies + ((HZ + 19)/20) + 1; - while (0 < (signed long)(timeout - jiffies)); -} - -/* * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive * and waits for a response. It also monitors irqs while this is * happening, in hope of automatically determining which one is @@ -176,20 +167,26 @@ unsigned long irqs = 0; byte s, a; - if (!HWIF(drive)->irq) { /* already got an IRQ? */ - probe_irq_off(probe_irq_on()); /* clear dangling irqs */ - irqs = probe_irq_on(); /* start monitoring irqs */ - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */ - } + if (IDE_CONTROL_REG) { + if (!HWIF(drive)->irq) { /* already got an IRQ? */ + probe_irq_off(probe_irq_on()); /* clear dangling irqs */ + irqs = probe_irq_on(); /* start monitoring irqs */ + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */ + } - delay_50ms(); /* take a deep breath */ - a = IN_BYTE(IDE_ALTSTATUS_REG); - s = IN_BYTE(IDE_STATUS_REG); - if ((a ^ s) & ~INDEX_STAT) { - printk("%s: probing with STATUS(0x%02x) instead of ALTSTATUS(0x%02x)\n", drive->name, s, a); - hd_status = IDE_STATUS_REG; /* ancient Seagate drives, broken interfaces */ - } else - hd_status = IDE_ALTSTATUS_REG; /* use non-intrusive polling */ + ide_delay_50ms(); /* take a deep breath */ + a = IN_BYTE(IDE_ALTSTATUS_REG); + s = IN_BYTE(IDE_STATUS_REG); + if ((a ^ s) & ~INDEX_STAT) { + printk("%s: probing with STATUS(0x%02x) instead of ALTSTATUS(0x%02x)\n", drive->name, s, a); + hd_status = IDE_STATUS_REG; /* ancient Seagate drives, broken interfaces */ + } else { + hd_status = IDE_ALTSTATUS_REG; /* use non-intrusive polling */ + } + } else { + ide_delay_50ms(); + hd_status = IDE_STATUS_REG; + } #if CONFIG_BLK_DEV_PDC4030 if (IS_PDC4030_DRIVE) { @@ -210,10 +207,10 @@ (void) probe_irq_off(irqs); return 1; /* drive timed-out */ } - delay_50ms(); /* give drive a breather */ + ide_delay_50ms(); /* give drive a breather */ } while (IN_BYTE(hd_status) & BUSY_STAT); - delay_50ms(); /* wait for IRQ and DRQ_STAT */ + ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */ if (OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) { unsigned long flags; __save_flags(flags); /* local CPU only */ @@ -224,7 +221,7 @@ __restore_flags(flags); /* local CPU only */ } else rc = 2; /* drive refused ID */ - if (!HWIF(drive)->irq) { + if (IDE_CONTROL_REG && !HWIF(drive)->irq) { irqs = probe_irq_off(irqs); /* get our irq number */ if (irqs > 0) { HWIF(drive)->irq = irqs; /* save it for later */ @@ -280,11 +277,11 @@ (cmd == WIN_IDENTIFY) ? "ATA" : "ATAPI"); #endif SELECT_DRIVE(hwif,drive); - delay_50ms(); + ide_delay_50ms(); if (IN_BYTE(IDE_SELECT_REG) != drive->select.all && !drive->present) { if (drive->select.b.unit != 0) { SELECT_DRIVE(hwif,&hwif->drives[0]); /* exit with drive0 selected */ - delay_50ms(); /* allow BUSY_STAT to assert & clear */ + ide_delay_50ms(); /* allow BUSY_STAT to assert & clear */ } return 3; /* no i/f present: mmm.. this should be a 4 -ml */ } @@ -297,13 +294,13 @@ if (rc == 1 && cmd == WIN_PIDENTIFY && drive->autotune != 2) { unsigned long timeout; printk("%s: no response (status = 0x%02x), resetting drive\n", drive->name, GET_STAT()); - delay_50ms(); + ide_delay_50ms(); OUT_BYTE (drive->select.all, IDE_SELECT_REG); - delay_50ms(); + ide_delay_50ms(); OUT_BYTE(WIN_SRST, IDE_COMMAND_REG); timeout = jiffies; while ((GET_STAT() & BUSY_STAT) && time_before(jiffies, timeout + WAIT_WORSTCASE)) - delay_50ms(); + ide_delay_50ms(); rc = try_to_identify(drive, cmd); } if (rc == 1) @@ -314,7 +311,7 @@ } if (drive->select.b.unit != 0) { SELECT_DRIVE(hwif,&hwif->drives[0]); /* exit with drive0 selected */ - delay_50ms(); + ide_delay_50ms(); (void) GET_STAT(); /* ensure drive irq is clear */ } return rc; @@ -407,15 +404,40 @@ unsigned int unit; unsigned long flags; + ide_ioreg_t ide_control_reg = hwif->io_ports[IDE_CONTROL_OFFSET]; + ide_ioreg_t region_low = hwif->io_ports[IDE_DATA_OFFSET]; + ide_ioreg_t region_high = region_low; + ide_ioreg_t region_request = 8; + int i; + if (hwif->noprobe) return; if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) probe_cmos_for_drives (hwif); - if ((hwif->chipset != ide_4drives || !hwif->mate->present) + + /* + * Calculate the region that this interface occupies, + * handling interfaces where the registers may not be + * ordered sanely. We deal with the CONTROL register + * separately. + */ + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + if (hwif->io_ports[i]) { + if (hwif->io_ports[i] < region_low) + region_low = hwif->io_ports[i]; + if (hwif->io_ports[i] > region_high) + region_high = hwif->io_ports[i]; + } + } + region_request = (region_high - region_low); + if (region_request == 0x0007) + region_request++; + if ((hwif->chipset != ide_4drives || !hwif->mate->present) && #if CONFIG_BLK_DEV_PDC4030 - && (hwif->chipset != ide_pdc4030 || hwif->channel == 0) + (hwif->chipset != ide_pdc4030 || hwif->channel == 0) && #endif /* CONFIG_BLK_DEV_PDC4030 */ - && (ide_check_region(hwif->io_ports[IDE_DATA_OFFSET],8) || ide_check_region(hwif->io_ports[IDE_CONTROL_OFFSET],1))) + (ide_check_region(region_low, region_request) || + (ide_control_reg && ide_check_region(ide_control_reg,1)))) { int msgout = 0; for (unit = 0; unit < MAX_DRIVES; ++unit) { @@ -443,21 +465,22 @@ if (drive->present && !hwif->present) { hwif->present = 1; if (hwif->chipset != ide_4drives || !hwif->mate->present) { - ide_request_region(hwif->io_ports[IDE_DATA_OFFSET], 8, hwif->name); - ide_request_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1, hwif->name); + ide_request_region(region_low, region_request, hwif->name); + if (ide_control_reg) + ide_request_region(ide_control_reg, 1, hwif->name); } } } - if (hwif->reset) { + if (ide_control_reg && hwif->reset) { unsigned long timeout = jiffies + WAIT_WORSTCASE; byte stat; printk("%s: reset\n", hwif->name); - OUT_BYTE(12, hwif->io_ports[IDE_CONTROL_OFFSET]); + OUT_BYTE(12, ide_control_reg); udelay(10); - OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]); + OUT_BYTE(8, ide_control_reg); do { - delay_50ms(); + ide_delay_50ms(); stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); } while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies)); @@ -660,7 +683,11 @@ 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 : MAX_SECTORS); +#else *max_sect++ = MAX_SECTORS; +#endif *max_ra++ = MAX_READAHEAD; } @@ -693,7 +720,8 @@ if (!hwif->present) return 0; if (!hwif->irq) { - if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) { + if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) + { printk("%s: DISABLED, NO IRQ\n", hwif->name); return (hwif->present = 0); } @@ -722,6 +750,12 @@ #endif #if MAX_HWIFS > 5 case IDE5_MAJOR: rfn = &do_ide5_request; break; +#endif +#if MAX_HWIFS > 6 + case IDE6_MAJOR: rfn = &do_ide6_request; break; +#endif +#if MAX_HWIFS > 7 + case IDE7_MAJOR: rfn = &do_ide7_request; break; #endif default: printk("%s: request_fn NOT DEFINED\n", hwif->name); diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide-proc.c linux/drivers/block/ide-proc.c --- v2.3.0/linux/drivers/block/ide-proc.c Wed May 6 14:42:53 1998 +++ linux/drivers/block/ide-proc.c Thu May 13 11:04:54 1999 @@ -65,13 +65,22 @@ #include #include #include +#include + #include -#include "ide.h" #ifndef MIN #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif +#ifdef CONFIG_BLK_DEV_VIA82C586 +int (*via_display_info)(char *, char **, off_t, int, int) = NULL; +#endif /* CONFIG_BLK_DEV_VIA82C586 */ + +#ifdef CONFIG_BLK_DEV_ALI15X3 +int (*ali_display_info)(char *, char **, off_t, int, int) = NULL; +#endif /* CONFIG_BLK_DEV_ALI15X3 */ + static int ide_getxdigit(char c) { int digit; @@ -682,6 +691,18 @@ ent = create_proc_entry("drivers", 0, root); if (!ent) return; ent->read_proc = proc_ide_read_drivers; +#ifdef CONFIG_BLK_DEV_VIA82C586 + if (via_display_info) { + ent = create_proc_entry("via", 0, root); + ent->get_info = via_display_info; + } +#endif /* CONFIG_BLK_DEV_VIA82C586 */ +#ifdef CONFIG_BLK_DEV_ALI15X3 + if (ali_display_info) { + ent = create_proc_entry("ali", 0, root); + ent->get_info = ali_display_info; + } +#endif /* CONFIG_BLK_DEV_ALI15X3 */ } void proc_ide_destroy(void) @@ -690,6 +711,14 @@ * Mmmm.. does this free up all resources, * or do we need to do a more proper cleanup here ?? */ +#ifdef CONFIG_BLK_DEV_VIA82C586 + if (via_display_info) + remove_proc_entry("ide/via",0); +#endif /* CONFIG_BLK_DEV_VIA82C586 */ +#ifdef CONFIG_BLK_DEV_ALI15X3 + if (ali_display_info) + remove_proc_entry("ide/ali",0); +#endif /* CONFIG_BLK_DEV_ALI15X3 */ remove_proc_entry("ide/drivers", 0); remove_proc_entry("ide", 0); } diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c --- v2.3.0/linux/drivers/block/ide-tape.c Fri Jan 8 10:04:58 1999 +++ linux/drivers/block/ide-tape.c Thu May 13 11:04:54 1999 @@ -338,6 +338,8 @@ #include #include #include +#include +#include #include #include @@ -347,11 +349,6 @@ #include /* - * Main Linux ide driver include file - */ -#include "ide.h" - -/* * For general magnetic tape device compatibility. */ #include @@ -401,6 +398,7 @@ /* * The following are used to debug the driver: * + * Setting IDETAPE_INFO_LOG to 1 will log driver vender information. * Setting IDETAPE_DEBUG_LOG to 1 will log driver flow control. * Setting IDETAPE_DEBUG_BUGS to 1 will enable self-sanity checks in * some places. @@ -415,9 +413,15 @@ * is verified to be stable enough. This will make it much more * esthetic. */ +#define IDETAPE_INFO_LOG 0 #define IDETAPE_DEBUG_LOG 0 #define IDETAPE_DEBUG_BUGS 1 +#if IDETAPE_DEBUG_LOG +#undef IDETAPE_INFO_LOG +#define IDETAPE_INFO_LOG IDETAPE_DEBUG_LOG +#endif + /* * After each failed packet command we issue a request sense command * and retry the packet command IDETAPE_MAX_PC_RETRIES times. @@ -1968,7 +1972,8 @@ dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive); #endif /* CONFIG_BLK_DEV_IDEDMA */ - OUT_BYTE (drive->ctl,IDE_CONTROL_REG); + if (IDE_CONTROL_REG) + OUT_BYTE (drive->ctl,IDE_CONTROL_REG); OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */ OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG); OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG); @@ -2334,7 +2339,7 @@ */ static void idetape_wait_for_request (ide_drive_t *drive, struct request *rq) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); #if IDETAPE_DEBUG_BUGS if (rq == NULL || !IDETAPE_RQ_CMD (rq->cmd)) { @@ -3337,16 +3342,16 @@ static int idetape_identify_device (ide_drive_t *drive,struct hd_driveid *id) { struct idetape_id_gcw gcw; -#if IDETAPE_DEBUG_LOG +#if IDETAPE_INFO_LOG unsigned short mask,i; -#endif /* IDETAPE_DEBUG_LOG */ +#endif /* IDETAPE_INFO_LOG */ if (!id) return 0; *((unsigned short *) &gcw) = id->config; -#if IDETAPE_DEBUG_LOG +#if IDETAPE_INFO_LOG printk (KERN_INFO "Dumping ATAPI Identify Device tape parameters\n"); printk (KERN_INFO "Protocol Type: "); switch (gcw.protocol) { @@ -3434,7 +3439,7 @@ } else printk (KERN_INFO "According to the device, fields 64-70 are not valid.\n"); -#endif /* IDETAPE_DEBUG_LOG */ +#endif /* IDETAPE_INFO_LOG */ /* Check that we can support this device */ @@ -3491,7 +3496,7 @@ tape->capabilities = *capabilities; /* Save us a copy */ tape->tape_block_size = capabilities->blk512 ? 512:1024; -#if IDETAPE_DEBUG_LOG +#if IDETAPE_INFO_LOG printk (KERN_INFO "Dumping the results of the MODE SENSE packet command\n"); printk (KERN_INFO "Mode Parameter Header:\n"); printk (KERN_INFO "Mode Data Length - %d\n",header->mode_data_length); @@ -3519,7 +3524,7 @@ printk (KERN_INFO "Continuous transfer limits in blocks - %d\n",capabilities->ctl); printk (KERN_INFO "Current speed in KBps - %d\n",capabilities->speed); printk (KERN_INFO "Buffer size - %d\n",capabilities->buffer_size*512); -#endif /* IDETAPE_DEBUG_LOG */ +#endif /* IDETAPE_INFO_LOG */ } static void idetape_add_settings(ide_drive_t *drive) @@ -3561,7 +3566,18 @@ drive->driver_data = tape; drive->ready_stat = 0; /* An ATAPI device ignores DRDY */ - drive->dsc_overlap = 1; +#ifdef CONFIG_BLK_DEV_IDEPCI + /* + * These two ide-pci host adapters appear to need this disabled. + */ + if ((hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) || + (hwif->pci_dev->device == PCI_DEVICE_ID_TTI_HPT343)) { + drive->dsc_overlap = 0; + } else +#endif /* CONFIG_BLK_DEV_IDEPCI */ + { + drive->dsc_overlap = 1; + } memset (tape, 0, sizeof (idetape_tape_t)); tape->drive = drive; tape->minor = minor; diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.3.0/linux/drivers/block/ide.c Mon May 3 09:34:51 1999 +++ linux/drivers/block/ide.c Thu May 13 11:31:31 1999 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide.c Version 6.18 August 16, 1998 + * linux/drivers/block/ide.c Version 6.19 January 29, 1999 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ @@ -92,6 +92,11 @@ * Version 6.16 fixed various bugs; even more SMP friendly * Version 6.17 fix for newest EZ-Drive problem * Version 6.18 default unpartitioned-disk translation now "BIOS LBA" + * Version 6.19 Re-design for a UNIFORM driver for all platforms, + * model based on suggestions from Russell King and + * Geert Uytterhoeven + * Promise DC4030VL now supported. + * delay_50ms() changed to ide_delay_50ms() and exported. * * Some additional driver compile-time options are in ide.h * @@ -99,6 +104,9 @@ * - modify kernel to obtain BIOS geometry for drives on 2nd/3rd/4th i/f */ +#define REVISION "Revision: 6.19" +#define VERSION "Id: ide.c 6.19 1999/01/29" + #undef REALLY_SLOW_IO /* most systems can safely undef this */ #define _IDE_C /* Tell ide.h it's really us */ @@ -117,6 +125,7 @@ #include #include #include +#include #include #include @@ -124,24 +133,29 @@ #include #include -#include "ide.h" #include "ide_modes.h" #ifdef CONFIG_KMOD #include #endif /* CONFIG_KMOD */ -static const byte ide_hwif_to_major[] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR }; +#ifdef CONFIG_BLK_DEV_VIA82C586 +extern byte fifoconfig; /* defined in via82c586.c used by ide_setup()*/ +#endif + +static const byte ide_hwif_to_major[] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR }; static int idebus_parameter; /* holds the "idebus=" parameter */ static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ static int initializing; /* set while initializing built-in drivers */ +#if defined(__mc68000__) || defined(CONFIG_APUS) /* * 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 = 0; +#endif /* __mc68000__ || CONFIG_APUS */ /* * ide_modules keeps track of the available IDE chipset/probe/driver modules. @@ -187,14 +201,18 @@ static void init_hwif_data (unsigned int index) { unsigned int unit; + hw_regs_t hw; ide_hwif_t *hwif = &ide_hwifs[index]; /* bulk initialize hwif & drive info with zeros */ memset(hwif, 0, sizeof(ide_hwif_t)); + memset(&hw, 0, sizeof(hw_regs_t)); /* fill in any non-zero initial values */ hwif->index = index; - ide_init_hwif_ports(hwif->io_ports, ide_default_io_base(index), &hwif->irq); + ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq); + memcpy(&hwif->hw, &hw, sizeof(hw)); + memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports)); hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; #ifdef CONFIG_BLK_DEV_HD if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) @@ -211,6 +229,7 @@ drive->media = ide_disk; drive->select.all = (unit<<4)|0xa0; drive->hwif = hwif; + init_waitqueue_head(&drive->wqueue); drive->ctl = 0x08; drive->ready_stat = READY_STAT; drive->bad_wstat = BAD_W_STAT; @@ -219,6 +238,7 @@ drive->name[0] = 'h'; drive->name[1] = 'd'; drive->name[2] = 'a' + (index * MAX_DRIVES) + unit; + init_waitqueue_head(&drive->wqueue); } } @@ -246,9 +266,13 @@ return; /* already initialized */ magic_cookie = 0; + /* Initialise all interface structures */ for (index = 0; index < MAX_HWIFS; ++index) init_hwif_data(index); + /* Add default hw interfaces */ + ide_init_default_hwifs(); + idebus_parameter = 0; system_bus_speed = 0; } @@ -652,6 +676,10 @@ pre_reset(&hwif->drives[unit]); #if OK_TO_RESET_CONTROLLER + if (!IDE_CONTROL_REG) { + __restore_flags(flags); + return; + } /* * Note that we also set nIEN while resetting the device, * to mask unwanted interrupts from the interface during the reset. @@ -857,7 +885,8 @@ void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler) { ide_set_handler (drive, handler, WAIT_CMD); - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */ + if (IDE_CONTROL_REG) + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */ OUT_BYTE(nsect,IDE_NSECTOR_REG); OUT_BYTE(cmd,IDE_COMMAND_REG); } @@ -1253,6 +1282,20 @@ } #endif /* MAX_HWIFS > 5 */ +#if MAX_HWIFS > 6 +void do_ide6_request (void) +{ + unlock_do_hwgroup_request (ide_hwifs[6].hwgroup); +} +#endif /* MAX_HWIFS > 6 */ + +#if MAX_HWIFS > 7 +void do_ide7_request (void) +{ + unlock_do_hwgroup_request (ide_hwifs[7].hwgroup); +} +#endif /* MAX_HWIFS > 7 */ + static void start_next_request (ide_hwgroup_t *hwgroup, int masked_irq) { unsigned long flags; @@ -1370,6 +1413,12 @@ __cli(); /* local CPU only */ spin_lock_irqsave(&hwgroup->spinlock, flags); hwif = hwgroup->hwif; + + if (!ide_ack_intr(hwif)) { + spin_unlock_irqrestore(&hwgroup->spinlock, flags); + return; + } + if ((handler = hwgroup->handler) == NULL || hwgroup->poll_timeout != 0) { /* * Not expecting an interrupt from this drive. @@ -1391,7 +1440,6 @@ * Probably not a shared PCI interrupt, * so we can safely try to do something about it: */ - (void)ide_ack_intr(hwif->io_ports[IDE_STATUS_OFFSET], hwif->io_ports[IDE_IRQ_OFFSET]); unexpected_intr(irq, hwgroup); } spin_unlock_irqrestore(&hwgroup->spinlock, flags); @@ -1403,7 +1451,6 @@ return; } hwgroup->handler = NULL; - (void)ide_ack_intr(hwif->io_ports[IDE_STATUS_OFFSET], hwif->io_ports[IDE_IRQ_OFFSET]); del_timer(&(hwgroup->timer)); spin_unlock_irqrestore(&hwgroup->spinlock, flags); if (drive->unmask) @@ -1490,7 +1537,7 @@ ide_hwgroup_t *hwgroup = HWGROUP(drive); unsigned int major = HWIF(drive)->major; struct request *cur_rq; - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); if (IS_PDC4030_DRIVE && rq->buffer != NULL) return -ENOSYS; /* special drive cmds not supported */ @@ -1696,6 +1743,7 @@ ide_hwgroup_t *hwgroup; int irq_count = 0, unit, i; unsigned long flags; + unsigned int p, minor; if (index >= MAX_HWIFS) return; @@ -1714,6 +1762,24 @@ goto abort; } hwif->present = 0; + + /* + * All clear? Then blow away the buffer cache + */ + sti(); + for (unit = 0; unit < MAX_DRIVES; ++unit) { + drive = &hwif->drives[unit]; + minor = drive->select.b.unit << PARTN_BITS; + for (p = 0; p < (1<part[p].nr_sects > 0) { + kdev_t devp = MKDEV(hwif->major, minor+p); + struct super_block * sb = get_super(devp); + if (sb) invalidate_inodes(sb); + invalidate_buffers (devp); + } + } + } + cli(); hwgroup = hwif->hwgroup; /* @@ -1734,7 +1800,8 @@ * allocated for weird IDE interface chipsets. */ ide_release_region(hwif->io_ports[IDE_DATA_OFFSET], 8); - ide_release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1); + if (hwif->io_ports[IDE_CONTROL_OFFSET]) + ide_release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1); /* * Remove us from the hwgroup, and free @@ -1798,21 +1865,58 @@ restore_flags(flags); /* all CPUs */ } -int ide_register (int arg1, int arg2, int irq) +/* + * Setup hw_regs_t structure described by parameters. You + * may set up the hw structure yourself OR use this routine to + * do it for you. + */ +void ide_setup_ports ( hw_regs_t *hw, + ide_ioreg_t base, int *offsets, + ide_ioreg_t ctrl, ide_ioreg_t intr, + ide_ack_intr_t *ack_intr, int irq) +{ + int i; + + for (i = 0; i < IDE_NR_PORTS; i++) { + if (offsets[i] == -1) { + switch(i) { + case IDE_CONTROL_OFFSET: + hw->io_ports[i] = ctrl; + break; + case IDE_IRQ_OFFSET: + hw->io_ports[i] = intr; + break; + default: + hw->io_ports[i] = 0; + break; + } + } else { + hw->io_ports[i] = base + offsets[i]; + } + } + hw->irq = irq; + hw->ack_intr = ack_intr; +} + +/* + * Register an IDE interface, specifing exactly the registers etc + * Set init=1 iff calling before probes have taken place. + */ +int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp) { int index, retry = 1; ide_hwif_t *hwif; - ide_ioreg_t data_port = (ide_ioreg_t) arg1, ctl_port = (ide_ioreg_t) arg2; do { for (index = 0; index < MAX_HWIFS; ++index) { hwif = &ide_hwifs[index]; - if (hwif->io_ports[IDE_DATA_OFFSET] == data_port) + if (hwif->hw.io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET]) goto found; } for (index = 0; index < MAX_HWIFS; ++index) { hwif = &ide_hwifs[index]; - if (!hwif->present) + if ((!hwif->present && !initializing) || + (!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing)) goto found; } for (index = 0; index < MAX_HWIFS; index++) @@ -1824,14 +1928,33 @@ ide_unregister(index); if (hwif->present) return -1; - ide_init_hwif_ports(hwif->io_ports, data_port, &hwif->irq); - if (ctl_port) - hwif->io_ports[IDE_CONTROL_OFFSET] = ctl_port; - hwif->irq = irq; + memcpy(&hwif->hw, hw, sizeof(*hw)); + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); + hwif->irq = hw->irq; hwif->noprobe = 0; - ide_init_module(IDE_PROBE_MODULE); - ide_init_module(IDE_DRIVER_MODULE); - return hwif->present ? index : -1; + + if (!initializing) { + ide_init_module(IDE_PROBE_MODULE); + ide_init_module(IDE_DRIVER_MODULE); + } + + if (hwifp) + *hwifp = hwif; + + return (initializing || hwif->present) ? index : -1; +} + +/* + * Compatability function with existing drivers. If you want + * something different, use the function above. + */ +int ide_register (int arg1, int arg2, int irq) +{ + hw_regs_t hw; + + ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL); + hw.irq = irq; + return ide_register_hw(&hw, NULL); } void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set) @@ -2056,10 +2179,24 @@ return ide_do_drive_cmd(drive, &rq, ide_wait); } +/* + * Delay for *at least* 50ms. As we don't know how much time is left + * until the next tick occurs, we wait an extra tick to be safe. + * This is used only during the probing/polling for drives at boot time. + * + * However, its usefullness may be needed in other places, thus we export it now. + * The future may change this to a millisecond setable delay. + */ +void ide_delay_50ms (void) +{ + unsigned long timeout = jiffies + ((HZ + 19)/20) + 1; + while (0 < (signed long)(timeout - jiffies)); +} + static int ide_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int err, major, minor; + int err = 0, major, minor; ide_drive_t *drive; struct request rq; kdev_t dev; @@ -2147,7 +2284,68 @@ return -ENOMEM; memcpy(argbuf, args, 4); } + if ((((byte *)arg)[0] == WIN_SETFEATURES) && + (((byte *)arg)[1] > 66) && + (((byte *)arg)[2] == 3) && + ((drive->id->word93 & 0x2000) == 0)) { + printk("%s: Speed warnings UDMA 3/4 is not functional.\n", drive->name); + goto abort; + } err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); + if (!err && + (((byte *)arg)[0] == WIN_SETFEATURES) && + (((byte *)arg)[1] >= 16) && + (((byte *)arg)[2] == 3) && + (drive->id->dma_ultra || + drive->id->dma_mword || + drive->id->dma_1word)) { + + /* + * Re-read drive->id for possible DMA mode + * change (copied from ide-probe.c) + */ + struct hd_driveid *id; + unsigned long timeout, irqs, flags; + + probe_irq_off(probe_irq_on()); + irqs = probe_irq_on(); + if (IDE_CONTROL_REG) + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); + ide_delay_50ms(); + OUT_BYTE(WIN_IDENTIFY, IDE_COMMAND_REG); + timeout = jiffies + WAIT_WORSTCASE; + do { + if (0 < (signed long)(jiffies - timeout)) { + if (irqs) + (void) probe_irq_off(irqs); + goto abort; /* drive timed-out */ + } + ide_delay_50ms(); /* give drive a breather */ + } while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT); + ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */ + if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) + goto abort; + __save_flags(flags); /* local CPU only */ + __cli(); /* local CPU only; some systems need this */ + id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); + ide_input_data(drive, id, SECTOR_WORDS); + (void) GET_STAT(); /* clear drive IRQ */ + ide__sti(); /* local CPU only */ + __restore_flags(flags); /* local CPU only */ + ide_fix_driveid(id); + if (id && id->cyls) { + drive->id->dma_ultra = id->dma_ultra; + drive->id->dma_mword = id->dma_mword; + drive->id->dma_1word = id->dma_1word; + /* anything more ? */ +#ifdef DEBUG + printk("%s: dma_ultra=%04X, dma_mword=%04X, dma_1word=%04X\n", + drive->name, id->dma_ultra, id->dma_mword, id->dma_1word); +#endif + kfree(id); + } + } + abort: if (copy_to_user((void *)arg, argbuf, argsize)) err = -EFAULT; if (argsize > 4) @@ -2233,6 +2431,32 @@ } /* + * + */ +char *ide_xfer_verbose (byte xfer_rate) { + switch(xfer_rate) { + case XFER_UDMA_4: return("UDMA 4"); + case XFER_UDMA_3: return("UDMA 3"); + case XFER_UDMA_2: return("UDMA 2"); + case XFER_UDMA_1: return("UDMA 1"); + case XFER_UDMA_0: return("UDMA 0"); + case XFER_MW_DMA_2: return("MW DMA 2"); + case XFER_MW_DMA_1: return("MW DMA 1"); + case XFER_MW_DMA_0: return("MW DMA 0"); + case XFER_SW_DMA_2: return("SW DMA 2"); + case XFER_SW_DMA_1: return("SW DMA 1"); + case XFER_SW_DMA_0: return("SW DMA 0"); + case XFER_PIO_4: return("PIO 4"); + case XFER_PIO_3: return("PIO 3"); + case XFER_PIO_2: return("PIO 2"); + case XFER_PIO_1: return("PIO 1"); + case XFER_PIO_0: return("PIO 0"); + case XFER_PIO_SLOW: return("PIO SLOW"); + default: return("XFER ERROR"); + } +} + +/* * stridx() returns the offset of c within s, * or -1 if c is '\0' or not found within s. */ @@ -2351,7 +2575,22 @@ * "idex=reset" : reset interface before first use * "idex=dma" : enable DMA by default on both drives if possible * - * The following are valid ONLY on ide0, + * "splitfifo=betweenChan" + * : FIFO Configuration of VIA 82c586(,"A"or"B"). + * --see what follows... + * "splitfifo=betweenChan,thresholdprim,thresholdsec" + * : FIFO Configuration of VIA 82c586(,"A" or "B"). + * betweenChan = 1(all FIFO's to primary channel) + * , 2(all FIFO's to secondary channel) + * , 3 or 4(evenly shared between them). + * note: without FIFO, a channel is (u)dma disabled! + * thresholdprim = 4, 3, 2 or 1 + * (standing for 1, 3/4, 1/2, 1/4). + * Sets the threshold of FIFO to begin dma + * transfer on the primary channel. + * thresholdsec = cf upper, but for secondary channel. + * + * The following are valid ONLY on ide0, (except dc4030) * and the defaults for the base,ctl ports must not be altered. * * "ide0=dtc2278" : probe/support DTC2278 interface @@ -2361,6 +2600,7 @@ * "ide0=qd6580" : probe/support qd6580 interface * "ide0=ali14xx" : probe/support ali14xx chipsets (ALI M1439, M1443, M1445) * "ide0=umc8672" : probe/support umc8672 chipsets + * "idex=dc4030" : probe/support Promise DC4030VL interface */ __initfunc(void ide_setup (char *s)) { @@ -2372,6 +2612,17 @@ const char max_hwif = '0' + (MAX_HWIFS - 1); printk("ide_setup: %s", s); + +#ifdef CONFIG_BLK_DEV_IDEDOUBLER + if (!strcmp(s, "ide=doubler")) { + extern int ide_doubler; + + printk("ide: Enabled support for IDE doublers\n"); + ide_doubler = 1; + return; + } +#endif /* CONFIG_BLK_DEV_IDEDOUBLER */ + init_ide_data (); /* @@ -2435,6 +2686,58 @@ } } +#if defined(CONFIG_BLK_DEV_VIA82C586) + /* + * Look for drive option "splitfifo=..." + */ + + if (s[0] == 's' && s[1] == 'p' && s[2] == 'l' && + s[3] == 'i' && s[4] == 't' && s[5] == 'f' && + s[6] == 'i' && s[7] == 'f' && s[8] == 'o') { + byte tmp = 0x3a; /* default config byte */ + + i = match_parm(&s[9], NULL, vals, 3); + switch(i) { + case 3: + tmp &= 0xf0; + if ((vals[1] > 0) && (vals[1] < 5)) { + /* sets threshold for primary Channel: */ + byte x = 4 - vals[1]; + tmp |= (x << 2); + } + else + goto bad_option; + if ((vals[2] > 0) && (vals[2] < 5)) { + /* sets threshold for secondary Channel: */ + byte x = 4 - vals[2]; + tmp |= x; + } + else + goto bad_option; + case 1: + /* set the FIFO config between channels to 0: */ + tmp &= 0x9f; + /* set the needed FIFO config between channels: */ + if (vals[0] == 1) /* primary fifo only */ + tmp |= 0x10; + else if (vals[0] == 2) /* secondary fifo only */ + tmp |= 0x70; + else if (vals[0] == 4) /* other shared fifo config */ + tmp |= 0x50; + else if (vals[0] == 3) /* default config */ + tmp |= 0x30; + else + goto bad_option; + break; + default: + goto bad_option; + } + /* set the found option in fifoconfig */ + fifoconfig = tmp; + goto done; + } +#endif /* defined(CONFIG_BLK_DEV_VIA82C586) */ + if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e') goto bad_option; /* @@ -2468,9 +2771,9 @@ if (i > 0 || i <= -7) { /* is parameter a chipset name? */ if (hwif->chipset != ide_unknown) goto bad_option; /* chipset already specified */ - if (i <= -7 && hw != 0) + if (i <= -7 && i != -14 && hw != 0) goto bad_hwif; /* chipset drivers are for "ide0=" only */ - if (i <= -7 && ide_hwifs[hw^1].chipset != ide_unknown) + if (i <= -7 && i != -14 && ide_hwifs[hw+1].chipset != ide_unknown) goto bad_option; /* chipset for 2nd port already specified */ printk("\n"); } @@ -2574,8 +2877,9 @@ case 2: /* base,ctl */ vals[2] = 0; /* default irq = probe for it */ case 3: /* base,ctl,irq */ - ide_init_hwif_ports(hwif->io_ports, (ide_ioreg_t) vals[0], &hwif->irq); - hwif->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) vals[1]; + hwif->hw.irq = vals[2]; + ide_init_hwif_ports(&hwif->hw, (ide_ioreg_t) vals[0], (ide_ioreg_t) vals[1], &hwif->irq); + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->irq = vals[2]; hwif->noprobe = 0; hwif->chipset = ide_generic; @@ -2612,9 +2916,122 @@ * an IDE disk drive, or if a geometry was "forced" on the commandline. * Returns 1 if the geometry translation was successful. */ + +#define ANDRIES_GEOMETRY 0 + int ide_xlate_1024 (kdev_t i_rdev, int xparm, const char *msg) { ide_drive_t *drive; + +#if ANDRIES_GEOMETRY + /* + * This is the documented list of values (some version of) + * OnTrack DM uses. + */ + + static const byte dm_head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0}; + + /* + * This is a pure phantasy list - known to be incorrect. + * + * In fact it seems that EZD does not do anything to the CHS + * values in the partition table, so whether EZD is present + * or not should probably not influence the geometry. + */ + + static const byte ez_head_vals[] = {4, 8, 16, 32, 64, 128, 240, 255, 0}; const byte *heads; + unsigned long tracks; + + drive = get_info_ptr(i_rdev); + if (!drive) + return 0; + + if (xparm > 1 && xparm <= drive->bios_head && drive->bios_sect == 63) { + /* + * Update the current 3D drive values. + */ + drive->id->cur_cyls = drive->bios_cyl; + drive->id->cur_heads = drive->bios_head; + drive->id->cur_sectors = drive->bios_sect; + return 0; /* we already have a translation */ + } + + if (xparm == -1) { + int ret = 0; +#if FAKE_FDISK_FOR_EZDRIVE + if (drive->remap_0_to_1 == 0) { + drive->remap_0_to_1 = 1; + printk("%s [remap 0->1]", msg); + msg = NULL; + ret = 1; + } + if (drive->bios_head > 16) +#endif /* FAKE_FDISK_FOR_EZDRIVE */ + { + /* + * Update the current 3D drive values. + */ + drive->id->cur_cyls = drive->bios_cyl; + drive->id->cur_heads = drive->bios_head; + drive->id->cur_sectors = drive->bios_sect; + return ret; /* we already have a translation */ + } + } + + if (msg) + printk("%s ", msg); + + if (drive->forced_geom) { + /* + * Update the current 3D drive values. + */ + drive->id->cur_cyls = drive->bios_cyl; + drive->id->cur_heads = drive->bios_head; + drive->id->cur_sectors = drive->bios_sect; + return 0; + } + +#if 1 + /* There used to be code here that assigned drive->id->CHS + to drive->CHS and that to drive->bios_CHS. However, + some disks have id->C/H/S = 4092/16/63 but are larger than 2.1 GB. + In such cases that code was wrong. Moreover, + there seems to be no reason to do any of these things. */ +#else + if (drive->id) { + drive->cyl = drive->id->cyls; + drive->head = drive->id->heads; + drive->sect = drive->id->sectors; + } + drive->bios_cyl = drive->cyl; + drive->bios_head = drive->head; + drive->bios_sect = drive->sect; + drive->special.b.set_geometry = 1; + +#endif + + tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63; + drive->bios_sect = 63; + if (xparm > 1) { + drive->bios_head = xparm; + drive->bios_cyl = tracks / drive->bios_head; + } else { + heads = (xparm == -1) ? ez_head_vals : dm_head_vals; + while (drive->bios_cyl >= 1024) { + drive->bios_head = *heads; + drive->bios_cyl = tracks / drive->bios_head; + if (0 == *++heads) + break; + } + if (xparm == 1) { + drive->sect0 = 63; + drive->bios_cyl = (tracks - 1) / drive->bios_head; + printk("[remap +63] "); + } + } + +#else /* ANDRIES_GEOMETRY */ + static const byte head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0}; const byte *heads = head_vals; unsigned long tracks; @@ -2689,14 +3106,16 @@ printk("[remap +63] "); } } +#endif /* ANDRIES_GEOMETRY */ + drive->part[0].nr_sects = current_capacity(drive); printk("[%d/%d/%d]", drive->bios_cyl, drive->bios_head, drive->bios_sect); /* * Update the current 3D drive values. */ - drive->id->cur_cyls = drive->bios_cyl; - drive->id->cur_heads = drive->bios_head; - drive->id->cur_sectors = drive->bios_sect; + drive->id->cur_cyls = drive->bios_cyl; + drive->id->cur_heads = drive->bios_head; + drive->id->cur_sectors = drive->bios_sect; return 1; } @@ -2739,6 +3158,42 @@ pmac_ide_probe(); } #endif /* CONFIG_BLK_DEV_IDE_PMAC */ +#ifdef CONFIG_BLK_DEV_IDE_ICSIDE + { + extern void icside_init(void); + icside_init(); + } +#endif /* CONFIG_BLK_DEV_IDE_ICSIDE */ +#ifdef CONFIG_BLK_DEV_IDE_RAPIDE + { + extern void rapide_init(void); + rapide_init(); + } +#endif /* CONFIG_BLK_DEV_IDE_RAPIDE */ +#ifdef CONFIG_BLK_DEV_GAYLE + { + extern void gayle_init(void); + gayle_init(); + } +#endif /* CONFIG_BLK_DEV_GAYLE */ +#ifdef CONFIG_BLK_DEV_FALCON_IDE + { + extern void falconide_init(void); + falconide_init(); + } +#endif /* CONFIG_BLK_DEV_FALCON_IDE */ +#ifdef CONFIG_BLK_DEV_MAC_IDE + { + extern void macide_init(void); + macide_init(); + } +#endif /* CONFIG_BLK_DEV_MAC_IDE */ +#ifdef CONFIG_BLK_DEV_BUDDHA + { + extern void buddha_init(void); + buddha_init(); + } +#endif /* CONFIG_BLK_DEV_BUDDHA */ } __initfunc(void ide_init_builtin_drivers (void)) @@ -3013,6 +3468,12 @@ #if MAX_HWIFS > 5 EXPORT_SYMBOL(do_ide5_request); #endif /* MAX_HWIFS > 5 */ +#if MAX_HWIFS > 6 +EXPORT_SYMBOL(do_ide6_request); +#endif /* MAX_HWIFS > 6 */ +#if MAX_HWIFS > 7 +EXPORT_SYMBOL(do_ide7_request); +#endif /* MAX_HWIFS > 7 */ /* * Driver module @@ -3037,6 +3498,7 @@ EXPORT_SYMBOL(ide_revalidate_disk); EXPORT_SYMBOL(ide_cmd); EXPORT_SYMBOL(ide_wait_cmd); +EXPORT_SYMBOL(ide_delay_50ms); EXPORT_SYMBOL(ide_stall_queue); #ifdef CONFIG_PROC_FS EXPORT_SYMBOL(ide_add_proc_entries); @@ -3046,14 +3508,23 @@ EXPORT_SYMBOL(ide_add_setting); EXPORT_SYMBOL(ide_remove_setting); +EXPORT_SYMBOL(ide_register_hw); EXPORT_SYMBOL(ide_register); EXPORT_SYMBOL(ide_unregister); +EXPORT_SYMBOL(ide_setup_ports); /* * This is gets invoked once during initialization, to set *everything* up */ __initfunc(int ide_init (void)) { + static char banner_printed = 0; + + if (!banner_printed) { + printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); + banner_printed = 1; + } + init_ide_data (); initializing = 1; diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide.h linux/drivers/block/ide.h --- v2.3.0/linux/drivers/block/ide.h Tue May 11 13:04:09 1999 +++ linux/drivers/block/ide.h Wed Dec 31 16:00:00 1969 @@ -1,769 +0,0 @@ -#ifndef _IDE_H -#define _IDE_H -/* - * linux/drivers/block/ide.h - * - * Copyright (C) 1994-1998 Linus Torvalds & authors - */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * This is the multiple IDE interface driver, as evolved from hd.c. - * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15). - * There can be up to two drives per interface, as per the ATA-2 spec. - * - * Primary i/f: ide0: major=3; (hda) minor=0; (hdb) minor=64 - * Secondary i/f: ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64 - * Tertiary i/f: ide2: major=33; (hde) minor=0; (hdf) minor=64 - * Quaternary i/f: ide3: major=34; (hdg) minor=0; (hdh) minor=64 - */ - -/****************************************************************************** - * IDE driver configuration options (play with these as desired): - * - * REALLY_SLOW_IO can be defined in ide.c and ide-cd.c, if necessary - */ -#undef REALLY_FAST_IO /* define if ide ports are perfect */ -#define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */ - -#ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */ -#define SUPPORT_SLOW_DATA_PORTS 1 /* 0 to reduce kernel size */ -#endif -#ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */ -#define SUPPORT_VLB_SYNC 1 /* 0 to reduce kernel size */ -#endif -#ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */ -#define DISK_RECOVERY_TIME 0 /* for hardware that needs it */ -#endif -#ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */ -#define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */ -#endif -#ifndef FAKE_FDISK_FOR_EZDRIVE /* 1 to help linux fdisk with EZDRIVE */ -#define FAKE_FDISK_FOR_EZDRIVE 1 /* 0 to reduce kernel size */ -#endif -#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */ -#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */ -#endif - -#ifdef CONFIG_BLK_DEV_CMD640 -#if 0 /* change to 1 when debugging cmd640 problems */ -void cmd640_dump_regs (void); -#define CMD640_DUMP_REGS cmd640_dump_regs() /* for debugging cmd640 chipset */ -#endif -#endif /* CONFIG_BLK_DEV_CMD640 */ - -/* - * IDE_DRIVE_CMD is used to implement many features of the hdparm utility - */ -#define IDE_DRIVE_CMD 99 /* (magic) undef to reduce kernel size*/ - -/* - * "No user-serviceable parts" beyond this point :) - *****************************************************************************/ - -typedef unsigned char byte; /* used everywhere */ - -/* - * Probably not wise to fiddle with these - */ -#define ERROR_MAX 8 /* Max read/write errors per sector */ -#define ERROR_RESET 3 /* Reset controller every 4th retry */ -#define ERROR_RECAL 1 /* Recalibrate every 2nd retry */ - -/* - * Ensure that various configuration flags have compatible settings - */ -#ifdef REALLY_SLOW_IO -#undef REALLY_FAST_IO -#endif - -#define HWIF(drive) ((ide_hwif_t *)((drive)->hwif)) -#define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup)) - -/* - * Definitions for accessing IDE controller registers - */ -#define IDE_NR_PORTS (10) - -#define IDE_DATA_OFFSET (0) -#define IDE_ERROR_OFFSET (1) -#define IDE_NSECTOR_OFFSET (2) -#define IDE_SECTOR_OFFSET (3) -#define IDE_LCYL_OFFSET (4) -#define IDE_HCYL_OFFSET (5) -#define IDE_SELECT_OFFSET (6) -#define IDE_STATUS_OFFSET (7) -#define IDE_CONTROL_OFFSET (8) -#define IDE_IRQ_OFFSET (9) - -#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET -#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET - -#define IDE_DATA_REG (HWIF(drive)->io_ports[IDE_DATA_OFFSET]) -#define IDE_ERROR_REG (HWIF(drive)->io_ports[IDE_ERROR_OFFSET]) -#define IDE_NSECTOR_REG (HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET]) -#define IDE_SECTOR_REG (HWIF(drive)->io_ports[IDE_SECTOR_OFFSET]) -#define IDE_LCYL_REG (HWIF(drive)->io_ports[IDE_LCYL_OFFSET]) -#define IDE_HCYL_REG (HWIF(drive)->io_ports[IDE_HCYL_OFFSET]) -#define IDE_SELECT_REG (HWIF(drive)->io_ports[IDE_SELECT_OFFSET]) -#define IDE_STATUS_REG (HWIF(drive)->io_ports[IDE_STATUS_OFFSET]) -#define IDE_CONTROL_REG (HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]) -#define IDE_IRQ_REG (HWIF(drive)->io_ports[IDE_IRQ_OFFSET]) - -#define IDE_FEATURE_REG IDE_ERROR_REG -#define IDE_COMMAND_REG IDE_STATUS_REG -#define IDE_ALTSTATUS_REG IDE_CONTROL_REG -#define IDE_IREASON_REG IDE_NSECTOR_REG -#define IDE_BCOUNTL_REG IDE_LCYL_REG -#define IDE_BCOUNTH_REG IDE_HCYL_REG - -#ifdef REALLY_FAST_IO -#define OUT_BYTE(b,p) outb((b),(p)) -#define IN_BYTE(p) (byte)inb(p) -#else -#define OUT_BYTE(b,p) outb_p((b),(p)) -#define IN_BYTE(p) (byte)inb_p(p) -#endif /* REALLY_FAST_IO */ - -#define GET_ERR() IN_BYTE(IDE_ERROR_REG) -#define GET_STAT() IN_BYTE(IDE_STATUS_REG) -#define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good)) -#define BAD_R_STAT (BUSY_STAT | ERR_STAT) -#define BAD_W_STAT (BAD_R_STAT | WRERR_STAT) -#define BAD_STAT (BAD_R_STAT | DRQ_STAT) -#define DRIVE_READY (READY_STAT | SEEK_STAT) -#define DATA_READY (DRQ_STAT) - -/* - * Some more useful definitions - */ -#define IDE_MAJOR_NAME "ide" /* the same for all i/f; see also genhd.c */ -#define MAJOR_NAME IDE_MAJOR_NAME -#define PARTN_BITS 6 /* number of minor dev bits for partitions */ -#define PARTN_MASK ((1< (b2) + (t)) || ((b2) > (b1) + (t))) -#define IDE_MIN(a,b) ((a)<(b) ? (a):(b)) -#define IDE_MAX(a,b) ((a)>(b) ? (a):(b)) - -/* - * Timeouts for various operations: - */ -#define WAIT_DRQ (5*HZ/100) /* 50msec - spec allows up to 20ms */ -#ifdef CONFIG_APM -#define WAIT_READY (5*HZ) /* 5sec - some laptops are very slow */ -#else -#define WAIT_READY (3*HZ/100) /* 30msec - should be instantaneous */ -#endif /* CONFIG_APM */ -#define WAIT_PIDENTIFY (10*HZ) /* 10sec - should be less than 3ms (?) - if all ATAPI CD is closed at boot */ -#define WAIT_WORSTCASE (30*HZ) /* 30sec - worst case when spinning up */ -#define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */ -#define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */ - -#define SELECT_DRIVE(hwif,drive) \ -{ \ - if (hwif->selectproc) \ - hwif->selectproc(drive); \ - OUT_BYTE((drive)->select.all, hwif->io_ports[IDE_SELECT_OFFSET]); \ -} - -/* - * Now for the data we need to maintain per-drive: ide_drive_t - */ - -#define ide_scsi 0x21 -#define ide_disk 0x20 -#define ide_optical 0x7 -#define ide_cdrom 0x5 -#define ide_tape 0x1 -#define ide_floppy 0x0 - -typedef union { - unsigned all : 8; /* all of the bits together */ - struct { - unsigned set_geometry : 1; /* respecify drive geometry */ - unsigned recalibrate : 1; /* seek to cyl 0 */ - unsigned set_multmode : 1; /* set multmode count */ - unsigned set_tune : 1; /* tune interface for drive */ - unsigned reserved : 4; /* unused */ - } b; - } special_t; - -typedef struct ide_drive_s { - struct request *queue; /* request queue */ - struct ide_drive_s *next; /* circular list of hwgroup drives */ - unsigned long sleep; /* sleep until this time */ - unsigned long service_start; /* time we started last request */ - unsigned long service_time; /* service time of last request */ - special_t special; /* special action flags */ - byte keep_settings; /* restore settings after drive reset */ - byte using_dma; /* disk is using dma for read/write */ - byte waiting_for_dma; /* dma currently in progress */ - byte unmask; /* flag: okay to unmask other irqs */ - byte slow; /* flag: slow data port */ - byte bswap; /* flag: byte swap data */ - byte dsc_overlap; /* flag: DSC overlap */ - byte nice1; /* flag: give potential excess bandwidth */ - unsigned present : 1; /* drive is physically present */ - unsigned noprobe : 1; /* from: hdx=noprobe */ - unsigned busy : 1; /* currently doing revalidate_disk() */ - unsigned removable : 1; /* 1 if need to do check_media_change */ - unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ - unsigned no_unmask : 1; /* disallow setting unmask bit */ - unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */ - unsigned nobios : 1; /* flag: do not probe bios for drive */ - unsigned revalidate : 1; /* request revalidation */ - unsigned atapi_overlap : 1; /* flag: ATAPI overlap (not supported) */ - unsigned nice0 : 1; /* flag: give obvious excess bandwidth */ - unsigned nice2 : 1; /* flag: give a share in our own bandwidth */ - unsigned doorlocking : 1; /* flag: for removable only: door lock/unlock works */ - unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */ -#if FAKE_FDISK_FOR_EZDRIVE - unsigned remap_0_to_1 : 1; /* flag: partitioned with ezdrive */ -#endif /* FAKE_FDISK_FOR_EZDRIVE */ - byte media; /* disk, cdrom, tape, floppy, ... */ - select_t select; /* basic drive/head select reg value */ - byte ctl; /* "normal" value for IDE_CONTROL_REG */ - byte ready_stat; /* min status value for drive ready */ - byte mult_count; /* current multiple sector setting */ - byte mult_req; /* requested multiple sector setting */ - byte tune_req; /* requested drive tuning setting */ - byte io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ - byte bad_wstat; /* used for ignoring WRERR_STAT */ - byte nowerr; /* used for ignoring WRERR_STAT */ - byte sect0; /* offset of first sector for DM6:DDO */ - byte usage; /* current "open()" count for drive */ - byte head; /* "real" number of heads */ - byte sect; /* "real" sectors per track */ - byte bios_head; /* BIOS/fdisk/LILO number of heads */ - byte bios_sect; /* BIOS/fdisk/LILO sectors per track */ - unsigned short bios_cyl; /* BIOS/fdisk/LILO number of cyls */ - unsigned short cyl; /* "real" number of cyls */ - unsigned int drive_data; /* for use by tuneproc/selectproc as needed */ - void *hwif; /* actually (ide_hwif_t *) */ - struct wait_queue *wqueue; /* used to wait for drive in open() */ - struct hd_driveid *id; /* drive model identification info */ - struct hd_struct *part; /* drive partition table */ - char name[4]; /* drive name, such as "hda" */ - void *driver; /* (ide_driver_t *) */ - void *driver_data; /* extra driver data */ - struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ - void *settings; /* /proc/ide/ drive settings */ - char driver_req[10]; /* requests specific driver */ - } ide_drive_t; - -/* - * An ide_dmaproc_t() initiates/aborts DMA read/write operations on a drive. - * - * The caller is assumed to have selected the drive and programmed the drive's - * sector address using CHS or LBA. All that remains is to prepare for DMA - * and then issue the actual read/write DMA/PIO command to the drive. - * - * Returns 0 if all went well. - * Returns 1 if DMA read/write could not be started, in which case the caller - * should either try again later, or revert to PIO for the current request. - */ -typedef enum { ide_dma_read, ide_dma_write, ide_dma_begin, ide_dma_end, - ide_dma_check, ide_dma_on, ide_dma_off, ide_dma_off_quietly, - ide_dma_test_irq - } ide_dma_action_t; - -typedef int (ide_dmaproc_t)(ide_dma_action_t, ide_drive_t *); - - -/* - * An ide_tuneproc_t() is used to set the speed of an IDE interface - * to a particular PIO mode. The "byte" parameter is used - * to select the PIO mode by number (0,1,2,3,4,5), and a value of 255 - * indicates that the interface driver should "auto-tune" the PIO mode - * according to the drive capabilities in drive->id; - * - * Not all interface types support tuning, and not all of those - * support all possible PIO settings. They may silently ignore - * or round values as they see fit. - */ -typedef void (ide_tuneproc_t)(ide_drive_t *, byte); - -/* - * This is used to provide support for strange interfaces - */ -typedef void (ide_selectproc_t) (ide_drive_t *); - -/* - * hwif_chipset_t is used to keep track of the specific hardware - * chipset used by each IDE interface, if known. - */ -typedef enum { ide_unknown, ide_generic, ide_pci, - ide_cmd640, ide_dtc2278, ide_ali14xx, - ide_qd6580, ide_umc8672, ide_ht6560b, - ide_pdc4030, ide_rz1000, ide_trm290, - ide_cmd646, ide_4drives - } hwif_chipset_t; - -typedef struct ide_pci_devid_s { - unsigned short vid; - unsigned short did; -} ide_pci_devid_t; - -#define IDE_PCI_DEVID_NULL ((ide_pci_devid_t){0,0}) -#define IDE_PCI_DEVID_EQ(a,b) (a.vid == b.vid && a.did == b.did) - -typedef struct hwif_s { - struct hwif_s *next; /* for linked-list in ide_hwgroup_t */ - void *hwgroup; /* actually (ide_hwgroup_t *) */ - ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */ - ide_drive_t drives[MAX_DRIVES]; /* drive info */ - struct gendisk *gd; /* gendisk structure */ - ide_tuneproc_t *tuneproc; /* routine to tune PIO mode for drives */ - ide_selectproc_t *selectproc; /* tweaks hardware to select drive */ - ide_dmaproc_t *dmaproc; /* dma read/write/abort routine */ - unsigned long *dmatable; /* dma physical region descriptor table */ - struct hwif_s *mate; /* other hwif from same PCI chip */ - unsigned long dma_base; /* base addr for dma ports */ - unsigned dma_extra; /* extra addr for dma ports */ - unsigned long config_data; /* for use by chipset-specific code */ - unsigned long select_data; /* for use by chipset-specific code */ - struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ - int irq; /* our irq number */ - byte major; /* our major number */ - char name[6]; /* name of interface, eg. "ide0" */ - byte index; /* 0 for ide0; 1 for ide1; ... */ - hwif_chipset_t chipset; /* sub-module for tuning.. */ - unsigned noprobe : 1; /* don't probe for this interface */ - unsigned present : 1; /* this interface exists */ - unsigned serialized : 1; /* serialized operation with mate hwif */ - unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ - unsigned reset : 1; /* reset after probe */ - unsigned autodma : 1; /* automatically try to enable DMA at boot */ - byte channel; /* for dual-port chips: 0=primary, 1=secondary */ - struct pci_dev *pci_dev; /* for pci chipsets */ - ide_pci_devid_t pci_devid; /* for pci chipsets: {VID,DID} */ -#if (DISK_RECOVERY_TIME > 0) - unsigned long last_time; /* time when previous rq was done */ -#endif - } ide_hwif_t; - -/* - * internal ide interrupt handler type - */ -typedef void (ide_handler_t)(ide_drive_t *); - -typedef struct hwgroup_s { - spinlock_t spinlock; /* protects "busy" and "handler" */ - ide_handler_t *handler;/* irq handler, if active */ - int busy; /* BOOL: protects all fields below */ - ide_drive_t *drive; /* current drive */ - ide_hwif_t *hwif; /* ptr to current hwif in linked-list */ - struct request *rq; /* current request */ - struct timer_list timer; /* failsafe timer */ - struct request wrq; /* local copy of current write rq */ - unsigned long poll_timeout; /* timeout value during long polls */ - } ide_hwgroup_t; - -/* - * configurable drive settings - */ - -#define TYPE_INT 0 -#define TYPE_INTA 1 -#define TYPE_BYTE 2 -#define TYPE_SHORT 3 - -#define SETTING_READ (1 << 0) -#define SETTING_WRITE (1 << 1) -#define SETTING_RW (SETTING_READ | SETTING_WRITE) - -typedef int (ide_procset_t)(ide_drive_t *, int); -typedef struct ide_settings_s { - char *name; - int rw; - int read_ioctl; - int write_ioctl; - int data_type; - int min; - int max; - int mul_factor; - int div_factor; - void *data; - ide_procset_t *set; - int auto_remove; - struct ide_settings_s *next; -} ide_settings_t; - -void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set); -void ide_remove_setting(ide_drive_t *drive, char *name); -ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name); -int ide_read_setting(ide_drive_t *t, ide_settings_t *setting); -int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val); -void ide_add_generic_settings(ide_drive_t *drive); - -/* - * /proc/ide interface - */ -typedef struct { - const char *name; - mode_t mode; - read_proc_t *read_proc; - write_proc_t *write_proc; -} ide_proc_entry_t; - -#ifdef CONFIG_PROC_FS -void proc_ide_create(void); -void proc_ide_destroy(void); -void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data); -void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p); -read_proc_t proc_ide_read_capacity; -read_proc_t proc_ide_read_geometry; - -/* - * Standard exit stuff: - */ -#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) \ -{ \ - len -= off; \ - if (len < count) { \ - *eof = 1; \ - if (len <= 0) \ - return 0; \ - } else \ - len = count; \ - *start = page + off; \ - return len; \ -} -#else -#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0; -#endif - -/* - * Subdrivers support. - */ -#define IDE_SUBDRIVER_VERSION 1 - -typedef int (ide_cleanup_proc)(ide_drive_t *); -typedef void (ide_do_request_proc)(ide_drive_t *, struct request *, unsigned long); -typedef void (ide_end_request_proc)(byte, ide_hwgroup_t *); -typedef int (ide_ioctl_proc)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); -typedef int (ide_open_proc)(struct inode *, struct file *, ide_drive_t *); -typedef void (ide_release_proc)(struct inode *, struct file *, ide_drive_t *); -typedef int (ide_check_media_change_proc)(ide_drive_t *); -typedef void (ide_pre_reset_proc)(ide_drive_t *); -typedef unsigned long (ide_capacity_proc)(ide_drive_t *); -typedef void (ide_special_proc)(ide_drive_t *); -typedef void (ide_setting_proc)(ide_drive_t *); - -typedef struct ide_driver_s { - const char *name; - const char *version; - byte media; - unsigned busy : 1; - unsigned supports_dma : 1; - unsigned supports_dsc_overlap : 1; - ide_cleanup_proc *cleanup; - ide_do_request_proc *do_request; - ide_end_request_proc *end_request; - ide_ioctl_proc *ioctl; - ide_open_proc *open; - ide_release_proc *release; - ide_check_media_change_proc *media_change; - ide_pre_reset_proc *pre_reset; - ide_capacity_proc *capacity; - ide_special_proc *special; - ide_proc_entry_t *proc; - } ide_driver_t; - -#define DRIVER(drive) ((ide_driver_t *)((drive)->driver)) - -/* - * IDE modules. - */ -#define IDE_CHIPSET_MODULE 0 /* not supported yet */ -#define IDE_PROBE_MODULE 1 -#define IDE_DRIVER_MODULE 2 - -typedef int (ide_module_init_proc)(void); - -typedef struct ide_module_s { - int type; - ide_module_init_proc *init; - void *info; - struct ide_module_s *next; -} ide_module_t; - -/* - * ide_hwifs[] is the master data structure used to keep track - * of just about everything in ide.c. Whenever possible, routines - * should be using pointers to a drive (ide_drive_t *) or - * pointers to a hwif (ide_hwif_t *), rather than indexing this - * structure directly (the allocation/layout may change!). - * - */ -#ifndef _IDE_C -extern ide_hwif_t ide_hwifs[]; /* master data repository */ -extern ide_module_t *ide_modules; -#endif - -/* - * We need blk.h, but we replace its end_request by our own version. - */ -#define IDE_DRIVER /* Toggle some magic bits in blk.h */ -#define LOCAL_END_REQUEST /* Don't generate end_request in blk.h */ -#include - -void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup); - -/* - * This is used for (nearly) all data transfers from/to the IDE interface - */ -void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); -void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); - -/* - * This is used for (nearly) all ATAPI data transfers from/to the IDE interface - */ -void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); -void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); - -/* - * This is used on exit from the driver, to designate the next irq handler - * and also to start the safety timer. - */ -void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout); - -/* - * Error reporting, in human readable form (luxurious, but a memory hog). - */ -byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat); - -/* - * ide_error() takes action based on the error returned by the controller. - * The calling function must return afterwards, to restart the request. - */ -void ide_error (ide_drive_t *drive, const char *msg, byte stat); - -/* - * Issue a simple drive command - * The drive must be selected beforehand. - */ -void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler); - -/* - * ide_fixstring() cleans up and (optionally) byte-swaps a text string, - * removing leading/trailing blanks and compressing internal blanks. - * It is primarily used to tidy up the model name/number fields as - * returned by the WIN_[P]IDENTIFY commands. - */ -void ide_fixstring (byte *s, const int bytecount, const int byteswap); - -/* - * This routine busy-waits for the drive status to be not "busy". - * It then checks the status for all of the "good" bits and none - * of the "bad" bits, and if all is okay it returns 0. All other - * cases return 1 after invoking ide_error() -- caller should return. - * - */ -int ide_wait_stat (ide_drive_t *drive, byte good, byte bad, unsigned long timeout); - -/* - * This routine is called from the partition-table code in genhd.c - * to "convert" a drive to a logical geometry with fewer than 1024 cyls. - * - * The second parameter, "xparm", determines exactly how the translation - * will be handled: - * 0 = convert to CHS with fewer than 1024 cyls - * using the same method as Ontrack DiskManager. - * 1 = same as "0", plus offset everything by 63 sectors. - * -1 = similar to "0", plus redirect sector 0 to sector 1. - * >1 = convert to a CHS geometry with "xparm" heads. - * - * Returns 0 if the translation was not possible, if the device was not - * an IDE disk drive, or if a geometry was "forced" on the commandline. - * Returns 1 if the geometry translation was successful. - */ -int ide_xlate_1024 (kdev_t, int, const char *); - -/* - * Start a reset operation for an IDE interface. - * The caller should return immediately after invoking this. - */ -void ide_do_reset (ide_drive_t *); - -/* - * This function is intended to be used prior to invoking ide_do_drive_cmd(). - */ -void ide_init_drive_cmd (struct request *rq); - -/* - * "action" parameter type for ide_do_drive_cmd() below. - */ -typedef enum - {ide_wait, /* insert rq at end of list, and wait for it */ - ide_next, /* insert rq immediately after current request */ - ide_preempt, /* insert rq in front of current request */ - ide_end} /* insert rq at end of list, but don't wait for it */ - ide_action_t; - -/* - * This function issues a special IDE device request - * onto the request queue. - * - * If action is ide_wait, then the rq is queued at the end of the - * request queue, and the function sleeps until it has been processed. - * This is for use when invoked from an ioctl handler. - * - * If action is ide_preempt, then the rq is queued at the head of - * the request queue, displacing the currently-being-processed - * request and this function returns immediately without waiting - * for the new rq to be completed. This is VERY DANGEROUS, and is - * intended for careful use by the ATAPI tape/cdrom driver code. - * - * If action is ide_next, then the rq is queued immediately after - * the currently-being-processed-request (if any), and the function - * returns without waiting for the new rq to be completed. As above, - * This is VERY DANGEROUS, and is intended for careful use by the - * ATAPI tape/cdrom driver code. - * - * If action is ide_end, then the rq is queued at the end of the - * request queue, and the function returns immediately without waiting - * for the new rq to be completed. This is again intended for careful - * use by the ATAPI tape/cdrom driver code. - */ -int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action); - -/* - * Clean up after success/failure of an explicit drive cmd. - * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_CMD). - */ -void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err); - -/* - * Issue ATA command and wait for completion. - */ -int ide_wait_cmd (ide_drive_t *drive, int cmd, int nsect, int feature, int sectors, byte *buf); - -/* - * ide_system_bus_speed() returns what we think is the system VESA/PCI - * bus speed (in MHz). This is used for calculating interface PIO timings. - * The default is 40 for known PCI systems, 50 otherwise. - * The "idebus=xx" parameter can be used to override this value. - */ -int ide_system_bus_speed (void); - -/* - * ide_multwrite() transfers a block of up to mcount sectors of data - * to a drive as part of a disk multwrite operation. - */ -void ide_multwrite (ide_drive_t *drive, unsigned int mcount); - -/* - * ide_stall_queue() can be used by a drive to give excess bandwidth back - * to the hwgroup by sleeping for timeout jiffies. - */ -void ide_stall_queue (ide_drive_t *drive, unsigned long timeout); - -/* - * ide_get_queue() returns the queue which corresponds to a given device. - */ -struct request **ide_get_queue (kdev_t dev); - -/* - * CompactFlash cards and their brethern pretend to be removable hard disks, - * but they never have a slave unit, and they don't have doorlock mechanisms. - * This test catches them, and is invoked elsewhere when setting appropriate config bits. - */ -int drive_is_flashcard (ide_drive_t *drive); - -int ide_spin_wait_hwgroup(ide_drive_t *drive, unsigned long *flags); -void ide_timer_expiry (unsigned long data); -void ide_intr (int irq, void *dev_id, struct pt_regs *regs); -void ide_geninit (struct gendisk *gd); -void do_ide0_request (void); -#if MAX_HWIFS > 1 -void do_ide1_request (void); -#endif -#if MAX_HWIFS > 2 -void do_ide2_request (void); -#endif -#if MAX_HWIFS > 3 -void do_ide3_request (void); -#endif -#if MAX_HWIFS > 4 -void do_ide4_request (void); -#endif -#if MAX_HWIFS > 5 -void do_ide5_request (void); -#endif -void ide_init_subdrivers (void); - -#ifndef _IDE_C -extern struct file_operations ide_fops[]; -#endif - -#ifdef _IDE_C -#ifdef CONFIG_BLK_DEV_IDE -int ideprobe_init (void); -#endif /* CONFIG_BLK_DEV_IDE */ -#ifdef CONFIG_BLK_DEV_IDEDISK -int idedisk_init (void); -#endif /* CONFIG_BLK_DEV_IDEDISK */ -#ifdef CONFIG_BLK_DEV_IDECD -int ide_cdrom_init (void); -#endif /* CONFIG_BLK_DEV_IDECD */ -#ifdef CONFIG_BLK_DEV_IDETAPE -int idetape_init (void); -#endif /* CONFIG_BLK_DEV_IDETAPE */ -#ifdef CONFIG_BLK_DEV_IDEFLOPPY -int idefloppy_init (void); -#endif /* CONFIG_BLK_DEV_IDEFLOPPY */ -#ifdef CONFIG_BLK_DEV_IDESCSI -int idescsi_init (void); -#endif /* CONFIG_BLK_DEV_IDESCSI */ -#endif /* _IDE_C */ - -int ide_register_module (ide_module_t *module); -void ide_unregister_module (ide_module_t *module); -ide_drive_t *ide_scan_devices (byte media, const char *name, ide_driver_t *driver, int n); -int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int version); -int ide_unregister_subdriver (ide_drive_t *drive); -int ide_replace_subdriver(ide_drive_t *drive, const char *driver); - -#ifdef CONFIG_BLK_DEV_IDEPCI -#define ON_BOARD 1 -#define NEVER_BOARD 0 -#ifdef CONFIG_BLK_DEV_OFFBOARD -# define OFF_BOARD ON_BOARD -#else /* CONFIG_BLK_DEV_OFFBOARD */ -# define OFF_BOARD NEVER_BOARD -#endif /* CONFIG_BLK_DEV_OFFBOARD */ - -unsigned long ide_find_free_region (unsigned short size) __init; -void ide_scan_pcibus (void) __init; -#endif -#ifdef CONFIG_BLK_DEV_IDEDMA -#define BAD_DMA_DRIVE 0 -#define GOOD_DMA_DRIVE 1 -int ide_build_dmatable (ide_drive_t *drive); -void ide_dma_intr (ide_drive_t *drive); -int check_drive_lists (ide_drive_t *drive, int good_bad); -int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive); -int ide_release_dma (ide_hwif_t *hwif); -void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init; -unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init; -#endif - -#ifdef CONFIG_BLK_DEV_PDC4030 -#include "pdc4030.h" -#define IS_PDC4030_DRIVE (HWIF(drive)->chipset == ide_pdc4030) -#else -#define IS_PDC4030_DRIVE (0) /* auto-NULLs out pdc4030 code */ -#endif /* CONFIG_BLK_DEV_PDC4030 */ - -#endif /* _IDE_H */ diff -u --recursive --new-file v2.3.0/linux/drivers/block/ide_modes.h linux/drivers/block/ide_modes.h --- v2.3.0/linux/drivers/block/ide_modes.h Tue May 11 13:03:59 1999 +++ linux/drivers/block/ide_modes.h Thu May 13 14:42:14 1999 @@ -15,7 +15,7 @@ * breaking the fragile cmd640.c support. */ -#if defined(CONFIG_BLK_DEV_CMD640) || defined(CONFIG_IDE_CHIPSETS) || defined(CONFIG_BLK_DEV_OPTI621) || defined(CONFIG_BLK_DEV_IDE_PMAC) +#ifdef CONFIG_BLK_DEV_IDE_MODES /* * Standard (generic) timings for PIO modes, from ATA2 specification. @@ -111,6 +111,8 @@ { "ST3600A", 1 }, { "ST3290A", 0 }, { "ST3144A", 0 }, + { "ST3491A", 1 }, /* reports 3, should be 1 or 2 (depending on */ + /* drive) according to Seagates FIND-ATA program */ { "QUANTUM ELS127A", 0 }, { "QUANTUM ELS170A", 0 }, @@ -222,5 +224,5 @@ } #endif /* _IDE_C */ -#endif /* defined(CONFIG_BLK_DEV_CMD640) || defined(CONFIG_IDE_CHIPSETS) || defined(CONFIG_BLK_DEV_OPTI621) */ +#endif /* CONFIG_BLK_DEV_IDE_MODES */ #endif /* _IDE_MODES_H */ diff -u --recursive --new-file v2.3.0/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v2.3.0/linux/drivers/block/ll_rw_blk.c Thu Mar 11 23:20:14 1999 +++ linux/drivers/block/ll_rw_blk.c Tue May 11 14:37:40 1999 @@ -53,7 +53,7 @@ /* * used to wait on when there are no free requests */ -struct wait_queue * wait_for_request = NULL; +DECLARE_WAIT_QUEUE_HEAD(wait_for_request); /* This specifies how many sectors to read ahead on the disk. */ @@ -208,7 +208,7 @@ static struct request * __get_request_wait(int n, kdev_t dev) { register struct request *req; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long flags; add_wait_queue(&wait_for_request, &wait); diff -u --recursive --new-file v2.3.0/linux/drivers/block/macide.c linux/drivers/block/macide.c --- v2.3.0/linux/drivers/block/macide.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/macide.c Thu May 13 11:04:54 1999 @@ -0,0 +1,167 @@ +/* + * linux/drivers/block/macide.c -- Macintosh IDE Driver + * + * Copyright (C) 1998 by Michael Schmitz + * + * This driver was written based on information obtained from the MacOS IDE + * driver binary by Mikael Forselius + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + /* + * Base of the IDE interface (see ATAManager ROM code) + */ + +#define MAC_HD_BASE 0x50f1a000 + + /* + * Offsets from the above base (scaling 4) + */ + +#define MAC_HD_DATA 0x00 +#define MAC_HD_ERROR 0x04 /* see err-bits */ +#define MAC_HD_NSECTOR 0x08 /* nr of sectors to read/write */ +#define MAC_HD_SECTOR 0x0c /* starting sector */ +#define MAC_HD_LCYL 0x10 /* starting cylinder */ +#define MAC_HD_HCYL 0x14 /* high byte of starting cyl */ +#define MAC_HD_SELECT 0x18 /* 101dhhhh , d=drive, hhhh=head */ +#define MAC_HD_STATUS 0x1c /* see status-bits */ +#define MAC_HD_CONTROL 0x38 /* control/altstatus */ + +static int macide_offsets[IDE_NR_PORTS] = { + MAC_HD_DATA, MAC_HD_ERROR, MAC_HD_NSECTOR, MAC_HD_SECTOR, MAC_HD_LCYL, + MAC_HD_HCYL, MAC_HD_SELECT, MAC_HD_STATUS, MAC_HD_CONTROL +}; + + /* + * Other registers + */ + + /* + * IDE interrupt status register for both (?) hwifs on Quadra + * Initial setting: 0xc + * Guessing again: + * Bit 0+1: some interrupt flags + * Bit 2+3: some interrupt enable + * Bit 4: ?? + * Bit 5: IDE interrupt flag (any hwif) + * Bit 6: maybe IDE interrupt enable (any hwif) ?? + * Bit 7: Any interrupt condition + * + * Only relevant item: bit 5, to be checked by mac_ack_intr + */ + +#define MAC_HD_ISR 0x101 + + /* + * IDE interrupt glue - seems to be wired to Nubus, Slot C? + * (ROM code disassembly again) + * First try: just use Nubus interrupt for Slot C. Have Nubus code call + * a wrapper to ide_intr that checks the ISR (see above). + * Need to #define IDE_IRQ_NUBUS though. + * Alternative method: set a mac_ide_hook function pointer to the wrapper + * here and have via_do_nubus call that hook if set. + * + * Quadra needs the hook, Powerbook can use Nubus slot C. + * Checking the ISR on Quadra is done by mac_ack_intr (see Amiga code). mac_ide_intr + * mac_ide_intr is obsolete except for providing the hwgroup argument. + */ + + /* The Mac hwif data, for passing hwgroup to ide_intr */ +static ide_hwif_t *mac_hwif = NULL; + + /* The function pointer used in the Nubus handler */ +void (*mac_ide_intr_hook)(int, void *, struct pt_regs *) = NULL; + + /* + * Only purpose: feeds the hwgroup to the main IDE handler. + * Obsolete as soon as Nubus code is fixed WRT pseudo slot C int. + * (should be the case on Powerbooks) + * Alas, second purpose: feed correct irq to IDE handler (I know, + * that's cheating) :-((( + * Fix needed for interrupt code: accept Nubus ints in the regular + * request_irq code, then register Powerbook IDE as Nubus slot C, + * Quadra as slot F (F for fictious). + */ +void mac_ide_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + ide_intr(mac_hwif->irq, mac_hwif->hwgroup, regs); +} + + /* + * Check the interrupt status + * + * Note: In 2.0 kernels, there have been timing problems with the + * Powerbook IDE interface (BUSY was asserted too long after the + * interrupt triggered). Result: repeated errors, recalibrate etc. + * Adding a wait loop to read_intr, write_intr and set_geom_intr + * fixed the problem (waits in read/write_intr were present for Amiga + * already). + * Powerbooks were not tested with 2.1 due to lack of FPU emulation + * (thanks Apple for using LC040). If the BUSY problem resurfaces in + * 2.1, my best bet would be to add the wait loop right here, afterr + * checking the interrupt register. + */ + +static int mac_ack_intr(ide_hwif_t *hwif) +{ + unsigned char ch; + + ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]); + if (!(ch & 0x20)) + return 0; + return 1; +} + + /* + * Probe for a Macintosh IDE interface + */ + +void macide_init(void) +{ + hw_regs_t hw; + int index = -1; + + if (MACH_IS_MAC) { + switch(macintosh_config->ide_type) { + case 0: + break; + + case MAC_IDE_QUADRA: + ide_setup_ports(&hw, (ide_ioreg_t)MAC_HD_BASE, macide_offsets, + 0, (ide_ioreg_t)(MAC_HD_BASE+MAC_HD_ISR), + mac_ack_intr, IRQ_MAC_NUBUS); + index = ide_register_hw(&hw, &mac_hwif); + mac_ide_intr_hook = mac_ide_intr; + break; + + default: + ide_setup_ports(&hw, (ide_ioreg_t)MAC_HD_BASE, macide_offsets, + 0, 0, NULL, IRQ_MAC_NUBUS); + index = ide_register_hw(&hw, &mac_hwif); + break; + } + + if (index != -1) { + if (macintosh_config->ide_type == MAC_IDE_QUADRA) + printk("ide%d: Macintosh Quadra IDE interface\n", index); + else + printk("ide%d: Macintosh Powerbook IDE interface\n", index); + } + } +} diff -u --recursive --new-file v2.3.0/linux/drivers/block/md.c linux/drivers/block/md.c --- v2.3.0/linux/drivers/block/md.c Sat Oct 31 10:37:14 1998 +++ linux/drivers/block/md.c Wed May 12 08:41:12 1999 @@ -817,12 +817,12 @@ struct md_thread *thread = (struct md_thread *) kmalloc(sizeof(struct md_thread), GFP_KERNEL); int ret; - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); if (!thread) return NULL; memset(thread, 0, sizeof(struct md_thread)); - init_waitqueue(&thread->wqueue); + init_waitqueue_head(&thread->wqueue); thread->sem = &sem; thread->run = run; @@ -838,7 +838,7 @@ void md_unregister_thread (struct md_thread *thread) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); thread->sem = &sem; thread->run = NULL; diff -u --recursive --new-file v2.3.0/linux/drivers/block/nbd.c linux/drivers/block/nbd.c --- v2.3.0/linux/drivers/block/nbd.c Tue Mar 9 16:58:05 1999 +++ linux/drivers/block/nbd.c Wed May 12 08:41:12 1999 @@ -75,7 +75,7 @@ nbdev = &nbd_dev[dev]; nbd_dev[dev].refcnt++; if (!(nbdev->flags & NBD_INITIALISED)) { - nbdev->queue_lock = MUTEX; + init_MUTEX(&nbdev->queue_lock); nbdev->flags |= NBD_INITIALISED; } MOD_INC_USE_COUNT; diff -u --recursive --new-file v2.3.0/linux/drivers/block/ns87415.c linux/drivers/block/ns87415.c --- v2.3.0/linux/drivers/block/ns87415.c Mon Mar 15 16:11:29 1999 +++ linux/drivers/block/ns87415.c Thu May 13 11:04:54 1999 @@ -17,9 +17,9 @@ #include #include #include -#include -#include "ide.h" +#include +#include static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; diff -u --recursive --new-file v2.3.0/linux/drivers/block/opti621.c linux/drivers/block/opti621.c --- v2.3.0/linux/drivers/block/opti621.c Mon Jan 4 15:07:27 1999 +++ linux/drivers/block/opti621.c Thu May 13 11:04:54 1999 @@ -98,8 +98,10 @@ #include #include #include +#include + #include -#include "ide.h" + #include "ide_modes.h" #define OPTI621_MAX_PIO 3 diff -u --recursive --new-file v2.3.0/linux/drivers/block/paride/paride.c linux/drivers/block/paride/paride.c --- v2.3.0/linux/drivers/block/paride/paride.c Tue Dec 22 08:29:00 1998 +++ linux/drivers/block/paride/paride.c Wed May 12 13:27:37 1999 @@ -247,7 +247,7 @@ pi->pardev = (void *) parport_register_device( pp,pi->device,NULL,pi_wake_up,NULL,0,(void *)pi); - pi->parq = NULL; + init_wait_queue_head(&pi->parq); if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port,pp->name); @@ -357,7 +357,7 @@ pi->parname = NULL; pi->pardev = NULL; - pi->parq = NULL; + init_wait_queue_head(&pi->parq); pi->claimed = 0; pi->claim_cont = NULL; diff -u --recursive --new-file v2.3.0/linux/drivers/block/paride/paride.h linux/drivers/block/paride/paride.h --- v2.3.0/linux/drivers/block/paride/paride.h Sat Jun 13 12:08:19 1998 +++ linux/drivers/block/paride/paride.h Wed May 12 13:27:37 1999 @@ -44,7 +44,7 @@ int reserved; /* number of ports reserved */ int private; /* for protocol module */ - struct wait_queue *parq; /* semaphore for parport sharing */ + wait_queue_head_t parq; /* semaphore for parport sharing */ void *pardev; /* pointer to pardevice */ char *parname; /* parport name */ int claimed; /* parport has already been claimed */ diff -u --recursive --new-file v2.3.0/linux/drivers/block/pdc202xx.c linux/drivers/block/pdc202xx.c --- v2.3.0/linux/drivers/block/pdc202xx.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/pdc202xx.c Thu May 13 11:04:54 1999 @@ -0,0 +1,568 @@ +/* + * linux/drivers/block/pdc202xx.c Version 0.26 May 12, 1999 + * + * Copyright (C) 1998-99 Andre Hedrick + * (hedrick@astro.dyer.vanderbilt.edu) + * + * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this + * compiled into the kernel if you have more than one card installed. + * Note that BIOS v1.29 is reported to fix the problem. Since this is + * safe chipset tuning, including this support is harmless + * + * The latest chipset code will support the following :: + * Three Ultra33 controllers and 12 drives. + * 8 are UDMA supported and 4 are limited to DMA mode 2 multi-word. + * The 8/4 ratio is a BIOS code limit by promise. + * + * UNLESS you enable "PDC202XX_FORCE_BURST_BIT" + * + * There is only one BIOS in the three contollers. + * + * May 8 20:56:17 Orion kernel: + * Uniform Multi-Platform E-IDE driver Revision: 6.19 + * PDC20246: IDE controller on PCI bus 00 dev a0 + * PDC20246: not 100% native mode: will probe irqs later + * PDC20246: ROM enabled at 0xfebd0000 + * PDC20246: (U)DMA Burst Bit ENABLED Primary PCI Mode Secondary PCI Mode. + * ide0: BM-DMA at 0xef80-0xef87, BIOS settings: hda:DMA, hdb:DMA + * ide1: BM-DMA at 0xef88-0xef8f, BIOS settings: hdc:pio, hdd:pio + * PDC20246: IDE controller on PCI bus 00 dev 98 + * PDC20246: not 100% native mode: will probe irqs later + * PDC20246: ROM enabled at 0xfebc0000 + * PDC20246: (U)DMA Burst Bit ENABLED Primary PCI Mode Secondary PCI Mode. + * ide2: BM-DMA at 0xef40-0xef47, BIOS settings: hde:DMA, hdf:DMA + * ide3: BM-DMA at 0xef48-0xef4f, BIOS settings: hdg:DMA, hdh:DMA + * PDC20246: IDE controller on PCI bus 00 dev 90 + * PDC20246: not 100% native mode: will probe irqs later + * PDC20246: ROM enabled at 0xfebb0000 + * PDC20246: (U)DMA Burst Bit DISABLED Primary PCI Mode Secondary PCI Mode. + * PDC20246: FORCING BURST BIT 0x00 -> 0x01 ACTIVE + * ide4: BM-DMA at 0xef00-0xef07, BIOS settings: hdi:DMA, hdj:pio + * ide5: BM-DMA at 0xef08-0xef0f, BIOS settings: hdk:pio, hdl:pio + * PIIX3: IDE controller on PCI bus 00 dev 39 + * PIIX3: device not capable of full native PCI mode + * + * ide0 at 0xeff0-0xeff7,0xefe6 on irq 19 + * ide1 at 0xefa8-0xefaf,0xebe6 on irq 19 + * ide2 at 0xefa0-0xefa7,0xef7e on irq 18 + * ide3 at 0xef68-0xef6f,0xef66 on irq 18 + * ide4 at 0xef38-0xef3f,0xef62 on irq 17 + * hda: QUANTUM FIREBALL ST6.4A, 6149MB w/81kB Cache, CHS=13328/15/63, UDMA(33) + * hdb: QUANTUM FIREBALL ST3.2A, 3079MB w/81kB Cache, CHS=6256/16/63, UDMA(33) + * hde: Maxtor 72004 AP, 1916MB w/128kB Cache, CHS=3893/16/63, DMA + * hdf: Maxtor 71626 A, 1554MB w/64kB Cache, CHS=3158/16/63, DMA + * hdi: Maxtor 90680D4, 6485MB w/256kB Cache, CHS=13176/16/63, UDMA(33) + * hdj: Maxtor 90680D4, 6485MB w/256kB Cache, CHS=13176/16/63, UDMA(33) + * + * Promise Ultra66 cards with BIOS v1.11 this + * compiled into the kernel if you have more than one card installed. + * + * PDC20262: IDE controller on PCI bus 00 dev a0 + * PDC20262: not 100% native mode: will probe irqs later + * PDC20262: ROM enabled at 0xfebb0000 + * PDC20262: (U)DMA Burst Bit ENABLED Primary PCI Mode Secondary PCI Mode. + * ide0: BM-DMA at 0xef00-0xef07, BIOS settings: hda:pio, hdb:pio + * ide1: BM-DMA at 0xef08-0xef0f, BIOS settings: hdc:pio, hdd:pio + * + * UDMA 4/2 and UDMA 3/1 only differ by the testing bit 13 in word93. + * Chipset timing speeds must be identical + * + * drive_number + * = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); + * = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); + */ + +#include /* for CONFIG_BLK_DEV_IDEPCI */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PDC202XX_DEBUG_DRIVE_INFO 0 +#define PDC202XX_DECODE_REGISTER_INFO 0 +#define PDC202XX_FORCE_BURST_BIT 0 +#define PDC202XX_FORCE_MASTER_MODE 0 + +extern char *ide_xfer_verbose (byte xfer_rate); + +/* A Register */ +#define SYNC_ERRDY_EN 0xC0 + +#define SYNC_IN 0x80 /* control bit, different for master vs. slave drives */ +#define ERRDY_EN 0x40 /* control bit, different for master vs. slave drives */ +#define IORDY_EN 0x20 /* PIO: IOREADY */ +#define PREFETCH_EN 0x10 /* PIO: PREFETCH */ + +#define PA3 0x08 /* PIO"A" timing */ +#define PA2 0x04 /* PIO"A" timing */ +#define PA1 0x02 /* PIO"A" timing */ +#define PA0 0x01 /* PIO"A" timing */ + +/* B Register */ + +#define MB2 0x80 /* DMA"B" timing */ +#define MB1 0x40 /* DMA"B" timing */ +#define MB0 0x20 /* DMA"B" timing */ + +#define PB4 0x10 /* PIO_FORCE 1:0 */ + +#define PB3 0x08 /* PIO"B" timing */ /* PIO flow Control mode */ +#define PB2 0x04 /* PIO"B" timing */ /* PIO 4 */ +#define PB1 0x02 /* PIO"B" timing */ /* PIO 3 half */ +#define PB0 0x01 /* PIO"B" timing */ /* PIO 3 other half */ + +/* C Register */ +#define IORDYp_NO_SPEED 0x4F +#define SPEED_DIS 0x0F + +#define DMARQp 0x80 +#define IORDYp 0x40 +#define DMAR_EN 0x20 +#define DMAW_EN 0x10 + +#define MC3 0x08 /* DMA"C" timing */ +#define MC2 0x04 /* DMA"C" timing */ +#define MC1 0x02 /* DMA"C" timing */ +#define MC0 0x01 /* DMA"C" timing */ + +#if PDC202XX_DECODE_REGISTER_INFO + +#define REG_A 0x01 +#define REG_B 0x02 +#define REG_C 0x04 +#define REG_D 0x08 + +static void decode_registers (byte registers, byte value) +{ + byte bit = 0, bit1 = 0, bit2 = 0; + + switch(registers) { + case REG_A: + bit2 = 0; + printk("A Register "); + if (value & 0x80) printk("SYNC_IN "); + if (value & 0x40) printk("ERRDY_EN "); + if (value & 0x20) printk("IORDY_EN "); + if (value & 0x10) printk("PREFETCH_EN "); + if (value & 0x08) { printk("PA3 ");bit2 |= 0x08; } + if (value & 0x04) { printk("PA2 ");bit2 |= 0x04; } + if (value & 0x02) { printk("PA1 ");bit2 |= 0x02; } + if (value & 0x01) { printk("PA0 ");bit2 |= 0x01; } + printk("PIO(A) = %d ", bit2); + break; + case REG_B: + bit1 = 0;bit2 = 0; + printk("B Register "); + if (value & 0x80) { printk("MB2 ");bit1 |= 0x80; } + if (value & 0x40) { printk("MB1 ");bit1 |= 0x40; } + if (value & 0x20) { printk("MB0 ");bit1 |= 0x20; } + printk("DMA(B) = %d ", bit1 >> 5); + if (value & 0x10) printk("PIO_FORCED/PB4 "); + if (value & 0x08) { printk("PB3 ");bit2 |= 0x08; } + if (value & 0x04) { printk("PB2 ");bit2 |= 0x04; } + if (value & 0x02) { printk("PB1 ");bit2 |= 0x02; } + if (value & 0x01) { printk("PB0 ");bit2 |= 0x01; } + printk("PIO(B) = %d ", bit2); + break; + case REG_C: + bit2 = 0; + printk("C Register "); + if (value & 0x80) printk("DMARQp "); + if (value & 0x40) printk("IORDYp "); + if (value & 0x20) printk("DMAR_EN "); + if (value & 0x10) printk("DMAW_EN "); + + if (value & 0x08) { printk("MC3 ");bit2 |= 0x08; } + if (value & 0x04) { printk("MC2 ");bit2 |= 0x04; } + if (value & 0x02) { printk("MC1 ");bit2 |= 0x02; } + if (value & 0x01) { printk("MC0 ");bit2 |= 0x01; } + printk("DMA(C) = %d ", bit2); + break; + case REG_D: + printk("D Register "); + break; + default: + return; + } + printk("\n %s ", (registers & REG_D) ? "DP" : + (registers & REG_C) ? "CP" : + (registers & REG_B) ? "BP" : + (registers & REG_A) ? "AP" : "ERROR"); + for (bit=128;bit>0;bit/=2) + printk("%s", (value & bit) ? "1" : "0"); + printk("\n"); +} + +#endif /* PDC202XX_DECODE_REGISTER_INFO */ + +static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) +{ + struct hd_driveid *id = drive->id; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + + int err; + unsigned int drive_conf; + byte drive_pci; + byte test1, test2, speed; + byte AP, BP, CP, DP, EP; + int drive_number = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); + byte udma_66 = ((id->word93 & 0x2000) && (dev->device == PCI_DEVICE_ID_PROMISE_20262)) ? 1 : 0; + byte udma_33 = ultra ? (inb((dev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK) + 0x001f) & 1) : 0; + + pci_read_config_byte(dev, 0x50, &EP); + + switch(drive_number) { + case 0: drive_pci = 0x60; + pci_read_config_dword(dev, drive_pci, &drive_conf); + if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4)) + goto chipset_is_set; + pci_read_config_byte(dev, (drive_pci), &test1); + if (!(test1 & SYNC_ERRDY_EN)) + pci_write_config_byte(dev, (drive_pci), test1|SYNC_ERRDY_EN); + break; + case 1: drive_pci = 0x64; + pci_read_config_dword(dev, drive_pci, &drive_conf); + if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4)) + goto chipset_is_set; + pci_read_config_byte(dev, 0x60, &test1); + pci_read_config_byte(dev, (drive_pci), &test2); + if ((test1 & SYNC_ERRDY_EN) && !(test2 & SYNC_ERRDY_EN)) + pci_write_config_byte(dev, (drive_pci), test2|SYNC_ERRDY_EN); + break; + case 2: drive_pci = 0x68; + pci_read_config_dword(dev, drive_pci, &drive_conf); + if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4)) + goto chipset_is_set; + pci_read_config_byte(dev, (drive_pci), &test1); + if (!(test1 & SYNC_ERRDY_EN)) + pci_write_config_byte(dev, (drive_pci), test1|SYNC_ERRDY_EN); + break; + case 3: drive_pci = 0x6c; + pci_read_config_dword(dev, drive_pci, &drive_conf); + if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4)) + goto chipset_is_set; + pci_read_config_byte(dev, 0x68, &test1); + pci_read_config_byte(dev, (drive_pci), &test2); + if ((test1 & SYNC_ERRDY_EN) && !(test2 & SYNC_ERRDY_EN)) + pci_write_config_byte(dev, (drive_pci), test2|SYNC_ERRDY_EN); + break; + default: + return ide_dma_off; + } + + if (drive->media != ide_disk) + return ide_dma_off_quietly; + + pci_read_config_byte(dev, (drive_pci), &AP); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + pci_read_config_byte(dev, (drive_pci)|0x03, &DP); + + if (id->capability & 4) { /* IORDY_EN */ + pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN); + pci_read_config_byte(dev, (drive_pci), &AP); + } + + if (drive->media == ide_disk) { /* PREFETCH_EN */ + pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); + pci_read_config_byte(dev, (drive_pci), &AP); + } + + if ((BP & 0xF0) && (CP & 0x0F)) { + /* clear DMA modes of upper 842 bits of B Register */ + /* clear PIO forced mode upper 1 bit of B Register */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0xF0); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + + /* clear DMA modes of lower 8421 bits of C Register */ + pci_write_config_byte(dev, (drive_pci)|0x02, CP & ~0x0F); + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + } + + pci_read_config_byte(dev, (drive_pci), &AP); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + + if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) { + if (!((id->dma_ultra >> 8) & 16)) { + drive->id->dma_ultra &= ~0xFF00; + drive->id->dma_ultra |= 0x1010; + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + } + /* speed 8 == UDMA mode 4 == speed 6 plus cable */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x20); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x01); + speed = XFER_UDMA_4; + } else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) { + if (!((id->dma_ultra >> 8) & 8)) { + drive->id->dma_ultra &= ~0xFF00; + drive->id->dma_ultra |= 0x0808; + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + } + /* speed 7 == UDMA mode 3 == speed 5 plus cable */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x40); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x02); + speed = XFER_UDMA_3; + } else if ((id->dma_ultra & 0x0004) && (udma_33)) { + if (!((id->dma_ultra >> 8) & 4)) { + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_ultra |= 0x0404; + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + } + /* speed 6 == UDMA mode 2 */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x20); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x01); + speed = XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0002) && (udma_33)) { + if (!((id->dma_ultra >> 8) & 2)) { + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_ultra |= 0x0202; + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + } + /* speed 5 == UDMA mode 1 */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x40); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x02); + speed = XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0001) && (udma_33)) { + if (!((id->dma_ultra >> 8) & 1)) { + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_ultra |= 0x0101; + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + } + /* speed 4 == UDMA mode 0 */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x60); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x03); + speed = XFER_UDMA_0; + } else if (id->dma_mword & 0x0004) { + if (!((id->dma_mword >> 8) & 4)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_mword |= 0x0404; + drive->id->dma_1word &= ~0x0F00; + } + /* speed 4 == DMA mode 2 multi-word */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x60); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x03); + speed = XFER_MW_DMA_2; + } else if (id->dma_mword & 0x0002) { + if (!((id->dma_mword >> 8) & 2)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_mword |= 0x0202; + drive->id->dma_1word &= ~0x0F00; + } + /* speed 3 == DMA mode 1 multi-word */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x60); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x04); + speed = XFER_MW_DMA_1; + } else if (id->dma_mword & 0x0001) { + if (!((id->dma_mword >> 8) & 1)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_mword |= 0x0101; + drive->id->dma_1word &= ~0x0F00; + } + /* speed 2 == DMA mode 0 multi-word */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x60); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x05); + speed = XFER_MW_DMA_0; + } else if (id->dma_1word & 0x0004) { + if (!((id->dma_1word >> 8) & 4)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + drive->id->dma_1word |= 0x0404; + } + /* speed 2 == DMA mode 2 single-word */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x60); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x05); + speed = XFER_SW_DMA_2; + } else if (id->dma_1word & 0x0002) { + if (!((id->dma_1word >> 8) & 2)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + drive->id->dma_1word |= 0x0202; + } + /* speed 1 == DMA mode 1 single-word */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x80); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x06); + speed = XFER_SW_DMA_1; + } else if (id->dma_1word & 0x0001) { + if (!((id->dma_1word >> 8) & 1)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; + drive->id->dma_1word |= 0x0101; + } + /* speed 0 == DMA mode 0 single-word */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP|0xC0); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x0B); + speed = XFER_SW_DMA_0; + } else { + /* restore original pci-config space */ + pci_write_config_dword(dev, drive_pci, drive_conf); + return ide_dma_off_quietly; + } + + err = ide_wait_cmd(drive, WIN_SETFEATURES, speed, SETFEATURES_XFER, 0, NULL); + +#if PDC202XX_DECODE_REGISTER_INFO + pci_read_config_byte(dev, (drive_pci), &AP); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + + decode_registers(REG_A, AP); + decode_registers(REG_B, BP); + decode_registers(REG_C, CP); + decode_registers(REG_D, DP); +#endif /* PDC202XX_DECODE_REGISTER_INFO */ + +#if PDC202XX_DEBUG_DRIVE_INFO + printk("%s: %s drive%d 0x%08x ", + drive->name, ide_xfer_verbose(speed), + drive_number, drive_conf); + pci_read_config_dword(dev, drive_pci, &drive_conf); + printk("0x%08x\n", drive_conf); +#endif /* PDC202XX_DEBUG_DRIVE_INFO */ + +chipset_is_set: + + return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + ((id->dma_ultra >> 8) & 7) ? ide_dma_on : + ((id->dma_mword >> 8) & 7) ? ide_dma_on : + ((id->dma_1word >> 8) & 7) ? ide_dma_on : + ide_dma_off_quietly); +} + +/* 0 1 2 3 4 5 6 7 8 + * 960, 480, 390, 300, 240, 180, 120, 90, 60 + * 180, 150, 120, 90, 60 + * DMA_Speed + * 180, 120, 90, 90, 90, 60, 30 + * 11, 5, 4, 3, 2, 1, 0 + */ + +static int config_drive_xfer_rate (ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + ide_hwif_t *hwif = HWIF(drive); + ide_dma_action_t dma_func = ide_dma_off_quietly; + + if (id && (id->capability & 1) && hwif->autodma) { + /* Consult the list of known "bad" drives */ + if (ide_dmaproc(ide_dma_bad_drive, drive)) { + return HWIF(drive)->dmaproc(ide_dma_off, drive); + } + + if (id->field_valid & 4) { + if (id->dma_ultra & 0x001F) { + /* Force if Capable UltraDMA */ + dma_func = config_chipset_for_dma(drive, 1); + if ((id->field_valid & 2) && + (dma_func != ide_dma_on)) + goto try_dma_modes; + } + } else if (id->field_valid & 2) { +try_dma_modes: + if ((id->dma_mword & 0x0004) || + (id->dma_1word & 0x0004)) { + /* Force if Capable regular DMA modes */ + dma_func = config_chipset_for_dma(drive, 0); + } + } else if ((ide_dmaproc(ide_dma_good_drive, drive)) && + (id->eide_dma_time > 150)) { + /* Consult the list of known "good" drives */ + dma_func = config_chipset_for_dma(drive, 0); + } + } + return HWIF(drive)->dmaproc(dma_func, drive); +} + +/* + * pdc202xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive. + */ +int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) +{ + switch (func) { + case ide_dma_check: + return config_drive_xfer_rate(drive); + default: + break; + } + return ide_dmaproc(func, drive); /* use standard DMA stuff */ +} + +__initfunc(unsigned int pci_init_pdc202xx (struct pci_dev *dev, const char *name)) +{ + unsigned long high_16 = dev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK; + byte udma_speed_flag = inb(high_16 + 0x001f); + byte primary_mode = inb(high_16 + 0x001a); + byte secondary_mode = inb(high_16 + 0x001b); + + if (dev->rom_address) { + pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->rom_address | PCI_ROM_ADDRESS_ENABLE); + printk("%s: ROM enabled at 0x%08lx\n", name, dev->rom_address); + } + + if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { + byte irq = 0, irq2 = 0; + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); /* 0xbc */ + if (irq != irq2) { + pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */ + printk("%s: pci-config space interrupt mirror fixed.\n", name); + } + } + + printk("%s: (U)DMA Burst Bit %sABLED " \ + "Primary %s Mode " \ + "Secondary %s Mode.\n", + name, + (udma_speed_flag & 1) ? "EN" : "DIS", + (primary_mode & 1) ? "MASTER" : "PCI", + (secondary_mode & 1) ? "MASTER" : "PCI" ); + +#if PDC202XX_FORCE_BURST_BIT + if (!(udma_speed_flag & 1)) { + printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", name, udma_speed_flag, (udma_speed_flag|1)); + outb(udma_speed_flag|1, high_16 + 0x001f); + printk("%sCTIVE\n", (inb(high_16 + 0x001f) & 1) ? "A" : "INA"); + } +#endif /* PDC202XX_FORCE_BURST_BIT */ + +#if PDC202XX_FORCE_MASTER_MODE + if (!(primary_mode & 1)) { + printk("%s: FORCING PRIMARY MODE BIT 0x%02x -> 0x%02x ", + name, primary_mode, (primary_mode|1)); + outb(primary_mode|1, high_16 + 0x001a); + printk("%s\n", (inb(high_16 + 0x001a) & 1) ? "MASTER" : "PCI"); + } + + if (!(secondary_mode & 1)) { + printk("%s: FORCING SECONDARY MODE BIT 0x%02x -> 0x%02x ", + name, secondary_mode, (secondary_mode|1)); + outb(secondary_mode|1, high_16 + 0x001b); + printk("%s\n", (inb(high_16 + 0x001b) & 1) ? "MASTER" : "PCI"); + } +#endif /* PDC202XX_FORCE_MASTER_MODE */ + return dev->irq; +} + +__initfunc(void ide_init_pdc202xx (ide_hwif_t *hwif)) +{ + if (hwif->dma_base) { + hwif->dmaproc = &pdc202xx_dmaproc; + } +} diff -u --recursive --new-file v2.3.0/linux/drivers/block/pdc4030.c linux/drivers/block/pdc4030.c --- v2.3.0/linux/drivers/block/pdc4030.c Tue Dec 29 11:24:57 1998 +++ linux/drivers/block/pdc4030.c Thu May 13 11:04:54 1999 @@ -1,17 +1,18 @@ /* -*- linux-c -*- - * linux/drivers/block/pdc4030.c Version 0.08 Nov 30, 1997 + * linux/drivers/block/pdc4030.c Version 0.10 Jan 25, 1999 * - * Copyright (C) 1995-1998 Linus Torvalds & authors (see below) + * Copyright (C) 1995-1999 Linus Torvalds & authors (see below) */ /* * Principal Author/Maintainer: peterd@pnd-pc.demon.co.uk * * This file provides support for the second port and cache of Promise - * IDE interfaces, e.g. DC4030, DC5030. + * IDE interfaces, e.g. DC4030VL, DC4030VL-1 and DC4030VL-2. * * Thanks are due to Mark Lord for advice and patiently answering stupid - * questions, and all those mugs^H^H^H^Hbrave souls who've tested this. + * questions, and all those mugs^H^H^H^Hbrave souls who've tested this, + * especially Andre Hedrick. * * Version 0.01 Initial version, #include'd in ide.c rather than * compiled separately. @@ -29,6 +30,9 @@ * Version 0.07 Added support for DC4030 variants * Secondary interface autodetection * Version 0.08 Renamed to pdc4030.c + * Version 0.09 Obsolete - never released - did manual write request + * splitting before max_sectors[major][minor] available. + * Version 0.10 Updated for 2.1 series of kernels */ /* @@ -37,12 +41,17 @@ * * 'linux ide0=dc4030' * - * As before, it seems that somewhere around 3Megs when writing, bad things - * start to happen [timeouts/retries -ml]. If anyone can give me more feedback, - * I'd really appreciate it. [email: peterd@pnd-pc.demon.co.uk] + * It should now work as a second controller also ('ide1=dc4030') but only + * if you DON'T have BIOS V4.44, which has a bug. If you have this and EPROM + * programming facilities, I can tell you what to fix... * + * As of January 1999, Promise Technology Inc. have finally supplied me with + * some technical information which has shed a glimmer of light on some of the + * problems I was having, especially with writes. */ +#define DEBUG_READ +#define DEBUG_WRITE #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -54,9 +63,11 @@ #include #include #include +#include + #include #include -#include "ide.h" + #include "pdc4030.h" /* This is needed as the controller may not interrupt if the required data is @@ -124,40 +135,48 @@ { ide_hwif_t *hwif = hwif_required; ide_drive_t *drive; - ide_hwif_t *second_hwif; + ide_hwif_t *hwif2; struct dc_ident ident; int i; if (!hwif) return 0; drive = &hwif->drives[0]; - second_hwif = &ide_hwifs[hwif->index+1]; - if(hwif->chipset == ide_pdc4030) /* we've already been found ! */ - return 1; - - if(IN_BYTE(IDE_NSECTOR_REG) == 0xFF || IN_BYTE(IDE_SECTOR_REG) == 0xFF) - { - return 0; + hwif2 = &ide_hwifs[hwif->index+1]; + if (hwif->chipset == ide_pdc4030) /* we've already been found ! */ + return 1; + + if (IN_BYTE(IDE_NSECTOR_REG) == 0xFF || IN_BYTE(IDE_SECTOR_REG) == 0xFF) { + return 0; } OUT_BYTE(0x08,IDE_CONTROL_REG); - if(pdc4030_cmd(drive,PROMISE_GET_CONFIG)) { - return 0; + if (pdc4030_cmd(drive,PROMISE_GET_CONFIG)) { + return 0; } - if(ide_wait_stat(drive,DATA_READY,BAD_W_STAT,WAIT_DRQ)) { - printk("%s: Failed Promise read config!\n",hwif->name); - return 0; + if (ide_wait_stat(drive,DATA_READY,BAD_W_STAT,WAIT_DRQ)) { + printk(KERN_INFO + "%s: Failed Promise read config!\n",hwif->name); + return 0; } ide_input_data(drive,&ident,SECTOR_WORDS); - if(ident.id[1] != 'P' || ident.id[0] != 'T') { - return 0; + if (ident.id[1] != 'P' || ident.id[0] != 'T') { + return 0; } - printk("%s: Promise caching controller, ",hwif->name); + printk(KERN_INFO "%s: Promise caching controller, ",hwif->name); switch(ident.type) { - case 0x43: printk("DC4030VL-2, "); break; - case 0x41: printk("DC4030VL-1, "); break; - case 0x40: printk("DC4030VL, "); break; - default: printk("unknown - type 0x%02x - please report!\n" + case 0x43: printk("DC4030VL-2, "); break; + case 0x41: printk("DC4030VL-1, "); break; + case 0x40: printk("DC4030VL, "); break; + default: + printk("unknown - type 0x%02x - please report!\n" ,ident.type); + printk("Please e-mail the following data to " + "promise@pnd-pc.demon.co.uk along with\n" + "a description of your card and drives:\n"); + for (i=0; i < 0x90; i++) { + printk("%02x ", ((unsigned char *)&ident)[i]); + if ((i & 0x0f) == 0x0f) printk("\n"); + } return 0; } printk("%dKB cache, ",(int)ident.cache_mem); @@ -167,27 +186,35 @@ default: hwif->irq = 15; break; } printk("on IRQ %d\n",hwif->irq); - hwif->chipset = second_hwif->chipset = ide_pdc4030; - hwif->mate = second_hwif; - second_hwif->mate = hwif; - second_hwif->channel = 1; - hwif->selectproc = second_hwif->selectproc = &promise_selectproc; + hwif->chipset = hwif2->chipset = ide_pdc4030; + hwif->mate = hwif2; + hwif2->mate = hwif; + hwif2->channel = 1; + hwif->selectproc = hwif2->selectproc = &promise_selectproc; /* Shift the remaining interfaces down by one */ for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) { ide_hwif_t *h = &ide_hwifs[i]; - printk("Shifting i/f %d values to i/f %d\n",i-1,i); - ide_init_hwif_ports(h->io_ports, (h-1)->io_ports[IDE_DATA_OFFSET], NULL); - h->io_ports[IDE_CONTROL_OFFSET] = (h-1)->io_ports[IDE_CONTROL_OFFSET]; +#ifdef DEBUG + printk(KERN_DEBUG "Shifting i/f %d values to i/f %d\n",i-1,i); +#endif + ide_init_hwif_ports(&h->hw, (h-1)->io_ports[IDE_DATA_OFFSET], 0, NULL); + memcpy(h->io_ports, h->hw.io_ports, sizeof(h->io_ports)); h->noprobe = (h-1)->noprobe; } - ide_init_hwif_ports(second_hwif->io_ports, hwif->io_ports[IDE_DATA_OFFSET], NULL); - second_hwif->io_ports[IDE_CONTROL_OFFSET] = hwif->io_ports[IDE_CONTROL_OFFSET]; - second_hwif->irq = hwif->irq; + ide_init_hwif_ports(&hwif2->hw, hwif->io_ports[IDE_DATA_OFFSET], 0, NULL); + memcpy(hwif2->io_ports, hwif->hw.io_ports, sizeof(hwif2->io_ports)); + hwif2->irq = hwif->irq; + hwif2->hw.irq = hwif->hw.irq = hwif->irq; for (i=0; i<2 ; i++) { - hwif->drives[i].io_32bit = 3; - second_hwif->drives[i].io_32bit = 3; - if(!ident.current_tm[i+2].cyl) second_hwif->drives[i].noprobe=1; + hwif->drives[i].io_32bit = 3; + hwif2->drives[i].io_32bit = 3; + hwif->drives[i].keep_settings = 1; + hwif2->drives[i].keep_settings = 1; + if (!ident.current_tm[i].cyl) + hwif->drives[i].noprobe = 1; + if (!ident.current_tm[i+2].cyl) + hwif2->drives[i].noprobe = 1; } return 1; } @@ -198,7 +225,7 @@ static void promise_read_intr (ide_drive_t *drive) { byte stat; - int i; + int total_remaining; unsigned int sectors_left, sectors_avail, nsect; struct request *rq; @@ -209,99 +236,140 @@ read_again: do { - sectors_left = IN_BYTE(IDE_NSECTOR_REG); - IN_BYTE(IDE_SECTOR_REG); + sectors_left = IN_BYTE(IDE_NSECTOR_REG); + IN_BYTE(IDE_SECTOR_REG); } while (IN_BYTE(IDE_NSECTOR_REG) != sectors_left); rq = HWGROUP(drive)->rq; sectors_avail = rq->nr_sectors - sectors_left; + if (!sectors_avail) + goto read_again; read_next: rq = HWGROUP(drive)->rq; - if ((nsect = rq->current_nr_sectors) > sectors_avail) + nsect = rq->current_nr_sectors; + if (nsect > sectors_avail) nsect = sectors_avail; sectors_avail -= nsect; ide_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); -#ifdef DEBUG - printk("%s: promise_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); +#ifdef DEBUG_READ + printk(KERN_DEBUG "%s: promise_read: sectors(%ld-%ld), " + "buf=0x%08lx, rem=%ld\n", drive->name, rq->sector, + rq->sector+nsect-1, (unsigned long) rq->buffer, + rq->nr_sectors-nsect); #endif rq->sector += nsect; rq->buffer += nsect<<9; rq->errors = 0; - i = (rq->nr_sectors -= nsect); - if ((rq->current_nr_sectors -= nsect) <= 0) + rq->nr_sectors -= nsect; + total_remaining = rq->nr_sectors; + if ((rq->current_nr_sectors -= nsect) <= 0) { ide_end_request(1, HWGROUP(drive)); - if (i > 0) { + } +/* + * Now the data has been read in, do the following: + * + * if there are still sectors left in the request, + * if we know there are still sectors available from the interface, + * go back and read the next bit of the request. + * else if DRQ is asserted, there are more sectors available, so + * go back and find out how many, then read them in. + * else if BUSY is asserted, we are going to get an interrupt, so + * set the handler for the interrupt and just return + */ + if (total_remaining > 0) { if (sectors_avail) - goto read_next; + goto read_next; stat = GET_STAT(); - if(stat & DRQ_STAT) - goto read_again; - if(stat & BUSY_STAT) { - ide_set_handler (drive, &promise_read_intr, WAIT_CMD); - return; + if (stat & DRQ_STAT) + goto read_again; + if (stat & BUSY_STAT) { +#ifdef DEBUG_READ + printk(KERN_DEBUG "%s: promise_read: waiting for" + "interrupt\n", drive->name); +#endif + ide_set_handler (drive, &promise_read_intr, WAIT_CMD); + return; } - printk("Ah! promise read intr: sectors left !DRQ !BUSY\n"); + printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left " + "!DRQ !BUSY\n", drive->name); ide_error(drive, "promise read intr", stat); } } /* + * promise_write_intr() + * This interrupt is called after the particularly odd polling for completion + * of the write request, once all the data has been sent. + */ +static void promise_write_intr(ide_drive_t *drive) +{ + byte stat; + int i; + struct request *rq; + + if (!OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)) { + ide_error(drive, "promise_write_intr", stat); + } + +#ifdef DEBUG_WRITE + printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name); +#endif + rq = HWGROUP(drive)->rq; + for (i = rq->nr_sectors; i > 0;) { + i -= rq->current_nr_sectors; + ide_end_request(1, HWGROUP(drive)); + } +} + +/* * promise_write_pollfunc() is the handler for disk write completion polling. */ static void promise_write_pollfunc (ide_drive_t *drive) { - int i; - ide_hwgroup_t *hwgroup = HWGROUP(drive); - struct request *rq; + if (IN_BYTE(IDE_NSECTOR_REG) != 0) { + if (time_before(jiffies, HWGROUP(drive)->poll_timeout)) { + ide_set_handler (drive, &promise_write_pollfunc, 1); + return; /* continue polling... */ + } + printk(KERN_ERR "%s: write timed-out!\n",drive->name); + ide_error (drive, "write timeout", GET_STAT()); + return; + } - if (IN_BYTE(IDE_NSECTOR_REG) != 0) { - if (time_before(jiffies, hwgroup->poll_timeout)) { - ide_set_handler (drive, &promise_write_pollfunc, 1); - return; /* continue polling... */ - } - printk("%s: write timed-out!\n",drive->name); - ide_error (drive, "write timeout", GET_STAT()); - return; - } - +#ifdef DEBUG_WRITE + printk(KERN_DEBUG "%s: Doing last 4 sectors\n", drive->name); +#endif ide_multwrite(drive, 4); - rq = hwgroup->rq; - for (i = rq->nr_sectors; i > 0;) { - i -= rq->current_nr_sectors; - ide_end_request(1, hwgroup); - } - return; + ide_set_handler(drive, &promise_write_intr, WAIT_CMD); + return; } /* * promise_write() transfers a block of one or more sectors of data to a * drive as part of a disk write operation. All but 4 sectors are transfered * in the first attempt, then the interface is polled (nicely!) for completion - * before the final 4 sectors are transfered. Don't ask me why, but this is - * how it's done in the drivers for other O/Ses. There is no interrupt - * generated on writes, which is why we have to do it like this. + * before the final 4 sectors are transfered. The interrupt generated on + * writes occurs after this process, which is why I got it wrong for so long! */ static void promise_write (ide_drive_t *drive) { - ide_hwgroup_t *hwgroup = HWGROUP(drive); - struct request *rq = &hwgroup->wrq; - int i; - - if (rq->nr_sectors > 4) { - ide_multwrite(drive, rq->nr_sectors - 4); - hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; - ide_set_handler (drive, &promise_write_pollfunc, 1); - return; - } else { - ide_multwrite(drive, rq->nr_sectors); - rq = hwgroup->rq; - for (i = rq->nr_sectors; i > 0;) { - i -= rq->current_nr_sectors; - ide_end_request(1, hwgroup); - } - } + ide_hwgroup_t *hwgroup = HWGROUP(drive); + struct request *rq = &hwgroup->wrq; + +#ifdef DEBUG_WRITE + printk(KERN_DEBUG "%s: promise_write: sectors(%ld-%ld), " + "buffer=0x%08lx\n", drive->name, rq->sector, + rq->sector + rq->nr_sectors - 1, rq->buffer); +#endif + if (rq->nr_sectors > 4) { + ide_multwrite(drive, rq->nr_sectors - 4); + hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + ide_set_handler (drive, &promise_write_pollfunc, 1); + return; + } else { + ide_multwrite(drive, rq->nr_sectors); + ide_set_handler(drive, &promise_write_intr, WAIT_CMD); + } } /* @@ -315,43 +383,54 @@ byte stat; if (rq->cmd == READ) { - ide_set_handler(drive, &promise_read_intr, WAIT_CMD); - OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG); -/* The card's behaviour is odd at this point. If the data is - available, DRQ will be true, and no interrupt will be - generated by the card. If this is the case, we need to simulate - an interrupt. Ugh! Otherwise, if an interrupt will occur, bit0 - of the SELECT register will be high, so we can just return and - be interrupted.*/ - timeout = jiffies + HZ/20; /* 50ms wait */ - do { - stat=GET_STAT(); - if(stat & DRQ_STAT) { - disable_irq(HWIF(drive)->irq); - ide_intr(HWIF(drive)->irq,HWGROUP(drive),NULL); - enable_irq(HWIF(drive)->irq); - return; - } - if(IN_BYTE(IDE_SELECT_REG) & 0x01) - return; - udelay(1); - } while (time_before(jiffies, timeout)); - printk("%s: reading: No DRQ and not waiting - Odd!\n", - drive->name); - return; - } - if (rq->cmd == WRITE) { - OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG); - if (ide_wait_stat(drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { - printk("%s: no DRQ after issuing PROMISE_WRITE\n", drive->name); - return; - } - if (!drive->unmask) - __cli(); /* local CPU only */ - HWGROUP(drive)->wrq = *rq; /* scratchpad */ - promise_write(drive); - return; + OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG); +/* + * The card's behaviour is odd at this point. If the data is + * available, DRQ will be true, and no interrupt will be + * generated by the card. If this is the case, we need to call the + * "interrupt" handler (promise_read_intr) directly. Otherwise, if + * an interrupt is going to occur, bit0 of the SELECT register will + * be high, so we can set the handler the just return and be interrupted. + * If neither of these is the case, we wait for up to 50ms (badly I'm + * afraid!) until one of them is. + */ + timeout = jiffies + HZ/20; /* 50ms wait */ + do { + stat=GET_STAT(); + if (stat & DRQ_STAT) { + udelay(1); + promise_read_intr(drive); + return; + } + if (IN_BYTE(IDE_SELECT_REG) & 0x01) { +#ifdef DEBUG_READ + printk(KERN_DEBUG "%s: read: waiting for " + "interrupt\n", drive->name); +#endif + ide_set_handler(drive, &promise_read_intr, WAIT_CMD); + return; + } + udelay(1); + } while (time_before(jiffies, timeout)); + + printk(KERN_ERR "%s: reading: No DRQ and not waiting - Odd!\n", + drive->name); + + } else if (rq->cmd == WRITE) { + OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG); + if (ide_wait_stat(drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { + printk(KERN_ERR "%s: no DRQ after issuing " + "PROMISE_WRITE\n", drive->name); + return; + } + if (!drive->unmask) + __cli(); /* local CPU only */ + HWGROUP(drive)->wrq = *rq; /* scratchpad */ + promise_write(drive); + + } else { + printk("KERN_WARNING %s: bad command: %d\n", + drive->name, rq->cmd); + ide_end_request(0, HWGROUP(drive)); } - printk("%s: bad command: %d\n", drive->name, rq->cmd); - ide_end_request(0, HWGROUP(drive)); } diff -u --recursive --new-file v2.3.0/linux/drivers/block/piix.c linux/drivers/block/piix.c --- v2.3.0/linux/drivers/block/piix.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/piix.c Thu May 13 11:04:54 1999 @@ -0,0 +1,258 @@ +/* + * linux/drivers/block/piix.c Version 0.22 March 29, 1999 + * + * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer + * Copyright (C) 1998-1999 Andre Hedrick, Author and Maintainer + * + * PIO mode setting function for Intel chipsets. + * For use instead of BIOS settings. + * + * 40-41 + * 42-43 + * + * 41 + * 43 + * + * | PIO 0 | c0 | 80 | 0 | + * | PIO 2 | SW2 | d0 | 90 | 4 | + * | PIO 3 | MW1 | e1 | a1 | 9 | + * | PIO 4 | MW2 | e3 | a3 | b | + * + * sitre = word40 & 0x4000; primary + * sitre = word42 & 0x4000; secondary + * + * 44 8421|8421 hdd|hdb + * + * 48 8421 hdd|hdc|hdb|hda udma enabled + * + * 0001 hda + * 0010 hdb + * 0100 hdc + * 1000 hdd + * + * 4a 84|21 hdb|hda + * 4b 84|21 hdd|hdc + * + * 00|00 udma 0 + * 01|01 udma 1 + * 10|10 udma 2 + * 11|11 reserved + * + * pci_read_config_word(HWIF(drive)->pci_dev, 0x40, ®40); + * pci_read_config_word(HWIF(drive)->pci_dev, 0x42, ®42); + * pci_read_config_word(HWIF(drive)->pci_dev, 0x44, ®44); + * pci_read_config_word(HWIF(drive)->pci_dev, 0x48, ®48); + * pci_read_config_word(HWIF(drive)->pci_dev, 0x4a, ®4a); + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ide_modes.h" + +#define PIIX_DMA_PROC 0 +#define PIIX_DEBUG_SET_XFER 0 +#define PIIX_DEBUG_DRIVE_INFO 0 + +/* + * Based on settings done by AMI BIOS + * (might be usefull if drive is not registered in CMOS for any reason). + */ +static void piix_tune_drive (ide_drive_t *drive, byte pio) +{ + unsigned long flags; + u16 master_data; + byte slave_data, speed; + int err; + int is_slave = (&HWIF(drive)->drives[1] == drive); + int master_port = HWIF(drive)->index ? 0x42 : 0x40; + int slave_port = 0x44; + /* ISP RTC */ + byte timings[][2] = { { 0, 0 }, + { 0, 0 }, + { 1, 0 }, + { 2, 1 }, + { 2, 3 }, }; + + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data); + if (is_slave) { + master_data = master_data | 0x4000; + if (pio > 1) + /* enable PPE, IE and TIME */ + master_data = master_data | 0x0070; + pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data); + slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0); + slave_data = slave_data | ((timings[pio][0] << 2) | (timings[pio][1] + << (HWIF(drive)->index ? 4 : 0))); + } else { + master_data = master_data & 0xccf8; + if (pio > 1) + /* enable PPE, IE and TIME */ + master_data = master_data | 0x0007; + master_data = master_data | (timings[pio][0] << 12) | + (timings[pio][1] << 8); + } + save_flags(flags); + cli(); + pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data); + if (is_slave) + pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data); + restore_flags(flags); + + switch(pio) { + case 4: speed = XFER_PIO_4;break; + case 3: speed = XFER_PIO_3;break; + case 2: speed = XFER_PIO_2;break; + case 1: speed = XFER_PIO_1;break; + default: + speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; + break; + } + + err = ide_wait_cmd(drive, WIN_SETFEATURES, speed, SETFEATURES_XFER, 0, NULL); +} + +extern char *ide_xfer_verbose (byte xfer_rate); + +static int piix_config_drive_for_dma(ide_drive_t *drive, int ultra) +{ + struct hd_driveid *id = drive->id; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + + int sitre; + short reg4042, reg44, reg48, reg4a; + byte speed; + int u_speed; + byte maslave = hwif->channel ? 0x42 : 0x40; + int drive_number = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); + int a_speed = 2 << (drive_number * 4); + int u_flag = 1 << drive_number; + + pci_read_config_word(dev, maslave, ®4042); + sitre = (reg4042 & 0x4000) ? 1 : 0; + pci_read_config_word(dev, 0x44, ®44); + pci_read_config_word(dev, 0x48, ®48); + pci_read_config_word(dev, 0x4a, ®4a); + +#if PIIX_DEBUG_SET_XFER + printk("PIIX%s: DMA enable ", + (dev->device == PCI_DEVICE_ID_INTEL_82371FB_0) ? "a" : + (dev->device == PCI_DEVICE_ID_INTEL_82371FB_1) ? "b" : + (dev->device == PCI_DEVICE_ID_INTEL_82371SB_1) ? "3" : + (dev->device == PCI_DEVICE_ID_INTEL_82371AB) ? "4" : " UNKNOWN" ); +#endif /* PIIX_DEBUG_SET_XFER */ + + if (id->dma_ultra && (ultra)) { + if (!(reg48 & u_flag)) { + pci_write_config_word(dev, 0x48, reg48|u_flag); + } + } else { + pci_write_config_word(dev, 0x48, reg48 & ~u_flag); + } + + if ((id->dma_ultra & 0x0004) && (ultra)) { + if (!((id->dma_ultra >> 8) & 4)) { + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_ultra |= 0x0404; + } + u_speed = 2 << (drive_number * 4); + if (!(reg4a & u_speed)) { + pci_write_config_word(dev, 0x4a, reg4a|u_speed); + } + speed = XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0002) && (ultra)) { + if (!((id->dma_ultra >> 8) & 2)) { + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_ultra |= 0x0202; + } + u_speed = 1 << (drive_number * 4); + if (!(reg4a & u_speed)) { + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + pci_write_config_word(dev, 0x4a, reg4a|u_speed); + } + speed = XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0001) && (ultra)) { + if (!((id->dma_ultra >> 8) & 1)) { + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_ultra |= 0x0101; + } + u_speed = 0 << (drive_number * 4); + if (!(reg4a & u_speed)) { + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + pci_write_config_word(dev, 0x4a, reg4a|u_speed); + } + speed = XFER_UDMA_0; + } else if (id->dma_mword & 0x0004) { + drive->id->dma_ultra &= ~0x0F0F; + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + if (!((id->dma_mword >> 8) & 4)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_mword |= 0x0404; + } + speed = XFER_MW_DMA_2; + } else if (id->dma_mword & 0x0002) { + drive->id->dma_ultra &= ~0x0F0F; + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + if (!((id->dma_mword >> 8) & 2)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_mword |= 0x0202; + } + speed = XFER_MW_DMA_1; + } else if (id->dma_1word & 0x0004) { + drive->id->dma_ultra &= ~0x0F0F; + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + if (!((id->dma_1word >> 8) & 4)) { + drive->id->dma_1word &= ~0x0F00; + drive->id->dma_1word |= 0x0404; + } + speed = XFER_SW_DMA_2; + } else { + return ide_dma_off_quietly; + } + + (void) ide_wait_cmd(drive, WIN_SETFEATURES, speed, SETFEATURES_XFER, 0, NULL); + +#if PIIX_DEBUG_DRIVE_INFO + printk("%s: %s drive%d ", + drive->name, + ide_xfer_verbose(speed), + drive_number); + printk("\n"); +#endif /* PIIX_DEBUG_DRIVE_INFO */ + + return ((int) ((id->dma_ultra >> 8) & 7) ? ide_dma_on : + ((id->dma_mword >> 8) & 7) ? ide_dma_on : + ((id->dma_1word >> 8) & 7) ? ide_dma_on : + ide_dma_off_quietly); +} + +static int piix_dmaproc(ide_dma_action_t func, ide_drive_t *drive) +{ + int ultra = (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_INTEL_82371AB) ? 1 : 0; + switch (func) { + case ide_dma_check: + return piix_config_drive_for_dma(drive, ultra); + default : + break; + } + /* Other cases are done by generic IDE-DMA code. */ + return ide_dmaproc(func, drive); +} + +void ide_init_piix (ide_hwif_t *hwif) +{ + hwif->tuneproc = &piix_tune_drive; +#if PIIX_DMA_PROC + hwif->dmaproc = &piix_dmaproc; +#endif /* PIIX_DMA_PROC */ +} diff -u --recursive --new-file v2.3.0/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c --- v2.3.0/linux/drivers/block/ps2esdi.c Thu Jan 14 10:31:41 1999 +++ linux/drivers/block/ps2esdi.c Tue May 11 23:32:10 1999 @@ -108,7 +108,9 @@ u_int dma_arb_level; /* DMA arbitration level */ -static struct wait_queue *ps2esdi_int = NULL, *ps2esdi_wait_open = NULL; +static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int); +static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_wait_open); + int no_int_yet; static int access_count[MAX_HD] = {0,}; static char ps2esdi_valid[MAX_HD] = {0,}; diff -u --recursive --new-file v2.3.0/linux/drivers/block/qd6580.c linux/drivers/block/qd6580.c --- v2.3.0/linux/drivers/block/qd6580.c Wed May 6 14:42:54 1998 +++ linux/drivers/block/qd6580.c Thu May 13 11:04:54 1999 @@ -19,8 +19,10 @@ #include #include #include +#include + #include -#include "ide.h" + #include "ide_modes.h" /* diff -u --recursive --new-file v2.3.0/linux/drivers/block/raid5.c linux/drivers/block/raid5.c --- v2.3.0/linux/drivers/block/raid5.c Fri May 8 00:17:13 1998 +++ linux/drivers/block/raid5.c Tue May 11 23:37:51 1999 @@ -91,7 +91,7 @@ void __wait_on_stripe(struct stripe_head *sh) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); PRINTK(("wait_on_stripe %lu\n", sh->sector)); sh->count++; @@ -1395,7 +1395,7 @@ goto abort; memset(raid_conf->stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE); - init_waitqueue(&raid_conf->wait_for_stripe); + init_waitqueue_head(&raid_conf->wait_for_stripe); PRINTK(("raid5_run(%d) called.\n", minor)); for (i = 0; i < mddev->nb_dev; i++) { diff -u --recursive --new-file v2.3.0/linux/drivers/block/rd.c linux/drivers/block/rd.c --- v2.3.0/linux/drivers/block/rd.c Thu Apr 29 11:53:41 1999 +++ linux/drivers/block/rd.c Tue May 11 14:37:40 1999 @@ -482,6 +482,7 @@ memset(&inode, 0, sizeof(inode)); memset(&in_dentry, 0, sizeof(in_dentry)); inode.i_rdev = device; + init_waitqueue_head(&inode.i_wait); infile.f_mode = 1; /* read only */ infile.f_dentry = &in_dentry; in_dentry.d_inode = &inode; @@ -490,6 +491,7 @@ memset(&out_inode, 0, sizeof(out_inode)); memset(&out_dentry, 0, sizeof(out_dentry)); out_inode.i_rdev = ram_device; + init_waitqueue_head(&out_inode.i_wait); outfile.f_mode = 3; /* read/write */ outfile.f_dentry = &out_dentry; out_dentry.d_inode = &out_inode; diff -u --recursive --new-file v2.3.0/linux/drivers/block/rz1000.c linux/drivers/block/rz1000.c --- v2.3.0/linux/drivers/block/rz1000.c Mon Jan 4 15:07:27 1999 +++ linux/drivers/block/rz1000.c Thu May 13 11:04:54 1999 @@ -26,9 +26,10 @@ #include #include #include -#include #include -#include "ide.h" +#include + +#include #ifdef CONFIG_BLK_DEV_IDEPCI diff -u --recursive --new-file v2.3.0/linux/drivers/block/sl82c105.c linux/drivers/block/sl82c105.c --- v2.3.0/linux/drivers/block/sl82c105.c Wed Mar 10 21:48:46 1999 +++ linux/drivers/block/sl82c105.c Thu May 13 11:04:54 1999 @@ -8,11 +8,11 @@ #include #include #include +#include #include #include -#include "ide.h" #include "ide_modes.h" void ide_init_sl82c105(ide_hwif_t *hwif) diff -u --recursive --new-file v2.3.0/linux/drivers/block/swim3.c linux/drivers/block/swim3.c --- v2.3.0/linux/drivers/block/swim3.c Wed Mar 10 21:48:46 1999 +++ linux/drivers/block/swim3.c Tue May 11 23:36:27 1999 @@ -193,7 +193,7 @@ struct timer_list timeout; int timeout_pending; int ejected; - struct wait_queue *wait; + wait_queue_head_t wait; int wanted; struct device_node* media_bay; /* NULL when not in bay */ char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)]; @@ -1132,6 +1132,7 @@ fs->secpertrack = 18; fs->total_secs = 2880; fs->media_bay = mediabay; + init_waitqueue_head(&fs->wait); fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space); memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd)); diff -u --recursive --new-file v2.3.0/linux/drivers/block/trm290.c linux/drivers/block/trm290.c --- v2.3.0/linux/drivers/block/trm290.c Fri Aug 7 17:56:09 1998 +++ linux/drivers/block/trm290.c Thu May 13 11:04:54 1999 @@ -134,11 +134,10 @@ #include #include #include +#include #include -#include "ide.h" - static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) { ide_hwif_t *hwif = HWIF(drive); @@ -185,7 +184,7 @@ break; /* always use PIO for writes */ #endif case ide_dma_read: - if (!(count = ide_build_dmatable(drive))) + if (!(count = ide_build_dmatable(drive, func))) break; /* try PIO instead of DMA */ trm290_prepare_drive(drive, 1); /* select DMA xfer */ outl(virt_to_bus(hwif->dmatable)|reading|writing, hwif->dma_base); diff -u --recursive --new-file v2.3.0/linux/drivers/block/umc8672.c linux/drivers/block/umc8672.c --- v2.3.0/linux/drivers/block/umc8672.c Wed May 6 14:42:54 1998 +++ linux/drivers/block/umc8672.c Thu May 13 11:04:54 1999 @@ -47,8 +47,10 @@ #include #include #include +#include + #include -#include "ide.h" + #include "ide_modes.h" /* diff -u --recursive --new-file v2.3.0/linux/drivers/block/via82c586.c linux/drivers/block/via82c586.c --- v2.3.0/linux/drivers/block/via82c586.c Fri Nov 13 10:29:44 1998 +++ linux/drivers/block/via82c586.c Thu May 13 11:04:54 1999 @@ -1,18 +1,44 @@ /* - * linux/drivers/block/via82c586.c Version 0.01 Aug 16, 1998 + * linux/drivers/block/via82c586.c Version 0.03 Nov. 19, 1998 * - * Copyright (C) 1998 Michel Aubry - * Copyright (C) 1998 Andre Hedrick + * Copyright (C) 1998 Michel Aubry, Maintainer + * Copyright (C) 1998 Andre Hedrick, Integrater * * The VIA MVP-3 is reported OK with UDMA. + * The TX Pro III is also reported OK with UDMA. * - * VIA chips also have a single FIFO, with the same 64 bytes deep buffer (16 levels - * of 4 bytes each). - * However, VIA chips can have the buffer split either 8:8 levels, 16:0 levels or - * 0:16 levels between both channels. One could think of using this feature, as even - * if no level of FIFO is given to a given channel, one can always reach ATAPI drives - * through it, or, if one channel is unused, configuration defaults to an even split - * FIFO levels. + * VIA chips also have a single FIFO, with the same 64 bytes deep + * buffer (16 levels of 4 bytes each). + * + * However, VIA chips can have the buffer split either 8:8 levels, + * 16:0 levels or 0:16 levels between both channels. One could think + * of using this feature, as even if no level of FIFO is given to a + * given channel, one can for instance always reach ATAPI drives through + * it, or, if one channel is unused, configuration defaults to + * an even split FIFO levels. + * + * This feature is available only through a kernel command line : + * "splitfifo=Chan,Thr0,Thr1" or "splitfifo=Chan". + * where: Chan =1,2,3 or 4 and Thrx = 1,2,3,or 4. + * + * If Chan == 1: + * gives all the fifo to channel 0, + * sets its threshold to Thr0/4, + * and disables any dma access to channel 1. + * + * If chan == 2: + * gives all the fifo to channel 1, + * sets its threshold to Thr1/4, + * and disables any dma access to channel 0. + * + * If chan == 3 or 4: + * shares evenly fifo between channels, + * gives channel 0 a threshold of Thr0/4, + * and channel 1 a threshold of Thr1/4. + * + * Note that by default (if no command line is provided) and if a channel + * has been disabled in Bios, all the fifo is given to the active channel, + * and its threshold is set to 3/4. */ #include @@ -24,9 +50,255 @@ #include #include #include +#include #include +#include + #include -#include "ide.h" + +#define DISPLAY_VIA_TIMINGS + +#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) +#include +#include + +static char *FIFO_str[] = { + " 1 ", + "3/4", + "1/2", + "1/4" +}; + +static char *control3_str[] = { + "No limitation", + "64", + "128", + "192" +}; + +static int via_get_info(char *, char **, off_t, int, int); +extern int (*via_display_info)(char *, char **, off_t, int, int); /* ide-proc.c */ +static struct pci_dev *bmide_dev; + +static char * print_apollo_drive_config (char *buf, struct pci_dev *dev) +{ + int rc; + unsigned int time; + byte tm; + char *p = buf; + + /* Drive Timing Control */ + rc = pci_read_config_dword(dev, 0x48, &time); + p += sprintf(p, "Act Pls Width: %02d %02d %02d %02d\n", + ((time & 0xf0000000)>>28) + 1, + ((time & 0xf00000)>>20) + 1, + ((time & 0xf000)>>12) + 1, + ((time & 0xf0)>>4) + 1 ); + p += sprintf(p, "Recovery Time: %02d %02d %02d %02d\n", + ((time & 0x0f000000)>>24) + 1, + ((time & 0x0f0000)>>16) + 1, + ((time & 0x0f00)>>8) + 1, + (time & 0x0f) + 1 ); + + /* Address Setup Time */ + rc = pci_read_config_byte(dev, 0x4C, &tm); + p += sprintf(p, "Add. Setup T.: %01dT %01dT %01dT %01dT\n", + ((tm & 0xc0)>>6) + 1, + ((tm & 0x30)>>4) + 1, + ((tm & 0x0c)>>2) + 1, + (tm & 0x03) + 1 ); + + /* UltraDMA33 Extended Timing Control */ + rc = pci_read_config_dword(dev, 0x50, &time); + p += sprintf(p, "------------------UDMA-Timing-Control------------------------\n"); + p += sprintf(p, "Enable Meth.: %01d %01d %01d %01d\n", + (time & 0x80000000) ? 1 : 0, + (time & 0x800000) ? 1 : 0, + (time & 0x8000) ? 1 : 0, + (time & 0x80) ? 1 : 0 ); + p += sprintf(p, "Enable: %s %s %s %s\n", + (time & 0x40000000) ? "yes" : "no ", + (time & 0x400000) ? "yes" : "no ", + (time & 0x4000) ? "yes" : "no ", + (time & 0x40) ? "yes" : "no " ); + p += sprintf(p, "Transfer Mode: %s %s %s %s\n", + (time & 0x20000000) ? "PIO" : "DMA", + (time & 0x200000) ? "PIO" : "DMA", + (time & 0x2000) ? "PIO" : "DMA", + (time & 0x20) ? "PIO" : "DMA" ); + p += sprintf(p, "Cycle Time: %01dT %01dT %01dT %01dT\n", + ((time & 0x03000000)>>24) + 2, + ((time & 0x030000)>>16) + 2, + ((time & 0x0300)>>8) + 2, + (time & 0x03) + 2 ); + + return (char *)p; +} + +static char * print_apollo_ide_config (char *buf, struct pci_dev *dev) +{ + byte time, tmp; + unsigned short size0, size1; + int rc; + char *p = buf; + + rc = pci_read_config_byte(dev, 0x41, &time); + p += sprintf(p, "Prefetch Buffer : %s %s\n", + (time & 128) ? "on " : "off", + (time & 32) ? "on " : "off" ); + p += sprintf(p, "Post Write Buffer: %s %s\n", + (time & 64) ? "on " : "off", + (time & 16) ? "on " : "off" ); + + /* FIFO configuration */ + rc = pci_read_config_byte(dev, 0x43, &time); + tmp = ((time & 0x20)>>2) + ((time & 0x40)>>3); + p += sprintf(p, "FIFO Conf/Chan. : %02d %02d\n", + 16 - tmp, tmp); + tmp = (time & 0x0F)>>2; + p += sprintf(p, "Threshold Prim. : %s %s\n", + FIFO_str[tmp], + FIFO_str[time & 0x03] ); + + /* chipset Control3 */ + rc = pci_read_config_byte(dev, 0x46, &time); + p += sprintf(p, "Read DMA FIFO flush: %s %s\n", + (time & 0x80) ? "on " : "off", + (time & 0x40) ? "on " : "off" ); + p += sprintf(p, "End Sect. FIFO flush: %s %s\n", + (time & 0x20) ? "on " : "off", + (time & 0x10) ? "on " : "off" ); + p += sprintf(p, "Max DRDY Pulse Width: %s %s\n", + control3_str[(time & 0x03)], + (time & 0x03) ? "PCI clocks" : "" ); + + /* Primary and Secondary sector sizes */ + rc = pci_read_config_word(dev, 0x60, &size0); + rc = pci_read_config_word(dev, 0x68, &size1); + p += sprintf(p, "Bytes Per Sector: %03d %03d\n", + size0 & 0xfff, + size1 & 0xfff ); + + return (char *)p; +} + +static char * print_apollo_chipset_control1 (char *buf, struct pci_dev *dev) +{ + byte t; + int rc; + char *p = buf; + unsigned short c; + byte l, l_max; + + rc = pci_read_config_word(dev, 0x04, &c); + rc = pci_read_config_byte(dev, 0x44, &t); + rc = pci_read_config_byte(dev, 0x0d, &l); + rc = pci_read_config_byte(dev, 0x3f, &l_max); + + p += sprintf(p, "Command register = 0x%x\n", c); + p += sprintf(p, "Master Read Cycle IRDY %d Wait State\n", + (t & 64) >>6 ); + p += sprintf(p, "Master Write Cycle IRDY %d Wait State\n", + (t & 32) >> 5 ); + p += sprintf(p, "FIFO Output Data 1/2 Clock Advance: %s\n", + (t & 16) ? "on " : "off" ); + p += sprintf(p, "Bus Master IDE Status Register Read Retry: %s\n", + (t & 8) ? "on " : "off" ); + p += sprintf(p, "Latency timer = %d (max. = %d)\n", + l, l_max); + + return (char *)p; +} + +static char * print_apollo_chipset_control2 (char *buf, struct pci_dev *dev) +{ + byte t; + int rc; + char *p = buf; + rc = pci_read_config_byte(dev, 0x45, &t); + p += sprintf(p, "Interrupt Steering Swap: %s\n", + (t & 64) ? "on ":"off" ); + + return (char *)p; +} + +static char * print_apollo_chipset_control3 (char *buf, struct pci_dev *dev, + unsigned short n) +{ + /* + * at that point we can be sure that register 0x20 of the + * chipset contains the right address... + */ + unsigned int bibma; + int rc; + byte c0, c1; + char *p = buf; + + rc = pci_read_config_dword(dev, 0x20, &bibma); + bibma = (bibma & 0xfff0) ; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb((unsigned short)bibma + 0x02); + c1 = inb((unsigned short)bibma + 0x0a); + + if (n == 0) { + /*p = sprintf(p,"--------------------Primary IDE------------Secondary IDE-----");*/ + p += sprintf(p, "both channels togth: %s %s\n", + (c0&0x80) ? "no" : "yes", + (c1&0x80) ? "no" : "yes" ); + } else { + /*p = sprintf(p,"--------------drive0------drive1-------drive0------drive1----");*/ + p += sprintf(p, "DMA enabled: %s %s %s %s\n", + (c0&0x20) ? "yes" : "no ", + (c0&0x40) ? "yes" : "no ", + (c1&0x20) ? "yes" : "no ", + (c1&0x40) ? "yes" : "no " ); + } + + return (char *)p; +} + +static int via_get_info (char *buffer, char **addr, off_t offset, int count, int dummy) +{ + /* + * print what /proc/via displays, + * if required from DISPLAY_APOLLO_TIMINGS + */ + char *p = buffer; + /* Parameter of chipset : */ + + /* Miscellaneous control 1 */ + p = print_apollo_chipset_control1(buffer, bmide_dev); + + /* Miscellaneous control 2 */ + p = print_apollo_chipset_control2(p, bmide_dev); + /* Parameters of drives: */ + + /* Header */ + p += sprintf(p, "------------------Primary IDE------------Secondary IDE-----\n"); + p = print_apollo_chipset_control3(p, bmide_dev, 0); + p = print_apollo_ide_config(p, bmide_dev); + p += sprintf(p, "--------------drive0------drive1-------drive0------drive1----\n"); + p = print_apollo_chipset_control3(p, bmide_dev, 1); + p = print_apollo_drive_config(p, bmide_dev); + + return p-buffer; /* hoping it is less than 4K... */ +} + +#endif /* defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) */ + +/* + * Used to set Fifo configuration via kernel command line: + */ + +byte fifoconfig = 0; +static byte newfifo = 0; + +/* Used to just intialize once Fifo configuration */ +static short int done = 0; /* * Set VIA Chipset Timings for (U)DMA modes enabled. @@ -37,49 +309,162 @@ static void set_via_timings (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; - byte post = hwif->channel ? 0xc0 : 0x30; - byte flush = hwif->channel ? 0xa0 : 0x50; + byte post = hwif->channel ? 0x30 : 0xc0; + byte flush = hwif->channel ? 0x50 : 0xa0; + int mask = hwif->channel ? ((newfifo & 0x60) ? 0 : 1) : + (((newfifo & 0x60) == 0x60) ? 1 : 0); byte via_config = 0; int rc = 0, errors = 0; printk("%s: VIA Bus-Master ", hwif->name); - if (!hwif->dma_base) { - printk(" ERROR, NO DMA_BASE\n"); - return; - } - - /* setting IDE read prefetch buffer and IDE post write buffer. + /* + * setting IDE read prefetch buffer and IDE post write buffer. * (This feature allows prefetched reads and post writes). */ - if ((rc = pci_read_config_byte(dev, 0x41, &via_config))) { - errors++; - goto via_error; - } - if ((rc = pci_write_config_byte(dev, 0x41, via_config | post))) { + if ((rc = pci_read_config_byte(dev, 0x41, &via_config))) errors++; - goto via_error; + + if (mask) { + if ((rc = pci_write_config_byte(dev, 0x41, via_config & ~post))) + errors++; + } else { + if ((rc = pci_write_config_byte(dev, 0x41, via_config | post))) + errors++; } - /* setting Channel read and End-of-sector FIFO flush. + /* + * setting Channel read and End-of-sector FIFO flush. * (This feature ensures that FIFO flush is enabled: * - for read DMA when interrupt asserts the given channel. * - at the end of each sector for the given channel.) */ - if ((rc = pci_read_config_byte(dev, 0x46, &via_config))) { + if ((rc = pci_read_config_byte(dev, 0x46, &via_config))) errors++; - goto via_error; + + if (mask) { + if ((rc = pci_write_config_byte(dev, 0x46, via_config & ~flush))) + errors++; + } else { + if ((rc = pci_write_config_byte(dev, 0x46, via_config | flush))) + errors++; } - if ((rc = pci_write_config_byte(dev, 0x46, via_config | flush))) { - errors++; - goto via_error; + + if (!hwif->dma_base) + printk("Config %s. No DMA Enabled\n", + errors ? "ERROR":"Success"); + else + printk("(U)DMA Timing Config %s\n", + errors ? "ERROR" : "Success"); +} + +/* + * Sets VIA 82c586 FIFO configuration: + * This chipsets gets a splitable fifo. This can be driven either by command + * line option (eg "splitfifo=2,2,3" which asks this driver to switch all the + * 16 fifo levels to the second drive, and give it a threshold of 3 for (u)dma + * triggering. + */ + +static int via_set_fifoconfig(ide_hwif_t *hwif) +{ + byte fifo; + unsigned int timings; + struct pci_dev *dev = hwif->pci_dev; + + /* read port configuration */ + if (pci_read_config_dword(dev, 0x40, &timings)) + return 1; + + /* first read actual fifo config: */ + if (pci_read_config_byte(dev, 0x43, &fifo)) + return 1; + + /* keep 4 and 7 bit as they seem to differ between chipsets flavors... */ + newfifo = fifo & 0x90; + + if (fifoconfig) { + /* we received a config request from kernel command line: */ + newfifo |= fifoconfig & 0x6f; + } else { + /* If ever just one channel is unused, allocate all fifo levels to it + * and give it a 3/4 threshold for (u)dma transfers. + * Otherwise, share it evenly between channels: + */ + if ((timings & 3) == 2) { + /* only primary channel is enabled + * 16 buf. to prim. chan. thresh=3/4 + */ + newfifo |= 0x06; + } else if ((timings & 3) == 1) { + /* only secondary channel is enabled! + * 16 buffers to sec. ch. thresh=3/4 + */ + newfifo |= 0x69; + } else { + /* fifo evenly distributed: */ + newfifo |= 0x2a; + } } -via_error: - printk("(U)DMA Timing Config %s\n", errors ? "ERROR" : "Success"); + /* write resulting configuration to chipset: */ + if (pci_write_config_byte(dev, 0x43, newfifo)) + return 1; + + /* and then reread it to get the actual one */ + if (pci_read_config_byte(dev, 0x43, &newfifo)) + return 1; + + /* print a kernel report: */ + printk("Split FIFO Configuration: %s Primary buffers, threshold = %s\n", + ((newfifo & 0x60) == 0x60) ? " 0" : + ((newfifo & 0x60) ? " 8" : "16"), + !(newfifo & 0x0c) ? "1" : + (!(newfifo & 0x08) ? "3/4" : + (newfifo & 0x04) ? "1/4" : "1/2")); + + printk(" %s Second. buffers, threshold = %s\n", + ((newfifo & 0x60) == 0x60) ? "16" : + ((newfifo & 0x60) ? " 8" : " 0"), + !(newfifo & 0x03) ? "1" : + (!(newfifo & 0x02) ? "3/4" : + (newfifo & 0x01) ? "1/4" : "1/2")); + +#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) + bmide_dev = hwif->pci_dev; + via_display_info = &via_get_info; +#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS*/ + return 0; +} + +/* + * ide_dmacapable_via82c568(ide_hwif_t *, unsigned long) + * checks if channel "channel" of if hwif is dma + * capable or not, according to kernel command line, + * and the new fifo settings. + * It calls "ide_setup_dma" on capable mainboards, and + * bypasses the setup if not capable. + */ + +void ide_dmacapable_via82c586 (ide_hwif_t *hwif, unsigned long dmabase) +{ + if (!done) { + via_set_fifoconfig(hwif); + done = 1; + } + + /* + * check if any fifo is available for requested port: + */ + if (((hwif->channel == 0) && ((newfifo & 0x60) == 0x60)) || + ((hwif->channel == 1) && ((newfifo & 0x60) == 0x00))) { + printk(" %s: VP_IDE Bus-Master DMA disabled (FIFO setting)\n", hwif->name); + } else { + ide_setup_dma(hwif, dmabase, 8); + } } -void ide_init_via82c586 (ide_hwif_t *hwif) +__initfunc(void ide_init_via82c586 (ide_hwif_t *hwif)) { set_via_timings(hwif); } diff -u --recursive --new-file v2.3.0/linux/drivers/block/xd.c linux/drivers/block/xd.c --- v2.3.0/linux/drivers/block/xd.c Thu Jan 7 08:46:58 1999 +++ linux/drivers/block/xd.c Tue May 11 23:37:06 1999 @@ -159,7 +159,8 @@ xd_release, /* release */ block_fsync /* fsync */ }; -static struct wait_queue *xd_wait_int = NULL, *xd_wait_open = NULL; +static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); +static DECLARE_WAIT_QUEUE_HEAD(xd_wait_open); static u_char xd_valid[XD_MAXDRIVES] = { 0,0 }; static u_char xd_drives = 0, xd_irq = 5, xd_dma = 3, xd_maxsectors; static u_char xd_override __initdata = 0, xd_type = 0; @@ -167,7 +168,7 @@ static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0,0,0,0,0,0 }; static volatile int xdc_busy = 0; -static struct wait_queue *xdc_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(xdc_wait); typedef void (*timeout_fn)(unsigned long); static struct timer_list xd_timer = { NULL, NULL, 0, 0, (timeout_fn) xd_wakeup }, diff -u --recursive --new-file v2.3.0/linux/drivers/cdrom/aztcd.c linux/drivers/cdrom/aztcd.c --- v2.3.0/linux/drivers/cdrom/aztcd.c Mon Aug 24 13:02:43 1998 +++ linux/drivers/cdrom/aztcd.c Wed May 12 13:27:37 1999 @@ -303,7 +303,7 @@ static char azt_auto_eject = AZT_AUTO_EJECT; static int AztTimeout, AztTries; -static struct wait_queue *azt_waitq = NULL; +static DECLARE_WAIT_QUEUE_HEAD(azt_waitq); static struct timer_list delay_timer = { NULL, NULL, 0, 0, NULL }; static struct azt_DiskInfo DiskInfo; diff -u --recursive --new-file v2.3.0/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c --- v2.3.0/linux/drivers/cdrom/cdu31a.c Sun Dec 20 04:36:47 1998 +++ linux/drivers/cdrom/cdu31a.c Wed May 12 13:27:37 1999 @@ -278,7 +278,7 @@ static volatile int sony_inuse = 0; /* Is the drive in use? Only one operation at a time allowed */ -static struct wait_queue * sony_wait = NULL; /* Things waiting for the drive */ +static DECLARE_WAIT_QUEUE_HEAD(sony_wait); /* Things waiting for the drive */ static struct task_struct *has_cd_task = NULL; /* The task that is currently using the CDROM drive, or @@ -311,7 +311,7 @@ /* The interrupt handler will wake this queue up when it gets an interrupts. */ -static struct wait_queue *cdu31a_irq_wait = NULL; +DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait); static int curr_control_reg = 0; /* Current value of the control register */ @@ -577,13 +577,13 @@ abort_read_started = 0; /* If something was waiting, wake it up now. */ - if (cdu31a_irq_wait != NULL) + if (waitqueue_active(&cdu31a_irq_wait)) { disable_interrupts(); wake_up(&cdu31a_irq_wait); } } - else if (cdu31a_irq_wait != NULL) + else if (waitqueue_active(&cdu31a_irq_wait)) { disable_interrupts(); wake_up(&cdu31a_irq_wait); diff -u --recursive --new-file v2.3.0/linux/drivers/cdrom/cm206.c linux/drivers/cdrom/cm206.c --- v2.3.0/linux/drivers/cdrom/cm206.c Wed Mar 10 17:01:57 1999 +++ linux/drivers/cdrom/cm206.c Wed May 12 13:27:37 1999 @@ -262,8 +262,8 @@ int openfiles; ush sector[READ_AHEAD*RAW_SECTOR_SIZE/2]; /* buffered cd-sector */ int sector_first, sector_last; /* range of these sectors */ - struct wait_queue * uart; /* wait queues for interrupt */ - struct wait_queue * data; + wait_queue_head_t uart; /* wait queues for interrupt */ + wait_queue_head_t data; struct timer_list timer; /* time-out */ char timed_out; signed char max_sectors; /* number of sectors that fit in adapter mem */ @@ -360,7 +360,7 @@ debug(("receiving #%d: 0x%x\n", cd->ur_w, cd->ur[cd->ur_w])); cd->ur_w++; cd->ur_w %= UR_SIZE; if (cd->ur_w == cd->ur_r) debug(("cd->ur overflow!\n")); - if (cd->uart && cd->background < 2) { + if (waitqueue_active(&cd->uart) && cd->background < 2) { del_timer(&cd->timer); wake_up_interruptible(&cd->uart); } @@ -368,7 +368,7 @@ /* data ready in fifo? */ else if (cd->intr_ds & ds_data_ready) { if (cd->background) ++cd->adapter_last; - if (cd->data && (cd->wait_back || !cd->background)) { + if (waitqueue_active(&cd->data) && (cd->wait_back || !cd->background)) { del_timer(&cd->timer); wake_up_interruptible(&cd->data); } @@ -419,12 +419,12 @@ { cd->timed_out = 1; debug(("Timing out\n")); - wake_up_interruptible((struct wait_queue **) who); + wake_up_interruptible((wait_queue_head_t *)who); } /* This function returns 1 if a timeout occurred, 0 if an interrupt happened */ -int sleep_or_timeout(struct wait_queue ** wait, int timeout) +int sleep_or_timeout(wait_queue_head_t *wait, int timeout) { cd->timed_out=0; cd->timer.data=(unsigned long) wait; @@ -442,7 +442,7 @@ void cm206_delay(int nr_jiffies) { - struct wait_queue * wait = NULL; + DECLARE_WAIT_QUEUE_HEAD(wait); sleep_or_timeout(&wait, nr_jiffies); } diff -u --recursive --new-file v2.3.0/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c --- v2.3.0/linux/drivers/cdrom/mcd.c Mon Apr 12 16:18:28 1999 +++ linux/drivers/cdrom/mcd.c Wed May 12 13:27:37 1999 @@ -162,7 +162,7 @@ MODULE_PARM(mcd, "1-2i"); static int McdTimeout, McdTries; -static struct wait_queue *mcd_waitq = NULL; +static DECLARE_WAIT_QUEUE_HEAD(mcd_waitq); static struct mcd_DiskInfo DiskInfo; static struct mcd_Toc Toc[MAX_TRACKS]; diff -u --recursive --new-file v2.3.0/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c --- v2.3.0/linux/drivers/cdrom/mcdx.c Sun Dec 20 04:36:47 1998 +++ linux/drivers/cdrom/mcdx.c Wed May 12 13:27:37 1999 @@ -150,9 +150,9 @@ struct s_drive_stuff { /* waitqueues */ - struct wait_queue *busyq; - struct wait_queue *lockq; - struct wait_queue *sleepq; + wait_queue_head_t busyq; + wait_queue_head_t lockq; + wait_queue_head_t sleepq; /* flags */ volatile int introk; /* status of last irq operation */ @@ -1046,6 +1046,10 @@ stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1; stuffp->wreg_hcon = stuffp->wreg_reset + 1; stuffp->wreg_chn = stuffp->wreg_hcon + 1; + + init_waitqueue_head(&stuffp->busyq); + init_waitqueue_head(&stuffp->lockq); + init_waitqueue_head(&stuffp->sleepq); /* check if i/o addresses are available */ if (check_region((unsigned int) stuffp->wreg_data, MCDX_IO_SIZE)) { diff -u --recursive --new-file v2.3.0/linux/drivers/cdrom/optcd.c linux/drivers/cdrom/optcd.c --- v2.3.0/linux/drivers/cdrom/optcd.c Sat Apr 24 17:49:37 1999 +++ linux/drivers/cdrom/optcd.c Wed May 12 13:27:37 1999 @@ -257,7 +257,7 @@ /* Timed waiting for status or data */ static int sleep_timeout; /* max # of ticks to sleep */ -static struct wait_queue *waitq = NULL; +static DECLARE_WAIT_QUEUE_HEAD(waitq); static struct timer_list delay_timer = {NULL, NULL, 0, 0, NULL}; #define SET_TIMER(func, jifs) \ diff -u --recursive --new-file v2.3.0/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c --- v2.3.0/linux/drivers/cdrom/sbpcd.c Sun Dec 20 04:36:47 1998 +++ linux/drivers/cdrom/sbpcd.c Wed May 12 13:27:37 1999 @@ -612,7 +612,7 @@ static volatile u_char busy_data=0; static volatile u_char busy_audio=0; /* true semaphores would be safer */ #endif OLD_BUSY -static struct semaphore ioctl_read_sem = MUTEX; +static DECLARE_MUTEX(ioctl_read_sem); static u_long timeout; static volatile u_char timed_out_delay=0; static volatile u_char timed_out_data=0; diff -u --recursive --new-file v2.3.0/linux/drivers/cdrom/sjcd.c linux/drivers/cdrom/sjcd.c --- v2.3.0/linux/drivers/cdrom/sjcd.c Mon Apr 12 16:18:32 1999 +++ linux/drivers/cdrom/sjcd.c Wed May 12 13:27:37 1999 @@ -115,7 +115,7 @@ MODULE_PARM(sjcd_base, "i"); #endif -static struct wait_queue *sjcd_waitq = NULL; +static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq); /* * Data transfer. diff -u --recursive --new-file v2.3.0/linux/drivers/cdrom/sonycd535.c linux/drivers/cdrom/sonycd535.c --- v2.3.0/linux/drivers/cdrom/sonycd535.c Thu Jan 7 08:46:59 1999 +++ linux/drivers/cdrom/sonycd535.c Wed May 12 13:27:37 1999 @@ -261,7 +261,7 @@ static int sony535_irq_used = CDU535_INTERRUPT; /* The interrupt handler will wake this queue up when it gets an interrupt. */ -static struct wait_queue *cdu535_irq_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(cdu535_irq_wait); /* @@ -318,7 +318,7 @@ cdu535_interrupt(int irq, void *dev_id, struct pt_regs *regs) { disable_interrupts(); - if (cdu535_irq_wait != NULL) + if (wait_queue_active(&cdu535_irq_wait)) wake_up(&cdu535_irq_wait); else printk(CDU535_MESSAGE_NAME diff -u --recursive --new-file v2.3.0/linux/drivers/char/atixlmouse.c linux/drivers/char/atixlmouse.c --- v2.3.0/linux/drivers/char/atixlmouse.c Mon Aug 24 13:02:43 1998 +++ linux/drivers/char/atixlmouse.c Wed May 12 13:27:37 1999 @@ -67,7 +67,7 @@ int present; int ready; int active; - struct wait_queue *wait; + wait_queue_head_t wait; struct fasync_struct *fasync; } mouse; @@ -223,7 +223,7 @@ mouse.ready = 0; mouse.buttons = mouse.latch_buttons = 0; mouse.dx = mouse.dy = 0; - mouse.wait = NULL; + init_waitqueue_head(&mouse.wait); printk("Bus mouse detected and installed.\n"); misc_register(&atixl_mouse); return 0; diff -u --recursive --new-file v2.3.0/linux/drivers/char/bttv.c linux/drivers/char/bttv.c --- v2.3.0/linux/drivers/char/bttv.c Sat Apr 24 17:49:37 1999 +++ linux/drivers/char/bttv.c Wed May 12 08:41:12 1999 @@ -3421,10 +3421,10 @@ btv->risc_jmp=NULL; btv->vbi_odd=NULL; btv->vbi_even=NULL; - btv->vbiq=NULL; - btv->capq=NULL; - btv->capqo=NULL; - btv->capqe=NULL; + init_waitqueue_head(&btv->vbiq); + init_waitqueue_head(&btv->capq); + init_waitqueue_head(&btv->capqo); + init_waitqueue_head(&btv->capqe); btv->vbip=VBIBUF_SIZE; btv->id=dev->device; diff -u --recursive --new-file v2.3.0/linux/drivers/char/bttv.h linux/drivers/char/bttv.h --- v2.3.0/linux/drivers/char/bttv.h Sat Apr 24 17:49:37 1999 +++ linux/drivers/char/bttv.h Wed May 12 08:41:12 1999 @@ -122,10 +122,10 @@ u32 *vbi_even; u32 bus_vbi_even; u32 bus_vbi_odd; - struct wait_queue *vbiq; - struct wait_queue *capq; - struct wait_queue *capqo; - struct wait_queue *capqe; + wait_queue_head_t vbiq; + wait_queue_head_t capq; + wait_queue_head_t capqo; + wait_queue_head_t capqe; int vbip; u32 *risc_odd; diff -u --recursive --new-file v2.3.0/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c --- v2.3.0/linux/drivers/char/busmouse.c Wed Dec 16 13:38:18 1998 +++ linux/drivers/char/busmouse.c Wed May 12 13:27:37 1999 @@ -277,7 +277,7 @@ mouse.buttons = 0x87; mouse.dx = 0; mouse.dy = 0; - mouse.wait = NULL; + init_waitqueue_head(&mouse.wait); printk(KERN_INFO "Logitech bus mouse detected, using IRQ %d.\n", mouse_irq); misc_register(&bus_mouse); diff -u --recursive --new-file v2.3.0/linux/drivers/char/console.c linux/drivers/char/console.c --- v2.3.0/linux/drivers/char/console.c Wed Mar 10 16:51:35 1999 +++ linux/drivers/char/console.c Tue May 11 14:37:40 1999 @@ -2269,7 +2269,7 @@ def_color = 0x07; /* white */ ulcolor = 0x0f; /* bold white */ halfcolor = 0x08; /* grey */ - vt_cons[currcons]->paste_wait = 0; + init_waitqueue_head(&vt_cons[currcons]->paste_wait); reset_terminal(currcons, do_clear); } diff -u --recursive --new-file v2.3.0/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c --- v2.3.0/linux/drivers/char/cyclades.c Mon Apr 12 10:09:47 1999 +++ linux/drivers/char/cyclades.c Wed May 12 13:27:37 1999 @@ -697,7 +697,7 @@ * allocated when the first cy_open occurs. */ static unsigned char *tmp_buf; -static struct semaphore tmp_buf_sem = MUTEX; +DECLARE_MUTEX(tmp_buf_sem); /* * This is used to look up the divisor speeds and the timeouts @@ -2246,7 +2246,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, struct cyclades_port *info) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); struct cyclades_card *cinfo; unsigned long flags; int chip, channel,index; @@ -5210,9 +5210,9 @@ cy_callout_driver.init_termios; info->normal_termios = cy_serial_driver.init_termios; - info->open_wait = 0; - info->close_wait = 0; - info->shutdown_wait = 0; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->shutdown_wait); /* info->session */ /* info->pgrp */ info->read_status_mask = 0; @@ -5279,9 +5279,9 @@ cy_callout_driver.init_termios; info->normal_termios = cy_serial_driver.init_termios; - info->open_wait = 0; - info->close_wait = 0; - info->shutdown_wait = 0; + init_waitqueue(&info->open_wait); + init_waitqueue(&info->close_wait); + init_waitqueue(&info->shutdown_wait); /* info->session */ /* info->pgrp */ info->read_status_mask = diff -u --recursive --new-file v2.3.0/linux/drivers/char/dtlk.c linux/drivers/char/dtlk.c --- v2.3.0/linux/drivers/char/dtlk.c Fri Apr 16 08:20:23 1999 +++ linux/drivers/char/dtlk.c Wed May 12 13:27:37 1999 @@ -87,7 +87,7 @@ static int dtlk_has_indexing; static unsigned int dtlk_portlist[] = {0x25e, 0x29e, 0x2de, 0x31e, 0x35e, 0x39e, 0}; -static struct wait_queue *dtlk_process_list = NULL; +static wait_queue_head_t dtlk_process_list; static struct timer_list dtlk_timer; /* prototypes for file_operations struct */ @@ -382,7 +382,7 @@ init_timer(&dtlk_timer); dtlk_timer.function = dtlk_timer_tick; - dtlk_process_list = NULL; + init_waitqueue_head(&dtlk_process_list); return 0; } diff -u --recursive --new-file v2.3.0/linux/drivers/char/epca.c linux/drivers/char/epca.c --- v2.3.0/linux/drivers/char/epca.c Tue Mar 16 14:21:51 1999 +++ linux/drivers/char/epca.c Wed May 12 13:27:37 1999 @@ -1268,7 +1268,7 @@ struct file *filp, struct channel *ch) { /* Begin block_til_ready */ - struct wait_queue wait = {current, NULL}; + DECLARE_WAITQUEUE(wait,current); int retval, do_clocal = 0; unsigned long flags; @@ -2236,8 +2236,8 @@ ch->blocked_open = 0; ch->callout_termios = pc_callout.init_termios; ch->normal_termios = pc_driver.init_termios; - ch->open_wait = 0; - ch->close_wait = 0; + init_waitqueue_head(&ch->open_wait); + init_waitqueue_head(&ch->close_wait); ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL); if (!(ch->tmp_buf)) { diff -u --recursive --new-file v2.3.0/linux/drivers/char/esp.c linux/drivers/char/esp.c --- v2.3.0/linux/drivers/char/esp.c Sat Oct 31 11:06:21 1998 +++ linux/drivers/char/esp.c Wed May 12 13:27:37 1999 @@ -169,7 +169,7 @@ * memory if large numbers of serial ports are open. */ static unsigned char *tmp_buf = 0; -static struct semaphore tmp_buf_sem = MUTEX; +static DECLARE_MUTEX(tmp_buf_sem); static inline int serial_paranoia_check(struct esp_struct *info, kdev_t device, const char *routine) @@ -2224,7 +2224,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, struct esp_struct *info) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int retval; int do_clocal = 0; @@ -2676,6 +2676,10 @@ info->config.flow_off = flow_off; info->config.pio_threshold = pio_threshold; info->next_port = ports; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); + init_waitqueue_head(&info->break_wait); ports = info; printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ", info->line, info->port, info->irq); diff -u --recursive --new-file v2.3.0/linux/drivers/char/ftape/lowlevel/fdc-io.c linux/drivers/char/ftape/lowlevel/fdc-io.c --- v2.3.0/linux/drivers/char/ftape/lowlevel/fdc-io.c Tue Dec 29 11:27:38 1998 +++ linux/drivers/char/ftape/lowlevel/fdc-io.c Wed May 12 13:27:37 1999 @@ -54,7 +54,7 @@ volatile int ftape_current_cylinder = -1; volatile fdc_mode_enum fdc_mode = fdc_idle; fdc_config_info fdc = {0}; -struct wait_queue *ftape_wait_intr = NULL; +DECLARE_WAIT_QUEUE_HEAD(ftape_wait_intr); unsigned int ft_fdc_base = CONFIG_FT_FDC_BASE; unsigned int ft_fdc_irq = CONFIG_FT_FDC_IRQ; @@ -385,7 +385,7 @@ */ int fdc_interrupt_wait(unsigned int time) { - struct wait_queue wait = {current, NULL}; + DECLARE_WAITQUEUE(wait,current); sigset_t old_sigmask; static int resetting = 0; long timeout; diff -u --recursive --new-file v2.3.0/linux/drivers/char/ftape/lowlevel/fdc-io.h linux/drivers/char/ftape/lowlevel/fdc-io.h --- v2.3.0/linux/drivers/char/ftape/lowlevel/fdc-io.h Tue Nov 25 14:45:27 1997 +++ linux/drivers/char/ftape/lowlevel/fdc-io.h Wed May 12 13:27:37 1999 @@ -209,7 +209,7 @@ */ extern volatile fdc_mode_enum fdc_mode; extern int fdc_setup_error; /* outdated ??? */ -extern struct wait_queue *ftape_wait_intr; +extern wait_queue_head_t ftape_wait_intr; extern int ftape_motor; /* fdc motor line state */ extern volatile int ftape_current_cylinder; /* track nr FDC thinks we're on */ extern volatile __u8 fdc_head; /* FDC head */ diff -u --recursive --new-file v2.3.0/linux/drivers/char/hfmodem/main.c linux/drivers/char/hfmodem/main.c --- v2.3.0/linux/drivers/char/hfmodem/main.c Sun Jan 17 18:28:06 1999 +++ linux/drivers/char/hfmodem/main.c Wed May 12 13:27:37 1999 @@ -638,6 +638,7 @@ hfmodem_state[0].ptt_out.seriobase = serio; hfmodem_state[0].ptt_out.pariobase = pario; hfmodem_state[0].ptt_out.midiiobase = midiio; + init_waitqueue_head(&hfmodem_state[0].wait); hfmodem_refclock_probe(); output_check(&hfmodem_state[0]); #if defined(CONFIG_HFMODEM_WSS) && defined(CONFIG_HFMODEM_SBC) @@ -703,7 +704,8 @@ int i; printk(hfmodem_drvinfo); - hfmodem_refclock_probe(); + init_waitqueue_head(&hfmode_state[0].wait); + hfmodem_refclock_probe(); output_check(&hfmodem_state[0]); #if defined(CONFIG_HFMODEM_WSS) && defined(CONFIG_HFMODEM_SBC) if (hw) diff -u --recursive --new-file v2.3.0/linux/drivers/char/isicom.c linux/drivers/char/isicom.c --- v2.3.0/linux/drivers/char/isicom.c Fri May 7 11:05:30 1999 +++ linux/drivers/char/isicom.c Wed May 12 13:27:37 1999 @@ -80,7 +80,7 @@ static void isicom_start(struct tty_struct * tty); static unsigned char * tmp_buf = 0; -static struct semaphore tmp_buf_sem = MUTEX; +static DECLARE_MUTEX(tmp_buf_sem); /* baud index mappings from linux defns to isi */ @@ -870,7 +870,7 @@ static int block_til_ready(struct tty_struct * tty, struct file * filp, struct isi_port * port) { int do_clocal = 0, retval; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); /* block if port is in the process of being closed */ @@ -1858,7 +1858,8 @@ port->bh_tqueue.routine = isicom_bottomhalf; port->bh_tqueue.data = port; port->status = 0; - + init_waitqueue_head(&port->open_wait); + init_waitqueue_head(&port->close_wait); /* . . . */ } } diff -u --recursive --new-file v2.3.0/linux/drivers/char/joystick/joystick.c linux/drivers/char/joystick/joystick.c --- v2.3.0/linux/drivers/char/joystick/joystick.c Tue Dec 1 19:05:05 1998 +++ linux/drivers/char/joystick/joystick.c Wed May 12 13:27:37 1999 @@ -491,7 +491,7 @@ static int js_read(struct inode *inode, struct file *file, char *buf, int count) #endif { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); struct js_event *buff = (void *) buf; struct js_list *curl; struct js_dev *jd; @@ -1081,7 +1081,7 @@ curd->next = NULL; curd->list = NULL; curd->port = port; - curd->wait = NULL; + init_waitqueue_head(&curd->wait); curd->open = open; curd->close = close; diff -u --recursive --new-file v2.3.0/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- v2.3.0/linux/drivers/char/keyboard.c Mon Apr 26 13:21:42 1999 +++ linux/drivers/char/keyboard.c Tue May 11 14:37:40 1999 @@ -64,7 +64,7 @@ extern void ctrl_alt_del(void); -struct wait_queue * keypress_wait = NULL; +DECLARE_WAIT_QUEUE_HEAD(keypress_wait); struct console; int keyboard_wait_for_keypress(struct console *co) diff -u --recursive --new-file v2.3.0/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v2.3.0/linux/drivers/char/lp.c Mon May 10 10:26:31 1999 +++ linux/drivers/char/lp.c Wed May 12 08:41:12 1999 @@ -187,15 +187,7 @@ /* if you have more than 3 printers, remember to increase LP_NO */ #define LP_NO 3 -struct lp_struct lp_table[LP_NO] = -{ - [0 ... LP_NO-1] = {NULL, 0, LP_INIT_CHAR, LP_INIT_TIME, LP_INIT_WAIT, - NULL, -#ifdef LP_STATS - 0, 0, {0}, -#endif - NULL, 0, 0, 0} -}; +struct lp_struct lp_table[LP_NO]; /* Test if printer is ready */ #define LP_READY(status) ((status) & LP_PBUSY) @@ -737,6 +729,7 @@ LP_F(minor) &= ~LP_BUSY; return -ENOMEM; } + init_waitqueue_head(&(lp_table[minor].wait_q)); return 0; } @@ -928,6 +921,24 @@ unsigned int count = 0; unsigned int i; struct parport *port; + + for(i = 0; i < LP_NO; i++) { + lp_table[i].dev = NULL; + lp_table[i].flags = 0; + lp_table[i].chars = LP_INIT_CHAR; + lp_table[i].time = LP_INIT_TIME; + lp_table[i].wait = LP_INIT_WAIT; + lp_table[i].lp_buffer = NULL; +#ifdef LP_STATS + lp_table[i].lastcall = 0; + lp_table[i].runchars = 0; + memset(&lp_table[i].stats, 0, sizeof(struct lp_stats)); +#endif + init_waitqueue_head(&lp_table[i].wait_q); + lp_table[i].last_error = 0; + lp_table[i].irq_detected = 0; + lp_table[i].irq_missed = 0; + } switch (parport_nr[0]) { diff -u --recursive --new-file v2.3.0/linux/drivers/char/msbusmouse.c linux/drivers/char/msbusmouse.c --- v2.3.0/linux/drivers/char/msbusmouse.c Wed Dec 16 13:39:11 1998 +++ linux/drivers/char/msbusmouse.c Wed May 12 13:27:37 1999 @@ -195,7 +195,7 @@ mouse.present = mouse.active = mouse.ready = 0; mouse.buttons = 0x80; mouse.dx = mouse.dy = 0; - mouse.wait = NULL; + init_waitqueue_head(&mouse.wait); if (check_region(MS_MSE_CONTROL_PORT, 0x04)) return -ENODEV; diff -u --recursive --new-file v2.3.0/linux/drivers/char/msp3400.c linux/drivers/char/msp3400.c --- v2.3.0/linux/drivers/char/msp3400.c Wed Feb 17 09:37:51 1999 +++ linux/drivers/char/msp3400.c Wed May 12 08:41:07 1999 @@ -83,7 +83,7 @@ /* thread */ struct task_struct *thread; - struct wait_queue *wq; + wait_queue_head_t wq; struct semaphore *notify; int active,restart,rmmod; @@ -523,7 +523,6 @@ current->fs->umask = 0; strcpy(current->comm,"msp3400"); - msp->wq = NULL; msp->thread = current; #ifdef __SMP__ @@ -748,7 +747,7 @@ { unsigned long flags; struct msp3400c *msp = data; - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); int i, val; /* lock_kernel(); */ @@ -844,7 +843,7 @@ static struct msp3400c *mspmix = NULL; /* ugly hack, should do something more sensible */ static int mixer_num; static int mixer_modcnt = 0; -static struct semaphore mixer_sem = MUTEX; +static DECLARE_MUTEX(mixer_sem); static int mix_to_v4l(int i) { @@ -1016,7 +1015,7 @@ static int msp3400c_attach(struct i2c_device *device) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); struct msp3400c *msp; int rev1,rev2; LOCK_FLAGS; @@ -1030,6 +1029,7 @@ msp->right = 65535; msp->bass = 32768; msp->treble = 32768; + init_waitqueue_head(&msp->wq); LOCK_I2C_BUS(msp->bus); if (-1 == msp3400c_reset(msp->bus)) { @@ -1069,7 +1069,6 @@ /* startup control thread */ MOD_INC_USE_COUNT; - msp->wq = NULL; msp->notify = &sem; kernel_thread(msp3400c_thread, (void *)msp, 0); down(&sem); @@ -1090,7 +1089,7 @@ static int msp3400c_detach(struct i2c_device *device) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); struct msp3400c *msp = (struct msp3400c*)device->data; LOCK_FLAGS; diff -u --recursive --new-file v2.3.0/linux/drivers/char/n_hdlc.c linux/drivers/char/n_hdlc.c --- v2.3.0/linux/drivers/char/n_hdlc.c Fri Mar 12 08:20:38 1999 +++ linux/drivers/char/n_hdlc.c Wed May 12 13:27:37 1999 @@ -221,8 +221,8 @@ struct tty_struct *backup_tty; /* TTY to use if tty gets closed */ /* Queues for select() functionality */ - struct wait_queue *read_wait; - struct wait_queue *write_wait; + wait_queue_head_t read_wait; + wait_queue_head_t write_wait; int tbusy; /* reentrancy flag for tx wakeup code */ int woke_up; @@ -724,7 +724,7 @@ { struct n_hdlc *n_hdlc = tty2n_hdlc (tty); int error = 0; - struct wait_queue wait = {current, NULL}; + DECLARE_WAITQUEUE(wait, current); N_HDLC_BUF *tbuf; if (debuglevel >= DEBUG_LEVEL_INFO) @@ -1006,8 +1006,8 @@ n_hdlc->magic = HDLC_MAGIC; n_hdlc->flags = 0; - n_hdlc->read_wait = NULL; - n_hdlc->write_wait = NULL; + init_waitqueue_head(&n_hdlc->read_wait); + init_waitqueue_head(&n_hdlc->write_wait); return n_hdlc; diff -u --recursive --new-file v2.3.0/linux/drivers/char/n_tty.c linux/drivers/char/n_tty.c --- v2.3.0/linux/drivers/char/n_tty.c Sat Apr 24 17:49:37 1999 +++ linux/drivers/char/n_tty.c Tue May 11 14:37:40 1999 @@ -605,7 +605,7 @@ tty->canon_data++; if (tty->fasync) kill_fasync(tty->fasync, SIGIO); - if (tty->read_wait) + if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); return; } @@ -707,7 +707,7 @@ if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { if (tty->fasync) kill_fasync(tty->fasync, SIGIO); - if (tty->read_wait) + if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); } @@ -868,7 +868,7 @@ unsigned char *buf, size_t nr) { unsigned char *b = buf; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int c; int minimum, time; ssize_t retval = 0; @@ -1058,7 +1058,7 @@ const unsigned char * buf, size_t nr) { const unsigned char *b = buf; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int c; ssize_t retval = 0; diff -u --recursive --new-file v2.3.0/linux/drivers/char/pc110pad.c linux/drivers/char/pc110pad.c --- v2.3.0/linux/drivers/char/pc110pad.c Sat Sep 5 17:01:45 1998 +++ linux/drivers/char/pc110pad.c Wed May 12 13:27:37 1999 @@ -48,7 +48,7 @@ /* driver/filesystem interface management */ -static struct wait_queue *queue; +static wait_queue_head_t queue; static struct fasync_struct *asyncptr; static int active=0; /* number of concurrent open()s */ @@ -656,6 +656,7 @@ return -EBUSY; } request_region(current_params.io, 4, "pc110pad"); + init_waitqueue_head(&queue); printk("PC110 digitizer pad at 0x%X, irq %d.\n", current_params.io,current_params.irq); misc_register(&pc110_pad); diff -u --recursive --new-file v2.3.0/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c --- v2.3.0/linux/drivers/char/pc_keyb.c Mon Apr 26 13:43:01 1999 +++ linux/drivers/char/pc_keyb.c Tue May 11 14:37:40 1999 @@ -864,7 +864,7 @@ static ssize_t read_aux(struct file * file, char * buffer, size_t count, loff_t *ppos) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); ssize_t i = count; unsigned char c; @@ -964,7 +964,7 @@ queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL); memset(queue, 0, sizeof(*queue)); queue->head = queue->tail = 0; - queue->proc_list = NULL; + init_waitqueue_head(&queue->proc_list); #ifdef INITIALIZE_MOUSE kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */ diff -u --recursive --new-file v2.3.0/linux/drivers/char/pc_keyb.h linux/drivers/char/pc_keyb.h --- v2.3.0/linux/drivers/char/pc_keyb.h Sat Feb 6 12:46:20 1999 +++ linux/drivers/char/pc_keyb.h Tue May 11 14:37:40 1999 @@ -124,7 +124,7 @@ struct aux_queue { unsigned long head; unsigned long tail; - struct wait_queue *proc_list; + wait_queue_head_t proc_list; struct fasync_struct *fasync; unsigned char buf[AUX_BUF_SIZE]; }; diff -u --recursive --new-file v2.3.0/linux/drivers/char/pty.c linux/drivers/char/pty.c --- v2.3.0/linux/drivers/char/pty.c Sat Feb 6 17:28:37 1999 +++ linux/drivers/char/pty.c Wed May 12 08:41:15 1999 @@ -30,7 +30,7 @@ struct pty_struct { int magic; - struct wait_queue * open_wait; + wait_queue_head_t open_wait; }; #define PTY_MAGIC 0x5001 @@ -336,13 +336,13 @@ __initfunc(int pty_init(void)) { -#ifdef CONFIG_UNIX98_PTYS int i; -#endif /* Traditional BSD devices */ memset(&pty_state, 0, sizeof(pty_state)); + for (i = 0; i < NR_PTYS; i++) + init_waitqueue_head(&pty_state[i].open_wait); memset(&pty_driver, 0, sizeof(struct tty_driver)); pty_driver.magic = TTY_DRIVER_MAGIC; pty_driver.driver_name = "pty_master"; @@ -405,6 +405,8 @@ #ifdef CONFIG_UNIX98_PTYS printk("pty: %d Unix98 ptys configured\n", UNIX98_NR_MAJORS*NR_PTYS); for ( i = 0 ; i < UNIX98_NR_MAJORS ; i++ ) { + int j; + ptm_driver[i] = pty_driver; ptm_driver[i].name = "ptm"; ptm_driver[i].proc_entry = 0; @@ -417,6 +419,9 @@ ptm_driver[i].termios = ptm_termios[i]; ptm_driver[i].termios_locked = ptm_termios_locked[i]; ptm_driver[i].driver_state = ptm_state[i]; + + for (j = 0; j < NR_PTYS; j++) + init_waitqueue_head(&ptm_state[i][j].open_wait); pts_driver[i] = pty_slave_driver; pts_driver[i].name = "pts"; diff -u --recursive --new-file v2.3.0/linux/drivers/char/qpmouse.c linux/drivers/char/qpmouse.c --- v2.3.0/linux/drivers/char/qpmouse.c Sat Oct 31 10:43:36 1998 +++ linux/drivers/char/qpmouse.c Tue May 11 14:37:40 1999 @@ -55,7 +55,7 @@ struct qp_queue { unsigned long head; unsigned long tail; - struct wait_queue *proc_list; + wait_queue_head_t proc_list; struct fasync_struct *fasync; unsigned char buf[QP_BUF_SIZE]; }; @@ -258,7 +258,7 @@ static ssize_t read_qp(struct file * file, char * buffer, size_t count, loff_t *ppos) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); ssize_t i = count; unsigned char c; @@ -354,7 +354,7 @@ queue = (struct qp_queue *) kmalloc(sizeof(*queue), GFP_KERNEL); memset(queue, 0, sizeof(*queue)); queue->head = queue->tail = 0; - queue->proc_list = NULL; + init_waitqueue_head(&queue->proc_list); return 0; } diff -u --recursive --new-file v2.3.0/linux/drivers/char/radio-cadet.c linux/drivers/char/radio-cadet.c --- v2.3.0/linux/drivers/char/radio-cadet.c Mon May 10 13:00:10 1999 +++ linux/drivers/char/radio-cadet.c Wed May 12 13:27:37 1999 @@ -34,7 +34,7 @@ static int curtuner=0; static int tunestat=0; static int sigstrength=0; -struct wait_queue *tunerq,*rdsq,*readq; +static wait_queue_head_t tunerq,rdsq,readq; struct timer_list tunertimer,rdstimer,readtimer; static __u8 rdsin=0,rdsout=0,rdsstat=0; static unsigned char rdsbuf[RDS_BUFFER]; @@ -75,7 +75,7 @@ rdstimer.function=cadet_wake; rdstimer.data=(unsigned long)1; rdstimer.expires=jiffies+(HZ/10); - rdsq=NULL; + init_waitqueue_head(&rdsq); add_timer(&rdstimer); sleep_on(&rdsq); @@ -260,7 +260,7 @@ tunertimer.function=cadet_wake; tunertimer.data=(unsigned long)0; tunertimer.expires=jiffies+(HZ/10); - tunerq=NULL; + init_waitqueue_head(&tunerq); add_timer(&tunertimer); sleep_on(&tunerq); cadet_gettune(); @@ -327,7 +327,7 @@ /* * Service pending read */ - if((rdsin!=rdsout)&&(readq!=NULL)) { + if( rdsin!=rdsout) { wake_up_interruptible(&readq); } @@ -369,7 +369,6 @@ return -EWOULDBLOCK; } interruptible_sleep_on(&readq); - readq=NULL; } while((iclose_delay = 50; info->callout_termios =callout_driver.init_termios; info->normal_termios = rocket_driver.init_termios; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR; @@ -807,7 +809,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, struct r_port *info) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int retval; int do_clocal = 0, extra_count = 0; unsigned long flags; diff -u --recursive --new-file v2.3.0/linux/drivers/char/rocket_int.h linux/drivers/char/rocket_int.h --- v2.3.0/linux/drivers/char/rocket_int.h Fri Jul 10 10:48:37 1998 +++ linux/drivers/char/rocket_int.h Wed May 12 13:27:37 1999 @@ -1144,8 +1144,8 @@ struct termios normal_termios; struct termios callout_termios; struct tq_struct tqueue; - struct wait_queue *open_wait; - struct wait_queue *close_wait; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; }; #define RPORT_MAGIC 0x525001 diff -u --recursive --new-file v2.3.0/linux/drivers/char/rtc.c linux/drivers/char/rtc.c --- v2.3.0/linux/drivers/char/rtc.c Thu Jan 14 22:58:47 1999 +++ linux/drivers/char/rtc.c Tue May 11 14:37:40 1999 @@ -69,7 +69,7 @@ * ioctls. */ -static struct wait_queue *rtc_wait; +static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); static struct timer_list rtc_irq_timer; @@ -150,7 +150,7 @@ static ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long data; ssize_t retval; @@ -567,7 +567,6 @@ #endif init_timer(&rtc_irq_timer); rtc_irq_timer.function = rtc_dropped_irq; - rtc_wait = NULL; save_flags(flags); cli(); /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */ diff -u --recursive --new-file v2.3.0/linux/drivers/char/selection.c linux/drivers/char/selection.c --- v2.3.0/linux/drivers/char/selection.c Thu Sep 17 09:35:03 1998 +++ linux/drivers/char/selection.c Tue May 11 14:37:40 1999 @@ -296,7 +296,7 @@ { struct vt_struct *vt = (struct vt_struct *) tty->driver_data; int pasted = 0, count; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); poke_blanked_console(); add_wait_queue(&vt->paste_wait, &wait); diff -u --recursive --new-file v2.3.0/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v2.3.0/linux/drivers/char/serial.c Tue Mar 23 13:13:58 1999 +++ linux/drivers/char/serial.c Thu May 13 14:52:15 1999 @@ -225,7 +225,7 @@ * memory if large numbers of serial ports are open. */ static unsigned char *tmp_buf; -static struct semaphore tmp_buf_sem = MUTEX; +static DECLARE_MUTEX(tmp_buf_sem); static inline int serial_paranoia_check(struct async_struct *info, kdev_t device, const char *routine) @@ -2422,7 +2422,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, struct async_struct *info) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); struct serial_state *state = info->state; int retval; int do_clocal = 0, extra_count = 0; @@ -2571,6 +2571,9 @@ return -ENOMEM; } memset(info, 0, sizeof(struct async_struct)); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); info->magic = SERIAL_MAGIC; info->port = sstate->port; info->flags = sstate->flags; diff -u --recursive --new-file v2.3.0/linux/drivers/char/specialix.c linux/drivers/char/specialix.c --- v2.3.0/linux/drivers/char/specialix.c Sun May 2 09:51:09 1999 +++ linux/drivers/char/specialix.c Wed May 12 13:27:37 1999 @@ -182,7 +182,7 @@ static struct termios * specialix_termios[SX_NBOARD * SX_NPORT] = { NULL, }; static struct termios * specialix_termios_locked[SX_NBOARD * SX_NPORT] = { NULL, }; static unsigned char * tmp_buf = NULL; -static struct semaphore tmp_buf_sem = MUTEX; +static DECLARE_MUTEX(tmp_buf_sem); static unsigned long baud_table[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, @@ -1311,7 +1311,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, struct specialix_port *port) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); struct specialix_board *bp = port_Board(port); int retval; int do_clocal = 0; @@ -2248,6 +2248,8 @@ sx_port[i].tqueue_hangup.data = &sx_port[i]; sx_port[i].close_delay = 50 * HZ/100; sx_port[i].closing_wait = 3000 * HZ/100; + init_waitqueue_head(&sx_port[i].open_wait); + init_waitqueue_head(&sx_port[i].close_wait); } return 0; diff -u --recursive --new-file v2.3.0/linux/drivers/char/specialix_io8.h linux/drivers/char/specialix_io8.h --- v2.3.0/linux/drivers/char/specialix_io8.h Wed Oct 28 22:04:05 1998 +++ linux/drivers/char/specialix_io8.h Wed May 12 13:27:37 1999 @@ -122,8 +122,8 @@ int xmit_cnt; struct termios normal_termios; struct termios callout_termios; - struct wait_queue *open_wait; - struct wait_queue *close_wait; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; struct tq_struct tqueue; struct tq_struct tqueue_hangup; short wakeup_chars; diff -u --recursive --new-file v2.3.0/linux/drivers/char/synclink.c linux/drivers/char/synclink.c --- v2.3.0/linux/drivers/char/synclink.c Sun Mar 28 10:31:31 1999 +++ linux/drivers/char/synclink.c Wed May 12 13:27:37 1999 @@ -241,11 +241,11 @@ int xmit_tail; int xmit_cnt; - struct wait_queue *open_wait; - struct wait_queue *close_wait; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; - struct wait_queue *status_event_wait_q; - struct wait_queue *event_wait_q; + wait_queue_head_t status_event_wait_q; + wait_queue_head_t event_wait_q; struct timer_list tx_timer; /* HDLC transmit timeout timer */ struct mgsl_struct *next_device; /* device list link */ @@ -904,7 +904,7 @@ * memory if large numbers of serial ports are open. */ static unsigned char *tmp_buf; -static struct semaphore tmp_buf_sem = MUTEX; +static DECLARE_MUTEX(tmp_buf_sem); static inline int mgsl_paranoia_check(struct mgsl_struct *info, kdev_t device, const char *routine) @@ -2724,7 +2724,7 @@ if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) { spin_lock_irqsave(&info->irq_spinlock,flags); - if (!info->event_wait_q) { + if (!waitqueue_active(&info->event_wait_q)) { /* disable enable exit hunt mode/idle rcvd IRQs */ regval = usc_InReg(info,RICR); usc_OutReg(info, RICR, regval & @@ -3295,7 +3295,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, struct mgsl_struct *info) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int retval; int do_clocal = 0, extra_count = 0; unsigned long flags; @@ -4152,6 +4152,10 @@ info->max_frame_size = 4096; info->close_delay = 5*HZ/10; info->closing_wait = 30*HZ; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->status_event_wait_q); + init_waitqueue_head(&info->event_wait_q); memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); info->idle_mode = HDLC_TXIDLE_FLAGS; diff -u --recursive --new-file v2.3.0/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c --- v2.3.0/linux/drivers/char/tpqic02.c Wed Mar 10 16:51:35 1999 +++ linux/drivers/char/tpqic02.c Wed May 12 13:27:37 1999 @@ -127,7 +127,7 @@ static volatile int ctlbits = 0; /* control reg bits for tape interface */ -static struct wait_queue *qic02_tape_transfer = NULL; /* sync rw with interrupts */ +static wait_queue_t qic02_tape_transfer; /* sync rw with interrupts */ static volatile struct mtget ioctl_status; /* current generic status */ @@ -2936,6 +2936,7 @@ return -ENODEV; } + init_waitqueue_head(&qic02_tape_transfer); /* prepare timer */ TIMEROFF; timer_table[QIC02_TAPE_TIMER].expires = 0; diff -u --recursive --new-file v2.3.0/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v2.3.0/linux/drivers/char/tty_io.c Mon Mar 22 10:06:21 1999 +++ linux/drivers/char/tty_io.c Tue May 11 14:37:40 1999 @@ -729,7 +729,7 @@ } /* Semaphore to protect creating and releasing a tty */ -static struct semaphore tty_sem = MUTEX; +static DECLARE_MUTEX(tty_sem); static void down_tty_sem(int index) { @@ -1930,7 +1930,9 @@ tty->flip.flag_buf_ptr = tty->flip.flag_buf; tty->flip.tqueue.routine = flush_to_ldisc; tty->flip.tqueue.data = tty; - tty->flip.pty_sem = MUTEX; + init_MUTEX(&tty->flip.pty_sem); + init_waitqueue_head(&tty->write_wait); + init_waitqueue_head(&tty->read_wait); tty->tq_hangup.routine = do_tty_hangup; tty->tq_hangup.data = tty; sema_init(&tty->atomic_read, 1); diff -u --recursive --new-file v2.3.0/linux/drivers/char/tty_ioctl.c linux/drivers/char/tty_ioctl.c --- v2.3.0/linux/drivers/char/tty_ioctl.c Tue Jan 19 10:12:05 1999 +++ linux/drivers/char/tty_ioctl.c Tue May 11 14:37:40 1999 @@ -42,7 +42,7 @@ void tty_wait_until_sent(struct tty_struct * tty, long timeout) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); #ifdef TTY_DEBUG_WAIT_UNTIL_SENT char buf[64]; diff -u --recursive --new-file v2.3.0/linux/drivers/char/vt.c linux/drivers/char/vt.c --- v2.3.0/linux/drivers/char/vt.c Wed Feb 3 22:57:41 1999 +++ linux/drivers/char/vt.c Tue May 11 14:37:40 1999 @@ -1099,7 +1099,7 @@ * while those not ready go back to sleep. Seems overkill to add a wait * to each vt just for this - usually this does nothing! */ -static struct wait_queue *vt_activate_queue = NULL; +static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue); /* * Sleeps until a vt is activated, or the task is interrupted. Returns @@ -1108,7 +1108,7 @@ int vt_waitactive(int vt) { int retval; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); add_wait_queue(&vt_activate_queue, &wait); for (;;) { diff -u --recursive --new-file v2.3.0/linux/drivers/fc4/fc.c linux/drivers/fc4/fc.c --- v2.3.0/linux/drivers/fc4/fc.c Mon Mar 15 16:11:29 1999 +++ linux/drivers/fc4/fc.c Wed May 12 08:41:15 1999 @@ -551,7 +551,7 @@ l->magic = LSMAGIC; l->count = count; FCND(("FCP Init for %d channels\n", count)) - l->sem = MUTEX_LOCKED; + init_MUTEX_LOCKED(&l->sem); l->timer.function = fcp_login_timeout; l->timer.data = (unsigned long)l; atomic_set (&l->todo, count); @@ -672,7 +672,7 @@ l.count = count; l.magic = LSOMAGIC; FCND(("FCP Force Offline for %d channels\n", count)) - l.sem = MUTEX_LOCKED; + init_MUTEX_LOCKED(&l.sem); l.timer.function = fcp_login_timeout; l.timer.data = (unsigned long)&l; atomic_set (&l.todo, count); @@ -933,7 +933,7 @@ fcp_cmd *cmd; fcp_cmnd *fcmd; fc_channel *fc = FC_SCMND(SCpnt); - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); if (!fc->rst_pkt) { fc->rst_pkt = (Scsi_Cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL); @@ -1070,7 +1070,7 @@ memset (&l, 0, sizeof(lse)); l.magic = LSEMAGIC; - l.sem = MUTEX_LOCKED; + init_MUTEX_LOCKED(&l.sem); l.timer.function = fcp_login_timeout; l.timer.data = (unsigned long)&l; l.status = FC_STATUS_TIMED_OUT; diff -u --recursive --new-file v2.3.0/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c --- v2.3.0/linux/drivers/isdn/isdn_common.c Tue Jan 19 11:06:52 1999 +++ linux/drivers/isdn/isdn_common.c Thu May 13 10:53:38 1999 @@ -741,7 +741,6 @@ isdn_free_queue(&dev->drv[di]->rpqueue[i]); kfree(dev->drv[di]->rpqueue); kfree(dev->drv[di]->rcv_waitq); - kfree(dev->drv[di]->snd_waitq); kfree(dev->drv[di]); dev->drv[di] = NULL; dev->drvid[di][0] = '\0'; @@ -785,7 +784,7 @@ * of the mapping (di,ch)<->minor, happen during the sleep? --he */ int -isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, struct wait_queue **sleep) +isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_queue_head_t *sleep) { int left; int count; @@ -2088,6 +2087,7 @@ return 0; } memset((char *) d, 0, sizeof(driver)); + init_waitqueue_head(&d->st_waitq); if (!(d->rcverr = (int *) kmalloc(sizeof(int) * n, GFP_KERNEL))) { printk(KERN_WARNING "register_isdn: Could not alloc rcverr\n"); kfree(d); @@ -2112,8 +2112,9 @@ for (j = 0; j < n; j++) { skb_queue_head_init(&d->rpqueue[j]); } - if (!(d->rcv_waitq = (struct wait_queue **) - kmalloc(sizeof(struct wait_queue *) * n, GFP_KERNEL))) { + d->rcv_waitq = (wait_queue_head_t *) + kmalloc(sizeof(wait_queue_head_t) * 2 * n, GFP_KERNEL); + if (!d->rcv_waitq) { printk(KERN_WARNING "register_isdn: Could not alloc rcv_waitq\n"); kfree(d->rpqueue); kfree(d->rcvcount); @@ -2121,18 +2122,11 @@ kfree(d); return 0; } - memset((char *) d->rcv_waitq, 0, sizeof(struct wait_queue *) * n); - if (!(d->snd_waitq = (struct wait_queue **) - kmalloc(sizeof(struct wait_queue *) * n, GFP_KERNEL))) { - printk(KERN_WARNING "register_isdn: Could not alloc snd_waitq\n"); - kfree(d->rcv_waitq); - kfree(d->rpqueue); - kfree(d->rcvcount); - kfree(d->rcverr); - kfree(d); - return 0; + d->snd_waitq = d->rcv_waitq + n; + for (j = 0; j < n; j++) { + init_waitqueue_head(&d->rcv_waitq[n]); + init_waitqueue_head(&d->snd_waitq[n]); } - memset((char *) d->snd_waitq, 0, sizeof(struct wait_queue *) * n); d->channels = n; d->loaded = 1; d->maxbufsize = i->maxbufsize; @@ -2215,12 +2209,15 @@ memset((char *) dev, 0, sizeof(isdn_dev)); init_timer(&dev->timer); dev->timer.function = isdn_timer_funct; - dev->sem = MUTEX; + init_MUTEX(&dev->sem); + init_waitqueue_head(&dev->info_waitq); for (i = 0; i < ISDN_MAX_CHANNELS; i++) { dev->drvmap[i] = -1; dev->chanmap[i] = -1; dev->m_idx[i] = -1; strcpy(dev->num[i], "???"); + init_waitqueue_head(&dev->mdm.info[i].open_wait); + init_waitqueue_head(&dev->mdm.info[i].close_wait); } if (register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops)) { printk(KERN_WARNING "isdn: Could not register control devices\n"); diff -u --recursive --new-file v2.3.0/linux/drivers/isdn/isdn_common.h linux/drivers/isdn/isdn_common.h --- v2.3.0/linux/drivers/isdn/isdn_common.h Tue Jan 19 11:06:52 1999 +++ linux/drivers/isdn/isdn_common.h Thu May 13 10:53:42 1999 @@ -90,7 +90,7 @@ extern void isdn_timer_ctrl(int tf, int onoff); extern void isdn_unexclusive_channel(int di, int ch); extern int isdn_getnum(char **); -extern int isdn_readbchan(int, int, u_char *, u_char *, int, struct wait_queue**); +extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); extern int isdn_get_free_channel(int, int, int, int, int); extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); extern int register_isdn(isdn_if * i); diff -u --recursive --new-file v2.3.0/linux/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c --- v2.3.0/linux/drivers/isdn/isdn_ppp.c Tue Jan 19 11:06:52 1999 +++ linux/drivers/isdn/isdn_ppp.c Thu May 13 10:53:46 1999 @@ -359,8 +359,7 @@ ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK; - if (ippp_table[lp->ppp_slot]->wq) - wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq); + wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq); } /* @@ -377,7 +376,7 @@ return 0; is = ippp_table[slot]; - if (is->state && is->wq) + if (is->state) wake_up_interruptible(&is->wq); is->state = IPPP_CLOSEWAIT; @@ -437,8 +436,9 @@ is->mru = 1524; /* MRU, default 1524 */ is->maxcid = 16; /* VJ: maxcid */ is->tk = current; - is->wq = NULL; /* read() wait queue */ - is->wq1 = NULL; /* select() wait queue */ + /* next two are redundant, but be paranoid */ + init_waitqueue_head(&is->wq); /* read() wait queue */ + init_waitqueue_head(&is->wql); /* select() wait queue */ is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */ is->last = is->rq; is->minor = min; @@ -777,8 +777,7 @@ is->last = bl->next; restore_flags(flags); - if (is->wq) - wake_up_interruptible(&is->wq); + wake_up_interruptible(&is->wq); return len; } @@ -911,6 +910,8 @@ return -1; } memset((char *) ippp_table[i], 0, sizeof(struct ippp_struct)); + init_waitqueue_head(&ippp_table[i]->wq); + init_waitqueue_head(&ippp_table[i]->wql); ippp_table[i]->state = 0; ippp_table[i]->first = ippp_table[i]->rq + NUM_RCV_BUFFS - 1; ippp_table[i]->last = ippp_table[i]->rq; diff -u --recursive --new-file v2.3.0/linux/drivers/isdn/isdn_tty.c linux/drivers/isdn/isdn_tty.c --- v2.3.0/linux/drivers/isdn/isdn_tty.c Sat Oct 31 10:37:14 1998 +++ linux/drivers/isdn/isdn_tty.c Thu May 13 10:53:50 1999 @@ -1567,8 +1567,7 @@ static int isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info * info) { - struct wait_queue wait = - {current, NULL}; + DECLARE_WAITQUEUE(wait, current); int do_clocal = 0; unsigned long flags; int retval; @@ -2004,8 +2003,8 @@ info->blocked_open = 0; info->callout_termios = m->cua_modem.init_termios; info->normal_termios = m->tty_modem.init_termios; - info->open_wait = 0; - info->close_wait = 0; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); info->isdn_driver = -1; info->isdn_channel = -1; info->drv_index = -1; diff -u --recursive --new-file v2.3.0/linux/drivers/misc/parport_share.c linux/drivers/misc/parport_share.c --- v2.3.0/linux/drivers/misc/parport_share.c Tue Oct 27 10:32:29 1998 +++ linux/drivers/misc/parport_share.c Tue May 11 23:38:24 1999 @@ -277,7 +277,7 @@ inc_parport_count(); port->ops->inc_use_count(); - init_waitqueue(&tmp->wait_q); + init_waitqueue_head(&tmp->wait_q); tmp->timeslice = PARPORT_DEFAULT_TIMESLICE; tmp->waitnext = tmp->waitprev = NULL; diff -u --recursive --new-file v2.3.0/linux/drivers/net/3c527.c linux/drivers/net/3c527.c --- v2.3.0/linux/drivers/net/3c527.c Sun Mar 21 07:11:36 1999 +++ linux/drivers/net/3c527.c Wed May 12 13:27:37 1999 @@ -102,7 +102,7 @@ u16 exec_pending; u16 mc_reload_wait; /* a multicast load request is pending */ atomic_t tx_count; /* buffers left */ - struct wait_queue *event; + wait_queue_head_t event; struct sk_buff *tx_skb[TX_RING_MAX]; /* Transmit ring */ u16 tx_skb_top; u16 tx_skb_end; @@ -411,6 +411,7 @@ lp->rx_chain = lp->exec_box->data[10]; lp->tx_len = lp->exec_box->data[9]; lp->rx_len = lp->exec_box->data[11]; + init_waitqueue_head(&lp->event); printk("%s: %d RX buffers, %d TX buffers. Base of 0x%08X.\n", dev->name, lp->rx_len, lp->tx_len, lp->base); diff -u --recursive --new-file v2.3.0/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c --- v2.3.0/linux/drivers/net/ibmtr.c Fri May 7 10:57:42 1999 +++ linux/drivers/net/ibmtr.c Wed May 12 13:27:37 1999 @@ -404,6 +404,8 @@ #endif ti->mmio= t_mmio; ti->readlog_pending = 0; + init_waitqueue_head(&ti->wait_for_tok_int); + init_waitqueue_head(&ti->wait_for_reset); dev->priv = ti; /* this seems like the logical use of the field ... let's try some empirical tests diff -u --recursive --new-file v2.3.0/linux/drivers/net/ibmtr.h linux/drivers/net/ibmtr.h --- v2.3.0/linux/drivers/net/ibmtr.h Tue Mar 16 14:21:52 1999 +++ linux/drivers/net/ibmtr.h Wed May 12 13:27:37 1999 @@ -193,8 +193,8 @@ unsigned short maxmtu16; /* Additions by David Morris */ unsigned char do_tok_int; - struct wait_queue *wait_for_tok_int; - struct wait_queue *wait_for_reset; + wait_queue_head_t wait_for_tok_int; + wait_queue_head_t wait_for_reset; unsigned char sram_base; /* Additions by Peter De Schrijver */ unsigned char page_mask; /* mask to select RAM page to Map*/ diff -u --recursive --new-file v2.3.0/linux/drivers/net/ppp.c linux/drivers/net/ppp.c --- v2.3.0/linux/drivers/net/ppp.c Tue May 11 09:55:45 1999 +++ linux/drivers/net/ppp.c Wed May 12 08:41:15 1999 @@ -2834,7 +2834,7 @@ ppp->magic = PPP_MAGIC; ppp->next = NULL; ppp->inuse = 1; - ppp->read_wait = NULL; + init_waitqueue_head(&ppp->read_wait); /* * Make up a suitable name for this device diff -u --recursive --new-file v2.3.0/linux/drivers/net/shaper.c linux/drivers/net/shaper.c --- v2.3.0/linux/drivers/net/shaper.c Wed Mar 10 16:51:35 1999 +++ linux/drivers/net/shaper.c Wed May 12 13:27:37 1999 @@ -582,6 +582,7 @@ init_timer(&sh->timer); sh->timer.function=shaper_timer; sh->timer.data=(unsigned long)sh; + init_waitqueue_head(&sh->wait_queue); return sh; } diff -u --recursive --new-file v2.3.0/linux/drivers/net/sktr.c linux/drivers/net/sktr.c --- v2.3.0/linux/drivers/net/sktr.c Thu Jan 7 08:46:59 1999 +++ linux/drivers/net/sktr.c Wed May 12 13:27:37 1999 @@ -414,7 +414,8 @@ if(tp == NULL) return (-ENOMEM); memset(tp, 0, sizeof(struct net_local)); - + init_waitqueue_head(&tp->wait_for_tok_int); + dev->priv = tp; dev->init = sktr_init_card; dev->open = sktr_open; diff -u --recursive --new-file v2.3.0/linux/drivers/net/sktr.h linux/drivers/net/sktr.h --- v2.3.0/linux/drivers/net/sktr.h Wed Jun 24 14:26:13 1998 +++ linux/drivers/net/sktr.h Wed May 12 13:27:37 1999 @@ -1087,7 +1087,7 @@ struct timer_list timer; - struct wait_queue *wait_for_tok_int; + wait_queue_head_t wait_for_tok_int; INTPTRS intptrs; /* Internal adapter pointer. Must be read * before OPEN command. diff -u --recursive --new-file v2.3.0/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c --- v2.3.0/linux/drivers/pci/oldproc.c Wed Apr 21 09:28:49 1999 +++ linux/drivers/pci/oldproc.c Thu May 13 11:00:08 1999 @@ -203,6 +203,7 @@ DEVICE( MOTOROLA, MOTOROLA_MPC106,"MPC106 Grackle"), DEVICE( MOTOROLA, MOTOROLA_RAVEN, "Raven"), DEVICE( PROMISE, PROMISE_20246, "IDE UltraDMA/33"), + DEVICE( PROMISE, PROMISE_20262, "IDE UltraDMA/66"), DEVICE( PROMISE, PROMISE_5300, "DC5030"), DEVICE( N9, N9_I128, "Imagine 128"), DEVICE( N9, N9_I128_2, "Imagine 128v2"), @@ -290,11 +291,15 @@ DEVICE( AL, AL_M1523, "M1523"), DEVICE( AL, AL_M1531, "M1531 Aladdin IV"), DEVICE( AL, AL_M1533, "M1533 Aladdin IV"), + DEVICE( AL, AL_M1541, "M1541 Aladdin V"), + DEVICE( AL, AL_M1543, "M1543 Aladdin V"), DEVICE( AL, AL_M3307, "M3307 MPEG-1 decoder"), DEVICE( AL, AL_M4803, "M4803"), DEVICE( AL, AL_M5219, "M5219"), DEVICE( AL, AL_M5229, "M5229 TXpro"), DEVICE( AL, AL_M5237, "M5237 USB"), + DEVICE( AL, AL_M5243, "M5243 AGP"), + DEVICE( AL, AL_M7101, "M7101 PMU"), DEVICE( SURECOM, SURECOM_NE34, "NE-34PCI LAN"), DEVICE( NEOMAGIC, NEOMAGIC_MAGICGRAPH_NM2070, "Magicgraph NM2070"), DEVICE( NEOMAGIC, NEOMAGIC_MAGICGRAPH_128V, "MagicGraph 128V"), diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/audio/audio.c linux/drivers/sbus/audio/audio.c --- v2.3.0/linux/drivers/sbus/audio/audio.c Thu Apr 22 19:24:51 1999 +++ linux/drivers/sbus/audio/audio.c Wed May 12 08:41:15 1999 @@ -117,6 +117,11 @@ * TODO: Make number of input/output buffers tunable parameters */ + init_waitqueue_head(&drv->open_wait); + init_waitqueue_head(&drv->output_write_wait); + init_waitqueue_head(&drv->output_drain_wait); + init_waitqueue_head(&drv->input_read_wait); + drv->num_output_buffers = 8; drv->output_buffer_size = (4096 * 2); drv->playing_count = 0; diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/audio/dbri.h linux/drivers/sbus/audio/dbri.h --- v2.3.0/linux/drivers/sbus/audio/dbri.h Mon Mar 15 16:11:30 1999 +++ linux/drivers/sbus/audio/dbri.h Wed May 12 08:41:15 1999 @@ -85,7 +85,7 @@ struct cs4215 mm; /* mmcodec special info */ #if 0 - struct wait_queue *wait, *int_wait; /* Where to sleep if busy */ + wait_queue_head_t wait, int_wait; /* Where to sleep if busy */ #endif struct audio_info perchip_info; diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/char/bpp.c linux/drivers/sbus/char/bpp.c --- v2.3.0/linux/drivers/sbus/char/bpp.c Mon Mar 15 16:11:30 1999 +++ linux/drivers/sbus/char/bpp.c Wed May 12 08:41:15 1999 @@ -81,7 +81,7 @@ unsigned char repeat_byte; /* These members manage timeouts for programmed delays */ - struct wait_queue *wait_queue; + wait_queue_head_t wait_queue; struct timer_list timer_list; }; diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/char/pcikbd.c linux/drivers/sbus/char/pcikbd.c --- v2.3.0/linux/drivers/sbus/char/pcikbd.c Tue May 11 08:24:32 1999 +++ linux/drivers/sbus/char/pcikbd.c Wed May 12 08:41:15 1999 @@ -1,4 +1,4 @@ -/* $Id: pcikbd.c,v 1.27 1999/05/09 06:40:47 ecd Exp $ +/* $Id: pcikbd.c,v 1.28 1999/05/12 11:15:05 davem Exp $ * pcikbd.c: Ultra/AX PC keyboard support. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -588,7 +588,7 @@ struct aux_queue { unsigned long head; unsigned long tail; - struct wait_queue *proc_list; + wait_queue_head_t proc_list; struct fasync_struct *fasync; unsigned char buf[AUX_BUF_SIZE]; }; @@ -739,7 +739,7 @@ * doing so might cause the keyboard driver to ignore all incoming keystrokes. */ -static struct semaphore aux_sema4 = MUTEX; +static DECLARE_MUTEX(aux_sema4); static inline void aux_start_atomic(void) { @@ -879,7 +879,7 @@ static ssize_t aux_read(struct file * file, char * buffer, size_t count, loff_t *ppos) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); ssize_t i = count; unsigned char c; diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/char/sab82532.c linux/drivers/sbus/char/sab82532.c --- v2.3.0/linux/drivers/sbus/char/sab82532.c Thu Mar 25 09:23:34 1999 +++ linux/drivers/sbus/char/sab82532.c Wed May 12 08:41:15 1999 @@ -1,4 +1,4 @@ -/* $Id: sab82532.c,v 1.30 1999/03/24 11:34:52 davem Exp $ +/* $Id: sab82532.c,v 1.31 1999/05/12 11:15:10 davem Exp $ * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -100,7 +100,7 @@ * memory if large numbers of serial ports are open. */ static unsigned char *tmp_buf = 0; -static struct semaphore tmp_buf_sem = MUTEX; +static DECLARE_MUTEX(tmp_buf_sem); static inline int serial_paranoia_check(struct sab82532 *info, kdev_t device, const char *routine) @@ -1715,7 +1715,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, struct sab82532 *info) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int retval; int do_clocal = 0; @@ -2136,7 +2136,7 @@ __initfunc(static inline void show_serial_version(void)) { - char *revision = "$Revision: 1.30 $"; + char *revision = "$Revision: 1.31 $"; char *version, *p; version = strchr(revision, ' '); @@ -2247,9 +2247,9 @@ info->tqueue_hangup.data = info; info->callout_termios = callout_driver.init_termios; info->normal_termios = serial_driver.init_termios; - info->open_wait = 0; - info->close_wait = 0; - info->delta_msr_wait = 0; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); info->icount.cts = info->icount.dsr = info->icount.rng = info->icount.dcd = 0; info->icount.rx = info->icount.tx = 0; diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/char/su.c linux/drivers/sbus/char/su.c --- v2.3.0/linux/drivers/sbus/char/su.c Mon Mar 15 16:11:30 1999 +++ linux/drivers/sbus/char/su.c Wed May 12 08:41:15 1999 @@ -1,4 +1,4 @@ -/* $Id: su.c,v 1.18 1999/01/02 16:47:37 davem Exp $ +/* $Id: su.c,v 1.19 1999/05/12 11:15:14 davem Exp $ * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -135,9 +135,9 @@ int xmit_tail; int xmit_cnt; struct tq_struct tqueue; - struct wait_queue *open_wait; - struct wait_queue *close_wait; - struct wait_queue *delta_msr_wait; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; + wait_queue_head_t delta_msr_wait; int count; struct async_icount icount; @@ -200,7 +200,7 @@ * memory if large numbers of serial ports are open. */ static unsigned char *tmp_buf; -static struct semaphore tmp_buf_sem = MUTEX; +static DECLARE_MUTEX(tmp_buf_sem); static inline int serial_paranoia_check(struct su_struct *info, kdev_t device, const char *routine) @@ -1878,7 +1878,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, struct su_struct *info) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int retval; int do_clocal = 0, extra_count = 0; unsigned long flags; @@ -2215,7 +2215,7 @@ */ __initfunc(static __inline__ void show_su_version(void)) { - char *revision = "$Revision: 1.18 $"; + char *revision = "$Revision: 1.19 $"; char *version, *p; version = strchr(revision, ' '); diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/char/sunkbd.c linux/drivers/sbus/char/sunkbd.c --- v2.3.0/linux/drivers/sbus/char/sunkbd.c Thu Apr 22 19:24:51 1999 +++ linux/drivers/sbus/char/sunkbd.c Wed May 12 08:41:15 1999 @@ -85,7 +85,7 @@ } #ifndef CONFIG_PCI -struct wait_queue * keypress_wait = NULL; +DECLARE_WAIT_QUEUE_HEAD(keypress_wait); #endif int keyboard_wait_for_keypress(struct console *co) @@ -1261,7 +1261,7 @@ static int kbd_head, kbd_tail; char kbd_opened; static int kbd_active = 0; -static struct wait_queue *kbd_wait; +static DECLARE_WAIT_QUEUE_HEAD(kbd_wait); static struct fasync_struct *kb_fasync; void @@ -1285,7 +1285,7 @@ static ssize_t kbd_read (struct file *f, char *buffer, size_t count, loff_t *ppos) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); char *end, *p; /* Return EWOULDBLOCK, because this is what the X server expects */ diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/char/sunmouse.c linux/drivers/sbus/char/sunmouse.c --- v2.3.0/linux/drivers/sbus/char/sunmouse.c Thu Apr 22 19:24:51 1999 +++ linux/drivers/sbus/char/sunmouse.c Wed May 12 08:41:15 1999 @@ -73,7 +73,7 @@ int ready; /* set if there if data is available */ int active; /* set if device is open */ int vuid_mode; /* VUID_NATIVE or VUID_FIRM_EVENT */ - struct wait_queue *proc_list; + wait_queue_head_t proc_list; struct fasync_struct *fasync; /* The event/stream queue */ @@ -368,7 +368,7 @@ sun_mouse_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); if (queue_empty ()){ if (file->f_flags & O_NONBLOCK) @@ -503,7 +503,7 @@ misc_register (&sun_mouse_mouse); sunmouse.delta_x = sunmouse.delta_y = 0; sunmouse.button_state = 0x80; - sunmouse.proc_list = NULL; + init_waitqueue_head(&sunmouse.proc_list); sunmouse.byte = 69; return 0; } diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/char/vfc.h linux/drivers/sbus/char/vfc.h --- v2.3.0/linux/drivers/sbus/char/vfc.h Tue May 13 22:41:12 1997 +++ linux/drivers/sbus/char/vfc.h Wed May 12 08:41:15 1999 @@ -128,7 +128,7 @@ unsigned int control_reg; struct semaphore device_lock_sem; struct timer_list poll_timer; - struct wait_queue *poll_wait; + wait_queue_head_t poll_wait; int instance; int busy; unsigned long which_io; diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/char/zs.c linux/drivers/sbus/char/zs.c --- v2.3.0/linux/drivers/sbus/char/zs.c Thu Apr 22 19:24:51 1999 +++ linux/drivers/sbus/char/zs.c Wed May 12 08:41:15 1999 @@ -1,4 +1,4 @@ -/* $Id: zs.c,v 1.41 1999/04/16 16:22:27 jj Exp $ +/* $Id: zs.c,v 1.42 1999/05/12 11:15:26 davem Exp $ * zs.c: Zilog serial port driver for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -174,7 +174,7 @@ * memory if large numbers of serial ports are open. */ static unsigned char tmp_buf[4096]; /* This is cheating */ -static struct semaphore tmp_buf_sem = MUTEX; +static DECLARE_MUTEX(tmp_buf_sem); static inline int serial_paranoia_check(struct sun_serial *info, dev_t device, const char *routine) @@ -1628,7 +1628,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, struct sun_serial *info) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int retval; int do_clocal = 0; unsigned char r0; @@ -1844,7 +1844,7 @@ static void show_serial_version(void) { - char *revision = "$Revision: 1.41 $"; + char *revision = "$Revision: 1.42 $"; char *version, *p; version = strchr(revision, ' '); @@ -2517,8 +2517,8 @@ info->tqueue_hangup.data = info; info->callout_termios = callout_driver.init_termios; info->normal_termios = serial_driver.init_termios; - info->open_wait = 0; - info->close_wait = 0; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); printk("tty%02d at 0x%04x (irq = %s)", info->line, info->port, __irq_itoa(info->irq)); printk(" is a Zilog8530\n"); diff -u --recursive --new-file v2.3.0/linux/drivers/sbus/char/zs.h linux/drivers/sbus/char/zs.h --- v2.3.0/linux/drivers/sbus/char/zs.h Thu Sep 4 12:54:49 1997 +++ linux/drivers/sbus/char/zs.h Wed May 12 08:41:15 1999 @@ -1,4 +1,4 @@ -/* $Id: zs.h,v 1.1 1997/08/28 02:23:45 ecd Exp $ +/* $Id: zs.h,v 1.2 1999/05/12 11:15:31 davem Exp $ * zs.h: Definitions for the Sparc Zilog serial driver. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -151,8 +151,8 @@ struct tq_struct tqueue_hangup; struct termios normal_termios; struct termios callout_termios; - struct wait_queue *open_wait; - struct wait_queue *close_wait; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; }; diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c --- v2.3.0/linux/drivers/scsi/aha152x.c Mon Apr 12 16:18:26 1999 +++ linux/drivers/scsi/aha152x.c Wed May 12 13:19:17 1999 @@ -414,8 +414,13 @@ #define P_PARITY 2 /* possible irq range */ +#ifdef PCMCIA +#define IRQ_MIN 0 +#define IRQ_MAX 16 +#else #define IRQ_MIN 9 #define IRQ_MAX 12 +#endif #define IRQS IRQ_MAX-IRQ_MIN+1 enum { @@ -746,7 +751,7 @@ if(!aha152x_porttest(setup->io_port)) return 0; - if(setup->irqirq>IRQ_MAX) + if((setup->irqirq>IRQ_MAX)) return 0; if((setup->scsiid < 0) || (setup->scsiid > 7)) diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/atari_scsi.c linux/drivers/scsi/atari_scsi.c --- v2.3.0/linux/drivers/scsi/atari_scsi.c Thu Jul 30 11:17:10 1998 +++ linux/drivers/scsi/atari_scsi.c Tue May 11 15:49:26 1999 @@ -497,9 +497,9 @@ static int falcon_got_lock = 0; -static struct wait_queue *falcon_fairness_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(falcon_fairness_wait); static int falcon_trying_lock = 0; -static struct wait_queue *falcon_try_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(falcon_try_wait); static int falcon_dont_release = 0; /* This function releases the lock on the DMA chip if there is no diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/eata_dma_proc.c linux/drivers/scsi/eata_dma_proc.c --- v2.3.0/linux/drivers/scsi/eata_dma_proc.c Thu Jan 7 09:28:47 1999 +++ linux/drivers/scsi/eata_dma_proc.c Wed May 12 13:27:37 1999 @@ -184,7 +184,7 @@ * Do the command and wait for it to finish. */ { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); scmd.request.rq_status = RQ_SCSI_BUSY; scmd.request.sem = &sem; scsi_do_cmd (&scmd, cmnd, buff + 0x144, 0x66, @@ -314,7 +314,7 @@ * Do the command and wait for it to finish. */ { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); scmd.request.rq_status = RQ_SCSI_BUSY; scmd.request.sem = &sem; scsi_do_cmd (&scmd, cmnd, buff2, 0x144, diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/gdth_proc.c linux/drivers/scsi/gdth_proc.c --- v2.3.0/linux/drivers/scsi/gdth_proc.c Mon Apr 12 09:56:16 1999 +++ linux/drivers/scsi/gdth_proc.c Wed May 12 13:27:37 1999 @@ -931,7 +931,7 @@ static void gdth_do_cmd(Scsi_Cmnd *scp,gdth_cmd_str *gdtcmd,int timeout) { char cmnd[12]; - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); TRACE2(("gdth_do_cmd()\n")); memset(cmnd, 0, 12); diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c --- v2.3.0/linux/drivers/scsi/hosts.c Mon Apr 12 09:51:04 1999 +++ linux/drivers/scsi/hosts.c Tue May 11 14:37:40 1999 @@ -665,7 +665,7 @@ retval->host_no = max_scsi_hosts++; /* never reuse host_no (DB) */ next_scsi_host++; retval->host_queue = NULL; - retval->host_wait = NULL; + init_waitqueue_head(&retval->host_wait); retval->resetting = 0; retval->last_reset = 0; retval->irq = 0; @@ -738,7 +738,7 @@ */ static void launch_error_handler_thread(struct Scsi_Host * shpnt) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); shpnt->eh_notify = &sem; diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h --- v2.3.0/linux/drivers/scsi/hosts.h Tue May 11 13:04:44 1999 +++ linux/drivers/scsi/hosts.h Thu May 13 14:43:03 1999 @@ -313,7 +313,7 @@ host. */ unsigned int eh_active:1; /* Indicates the eh thread is awake and active if this is true. */ - struct wait_queue * host_wait; + wait_queue_head_t host_wait; Scsi_Host_Template * hostt; atomic_t host_active; /* commands checked out */ volatile unsigned short host_busy; /* commands actually active on low-level */ diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c --- v2.3.0/linux/drivers/scsi/megaraid.c Thu May 6 23:14:37 1999 +++ linux/drivers/scsi/megaraid.c Tue May 11 15:48:45 1999 @@ -1522,7 +1522,7 @@ *----------------------------------------------------------------------*/ volatile static int internal_done_flag = 0; volatile static int internal_done_errcode = 0; -static struct wait_queue *internal_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(internal_wait); static void internal_done (Scsi_Cmnd * SCpnt) { diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/pluto.c linux/drivers/scsi/pluto.c --- v2.3.0/linux/drivers/scsi/pluto.c Mon Mar 15 16:11:31 1999 +++ linux/drivers/scsi/pluto.c Wed May 12 08:41:15 1999 @@ -54,7 +54,7 @@ static int fcscount __initdata = 0; static atomic_t fcss __initdata = ATOMIC_INIT(0); static struct timer_list fc_timer __initdata = { 0 }; -struct semaphore fc_sem __initdata = MUTEX_LOCKED; +DECLARE_MUTEX_LOCKED(fc_sem); static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd); diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.3.0/linux/drivers/scsi/scsi.c Thu Apr 29 11:53:41 1999 +++ linux/drivers/scsi/scsi.c Tue May 11 14:37:40 1999 @@ -473,6 +473,8 @@ SDpnt->host = shpnt; SDpnt->online = TRUE; + init_waitqueue_head(&SDpnt->device_wait); + /* * Next, hook the device to the host in question. */ @@ -660,7 +662,7 @@ SCpnt->lun = SDpnt->lun; SCpnt->channel = SDpnt->channel; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; SCpnt->request.rq_status = RQ_SCSI_BUSY; spin_lock_irq(&io_request_lock); @@ -703,7 +705,7 @@ scsi_cmd[5] = 0; SCpnt->cmd_len = 0; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; SCpnt->request.rq_status = RQ_SCSI_BUSY; spin_lock_irq(&io_request_lock); @@ -849,7 +851,7 @@ scsi_cmd[5] = 0; SCpnt->cmd_len = 0; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; spin_lock_irq(&io_request_lock); @@ -890,6 +892,8 @@ SDpnt->device_queue = SCpnt; SDpnt->online = TRUE; + init_waitqueue_head(&SDpnt->device_wait); + /* * Since we just found one device, there had damn well better be one in the list * already. @@ -2639,7 +2643,7 @@ { if( shpnt->hostt == tpnt && shpnt->hostt->use_new_eh_code ) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); shpnt->eh_notify = &sem; kernel_thread((int (*)(void *))scsi_error_handler, @@ -2876,7 +2880,7 @@ && shpnt->hostt->use_new_eh_code && shpnt->ehandler != NULL ) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); shpnt->eh_notify = &sem; send_sig(SIGKILL, shpnt->ehandler, 1); diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h --- v2.3.0/linux/drivers/scsi/scsi.h Tue May 11 13:04:47 1999 +++ linux/drivers/scsi/scsi.h Thu May 13 14:43:05 1999 @@ -417,7 +417,7 @@ */ struct scsi_device * next; /* Used for linked list */ struct scsi_device * prev; /* Used for linked list */ - struct wait_queue * device_wait;/* Used to wait if + wait_queue_head_t device_wait;/* Used to wait if device is busy */ struct Scsi_Host * host; volatile unsigned short device_busy; /* commands actually active on low-level */ @@ -711,7 +711,7 @@ #define SCSI_SLEEP(QUEUE, CONDITION) { \ if (CONDITION) { \ - struct wait_queue wait = { current, NULL}; \ + DECLARE_WAITQUEUE(wait, current); \ add_wait_queue(QUEUE, &wait); \ for(;;) { \ current->state = TASK_UNINTERRUPTIBLE; \ diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c --- v2.3.0/linux/drivers/scsi/scsi_error.c Wed Feb 24 16:27:54 1999 +++ linux/drivers/scsi/scsi_error.c Tue May 11 14:37:40 1999 @@ -560,7 +560,7 @@ void scsi_sleep (int timeout) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); struct timer_list timer; init_timer(&timer); @@ -603,7 +603,7 @@ if (host->can_queue) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->eh_state = SCSI_STATE_QUEUED; @@ -1924,7 +1924,7 @@ { struct Scsi_Host * host = (struct Scsi_Host *) data; int rtn; - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); unsigned long flags; lock_kernel(); diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c --- v2.3.0/linux/drivers/scsi/scsi_ioctl.c Thu Apr 29 11:53:41 1999 +++ linux/drivers/scsi/scsi_ioctl.c Tue May 11 14:37:40 1999 @@ -113,7 +113,7 @@ SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", cmd[0])); SCpnt = scsi_allocate_device(NULL, dev, 1); { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; scsi_do_cmd(SCpnt, cmd, NULL, 0, scsi_ioctl_done, timeout, retries); spin_unlock_irqrestore(&io_request_lock, flags); @@ -289,7 +289,7 @@ SCpnt = scsi_allocate_device(NULL, dev, 1); { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; scsi_do_cmd(SCpnt, cmd, buf, needed, scsi_ioctl_done, timeout, retries); diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c --- v2.3.0/linux/drivers/scsi/sd.c Thu Apr 29 11:53:41 1999 +++ linux/drivers/scsi/sd.c Tue May 11 14:37:40 1999 @@ -1183,7 +1183,7 @@ SCpnt->sense_buffer[2] = 0; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); /* Mark as really busy again */ SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; @@ -1221,7 +1221,7 @@ SCpnt->sense_buffer[2] = 0; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); /* Mark as really busy again */ SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; @@ -1263,7 +1263,7 @@ SCpnt->sense_buffer[2] = 0; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); /* Mark as really busy again */ SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; @@ -1444,7 +1444,7 @@ /* same code as READCAPA !! */ { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.rq_status = RQ_SCSI_BUSY; /* Mark as really busy again */ SCpnt->request.sem = &sem; scsi_do_cmd (SCpnt, diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c --- v2.3.0/linux/drivers/scsi/sg.c Fri May 7 11:05:30 1999 +++ linux/drivers/scsi/sg.c Tue May 11 14:37:40 1999 @@ -135,7 +135,7 @@ { struct sg_fd * nextfp; /* NULL when last opened fd on this device */ struct sg_device * parentdp; /* owning device */ - struct wait_queue * read_wait; /* queue read until command done */ + wait_queue_head_t read_wait; /* queue read until command done */ int timeout; /* defaults to SG_DEFAULT_TIMEOUT */ char * fst_buf; /* try to grab SG_SCATTER_SZ sized buffer on open */ int fb_size; /* actual size of allocated fst_buf */ @@ -153,7 +153,7 @@ typedef struct sg_device /* holds the state of each scsi generic device */ { Scsi_Device * device; - struct wait_queue * generic_wait;/* queue open if O_EXCL on prev. open */ + wait_queue_head_t generic_wait;/* queue open if O_EXCL on prev. open */ int sg_tablesize; /* adapter's max scatter-gather table size */ Sg_fd * headfp; /* first open fd belonging to this device */ kdev_t i_rdev; /* holds device major+minor number */ @@ -988,7 +988,7 @@ SCSI_LOG_TIMEOUT(3, printk("sg_attach: dev=%d \n", k)); sdp->device = scsidp; - sdp->generic_wait = NULL; + init_waitqueue_head(&sdp->generic_wait); sdp->headfp= NULL; sdp->exclude = 0; sdp->merge_fd = 0; /* Cope with SG_DEF_MERGE_FD on open */ diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c --- v2.3.0/linux/drivers/scsi/sr.c Fri Jan 15 14:41:04 1999 +++ linux/drivers/scsi/sr.c Tue May 11 14:37:40 1999 @@ -895,7 +895,7 @@ /* Do the command and wait.. */ { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; spin_lock_irqsave(&io_request_lock, flags); scsi_do_cmd (SCpnt, diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c --- v2.3.0/linux/drivers/scsi/sr_ioctl.c Mon May 10 13:01:21 1999 +++ linux/drivers/scsi/sr_ioctl.c Tue May 11 14:37:40 1999 @@ -64,7 +64,7 @@ if( !scsi_block_when_processing_errors(SDev) ) return -ENODEV; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; spin_lock_irqsave(&io_request_lock, flags); scsi_do_cmd(SCpnt, diff -u --recursive --new-file v2.3.0/linux/drivers/scsi/st.c linux/drivers/scsi/st.c --- v2.3.0/linux/drivers/scsi/st.c Sun Mar 7 15:20:26 1999 +++ linux/drivers/scsi/st.c Tue May 11 14:37:40 1999 @@ -279,7 +279,7 @@ } cmd[1] |= (SCpnt->lun << 5) & 0xe0; - STp->sem = MUTEX_LOCKED; + init_MUTEX_LOCKED(&STp->sem); SCpnt->use_sg = (bytes > (STp->buffer)->sg[0].length) ? (STp->buffer)->use_sg : 0; if (SCpnt->use_sg) { diff -u --recursive --new-file v2.3.0/linux/drivers/sound/dev_table.c linux/drivers/sound/dev_table.c --- v2.3.0/linux/drivers/sound/dev_table.c Mon Apr 12 16:18:27 1999 +++ linux/drivers/sound/dev_table.c Tue May 11 23:40:50 1999 @@ -435,9 +435,9 @@ return -(ENOMEM); } memset((char *) op, 0, sizeof(struct audio_operations)); - init_waitqueue(&op->in_sleeper); - init_waitqueue(&op->out_sleeper); - init_waitqueue(&op->poll_sleeper); + init_waitqueue_head(&op->in_sleeper); + init_waitqueue_head(&op->out_sleeper); + init_waitqueue_head(&op->poll_sleeper); if (driver_size < sizeof(struct audio_driver)) memset((char *) d, 0, sizeof(struct audio_driver)); diff -u --recursive --new-file v2.3.0/linux/drivers/sound/dmasound.c linux/drivers/sound/dmasound.c --- v2.3.0/linux/drivers/sound/dmasound.c Wed Mar 10 21:48:46 1999 +++ linux/drivers/sound/dmasound.c Tue May 11 23:28:01 1999 @@ -809,7 +809,7 @@ * Bit 1 is set: a frame is playing */ int playing; - struct wait_queue *write_queue, *open_queue, *sync_queue; + wait_queue_head_t write_queue, open_queue, sync_queue; int open_mode; int busy, syncing; #ifdef CONFIG_ATARI @@ -4623,7 +4623,9 @@ if (sq_unit < 0) return; - sq.write_queue = sq.open_queue = sq.sync_queue = 0; + init_waitqueue_head(&sq.write_queue); + init_waitqueue_head(&sq.open_queue); + init_waitqueue_head(&sq.sync_queue); sq.busy = 0; /* whatever you like as startup mode for /dev/dsp, diff -u --recursive --new-file v2.3.0/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c --- v2.3.0/linux/drivers/sound/es1370.c Mon Apr 12 16:18:27 1999 +++ linux/drivers/sound/es1370.c Wed May 12 13:27:37 1999 @@ -310,7 +310,7 @@ spinlock_t lock; struct semaphore open_sem; mode_t open_mode; - struct wait_queue *open_wait; + wait_queue_head_t open_wait; struct dmabuf { void *rawbuf; @@ -321,7 +321,7 @@ unsigned total_bytes; int count; unsigned error; /* over/underrun */ - struct wait_queue *wait; + wait_queue_head_t wait; /* redundant, but makes calculations easier */ unsigned fragsize; unsigned dmasize; @@ -339,8 +339,8 @@ struct { unsigned ird, iwr, icnt; unsigned ord, owr, ocnt; - struct wait_queue *iwait; - struct wait_queue *owait; + wait_queue_head_t iwait; + wait_queue_head_t owait; unsigned char ibuf[MIDIINBUF]; unsigned char obuf[MIDIOUTBUF]; } midi; @@ -1007,7 +1007,7 @@ static int drain_dac1(struct es1370_state *s, int nonblock) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long flags; int count, tmo; @@ -1042,7 +1042,7 @@ static int drain_dac2(struct es1370_state *s, int nonblock) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long flags; int count, tmo; @@ -2191,7 +2191,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file) { struct es1370_state *s = (struct es1370_state *)file->private_data; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long flags; unsigned count, tmo; @@ -2308,13 +2308,13 @@ continue; } memset(s, 0, sizeof(struct es1370_state)); - init_waitqueue(&s->dma_adc.wait); - init_waitqueue(&s->dma_dac1.wait); - init_waitqueue(&s->dma_dac2.wait); - init_waitqueue(&s->open_wait); - init_waitqueue(&s->midi.iwait); - init_waitqueue(&s->midi.owait); - s->open_sem = MUTEX; + init_waitqueue_head(&s->dma_adc.wait); + init_waitqueue_head(&s->dma_dac1.wait); + init_waitqueue_head(&s->dma_dac2.wait); + init_waitqueue_head(&s->open_wait); + init_waitqueue_head(&s->midi.iwait); + init_waitqueue_head(&s->midi.owait); + init_MUTEX(&s->open_sem); s->magic = ES1370_MAGIC; s->io = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; s->irq = pcidev->irq; diff -u --recursive --new-file v2.3.0/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c --- v2.3.0/linux/drivers/sound/es1371.c Mon Apr 12 16:18:27 1999 +++ linux/drivers/sound/es1371.c Wed May 12 13:27:37 1999 @@ -361,7 +361,7 @@ spinlock_t lock; struct semaphore open_sem; mode_t open_mode; - struct wait_queue *open_wait; + wait_queue_head_t open_wait; struct dmabuf { void *rawbuf; @@ -372,7 +372,7 @@ unsigned total_bytes; int count; unsigned error; /* over/underrun */ - struct wait_queue *wait; + wait_queue_head_t wait; /* redundant, but makes calculations easier */ unsigned fragsize; unsigned dmasize; @@ -390,8 +390,8 @@ struct { unsigned ird, iwr, icnt; unsigned ord, owr, ocnt; - struct wait_queue *iwait; - struct wait_queue *owait; + wait_queue_head_t iwait; + wait_queue_head_t owait; unsigned char ibuf[MIDIINBUF]; unsigned char obuf[MIDIOUTBUF]; } midi; @@ -1454,7 +1454,7 @@ static int drain_dac1(struct es1371_state *s, int nonblock) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long flags; int count, tmo; @@ -1489,7 +1489,7 @@ static int drain_dac2(struct es1371_state *s, int nonblock) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long flags; int count, tmo; @@ -2625,7 +2625,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file) { struct es1371_state *s = (struct es1371_state *)file->private_data; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long flags; unsigned count, tmo; @@ -2745,13 +2745,13 @@ continue; } memset(s, 0, sizeof(struct es1371_state)); - init_waitqueue(&s->dma_adc.wait); - init_waitqueue(&s->dma_dac1.wait); - init_waitqueue(&s->dma_dac2.wait); - init_waitqueue(&s->open_wait); - init_waitqueue(&s->midi.iwait); - init_waitqueue(&s->midi.owait); - s->open_sem = MUTEX; + init_waitqueue_head(&s->dma_adc.wait); + init_waitqueue_head(&s->dma_dac1.wait); + init_waitqueue_head(&s->dma_dac2.wait); + init_waitqueue_head(&s->open_wait); + init_waitqueue_head(&s->midi.iwait); + init_waitqueue_head(&s->midi.owait); + init_MUTEX(&s->open_sem); s->magic = ES1371_MAGIC; s->io = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; s->irq = pcidev->irq; diff -u --recursive --new-file v2.3.0/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c --- v2.3.0/linux/drivers/sound/gus_wave.c Thu Jan 28 11:25:04 1999 +++ linux/drivers/sound/gus_wave.c Tue May 11 23:40:50 1999 @@ -118,7 +118,7 @@ static int gus_audio_bsize; static char bounce_buf[8 * 1024]; /* Must match value set to max_fragment */ -static struct wait_queue *dram_sleeper = NULL; +static DECLARE_WAIT_QUEUE_HEAD(dram_sleeper); /* * Variables and buffers for PCM output @@ -1663,7 +1663,7 @@ gus_no_dma = 0; } - init_waitqueue(&dram_sleeper); + init_waitqueue_head(&dram_sleeper); gus_busy = 1; active_device = GUS_DEV_WAVE; diff -u --recursive --new-file v2.3.0/linux/drivers/sound/midibuf.c linux/drivers/sound/midibuf.c --- v2.3.0/linux/drivers/sound/midibuf.c Wed Dec 16 12:52:01 1998 +++ linux/drivers/sound/midibuf.c Tue May 11 23:40:50 1999 @@ -29,8 +29,8 @@ #define MAX_QUEUE_SIZE 4000 -static struct wait_queue *midi_sleeper[MAX_MIDI_DEV] = {NULL}; -static struct wait_queue *input_sleeper[MAX_MIDI_DEV] = {NULL}; +static wait_queue_head_t midi_sleeper[MAX_MIDI_DEV]; +static wait_queue_head_t input_sleeper[MAX_MIDI_DEV]; struct midi_buf { @@ -202,8 +202,8 @@ midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0; open_devs++; - init_waitqueue(&midi_sleeper[dev]); - init_waitqueue(&input_sleeper[dev]); + init_waitqueue_head(&midi_sleeper[dev]); + init_waitqueue_head(&input_sleeper[dev]); if (open_devs < 2) /* This was first open */ { diff -u --recursive --new-file v2.3.0/linux/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c --- v2.3.0/linux/drivers/sound/msnd_pinnacle.c Mon Jan 4 11:37:30 1999 +++ linux/drivers/sound/msnd_pinnacle.c Tue May 11 23:40:50 1999 @@ -1913,9 +1913,9 @@ if (digital) set_bit(F_HAVEDIGITAL, &dev.flags); #endif - init_waitqueue(&dev.writeblock); - init_waitqueue(&dev.readblock); - init_waitqueue(&dev.writeflush); + init_waitqueue_head(&dev.writeblock); + init_waitqueue_head(&dev.readblock); + init_waitqueue_head(&dev.writeflush); msnd_fifo_init(&dev.DAPF); msnd_fifo_init(&dev.DARF); #ifndef LINUX20 diff -u --recursive --new-file v2.3.0/linux/drivers/sound/sequencer.c linux/drivers/sound/sequencer.c --- v2.3.0/linux/drivers/sound/sequencer.c Sun Mar 7 15:22:06 1999 +++ linux/drivers/sound/sequencer.c Tue May 11 23:40:50 1999 @@ -53,8 +53,8 @@ #define SEQ_2 2 static int seq_mode = SEQ_1; -static struct wait_queue *seq_sleeper = NULL; -static struct wait_queue *midi_sleeper = NULL; +static DECLARE_WAIT_QUEUE_HEAD(seq_sleeper); +static DECLARE_WAIT_QUEUE_HEAD(midi_sleeper); static int midi_opened[MAX_MIDI_DEV] = { 0 @@ -1117,8 +1117,8 @@ if (seq_mode == SEQ_2) tmr->open(tmr_no, seq_mode); - init_waitqueue(&seq_sleeper); - init_waitqueue(&midi_sleeper); + init_waitqueue_head(&seq_sleeper); + init_waitqueue_head(&midi_sleeper); output_threshold = SEQ_MAX_QUEUE / 2; return 0; diff -u --recursive --new-file v2.3.0/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c --- v2.3.0/linux/drivers/sound/sonicvibes.c Mon Apr 12 16:18:27 1999 +++ linux/drivers/sound/sonicvibes.c Wed May 12 13:27:37 1999 @@ -286,7 +286,7 @@ spinlock_t lock; struct semaphore open_sem; mode_t open_mode; - struct wait_queue *open_wait; + wait_queue_head_t open_wait; struct dmabuf { void *rawbuf; @@ -297,7 +297,7 @@ unsigned total_bytes; int count; unsigned error; /* over/underrun */ - struct wait_queue *wait; + wait_queue_head_t wait; /* redundant, but makes calculations easier */ unsigned fragsize; unsigned dmasize; @@ -315,8 +315,8 @@ struct { unsigned ird, iwr, icnt; unsigned ord, owr, ocnt; - struct wait_queue *iwait; - struct wait_queue *owait; + wait_queue_head_t iwait; + wait_queue_head_t owait; struct timer_list timer; unsigned char ibuf[MIDIINBUF]; unsigned char obuf[MIDIOUTBUF]; @@ -1241,7 +1241,7 @@ static int drain_dac(struct sv_state *s, int nonblock) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long flags; int count, tmo; @@ -2043,7 +2043,7 @@ static int sv_midi_release(struct inode *inode, struct file *file) { struct sv_state *s = (struct sv_state *)file->private_data; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long flags; unsigned count, tmo; @@ -2344,12 +2344,12 @@ continue; } memset(s, 0, sizeof(struct sv_state)); - init_waitqueue(&s->dma_adc.wait); - init_waitqueue(&s->dma_dac.wait); - init_waitqueue(&s->open_wait); - init_waitqueue(&s->midi.iwait); - init_waitqueue(&s->midi.owait); - s->open_sem = MUTEX; + init_waitqueue_head(&s->dma_adc.wait); + init_waitqueue_head(&s->dma_dac.wait); + init_waitqueue_head(&s->open_wait); + init_waitqueue_head(&s->midi.iwait); + init_waitqueue_head(&s->midi.owait); + init_MUTEX(&s->open_sem); s->magic = SV_MAGIC; s->iosb = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; s->ioenh = pcidev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK; diff -u --recursive --new-file v2.3.0/linux/drivers/sound/wavfront.c linux/drivers/sound/wavfront.c --- v2.3.0/linux/drivers/sound/wavfront.c Thu Jan 14 22:59:47 1999 +++ linux/drivers/sound/wavfront.c Tue May 11 23:40:50 1999 @@ -290,7 +290,7 @@ int samples_used; /* how many */ char interrupts_on; /* h/w MPU interrupts enabled ? */ char rom_samples_rdonly; /* can we write on ROM samples */ - struct wait_queue *interrupt_sleeper; + wait_queue_head_t interrupt_sleeper; } dev; static int detect_wffx(void); @@ -2535,7 +2535,7 @@ } - init_waitqueue (&dev.interrupt_sleeper); + init_waitqueue_head (&dev.interrupt_sleeper); if (wavefront_hw_reset ()) { printk (KERN_WARNING LOGNAME "hardware reset failed\n"); diff -u --recursive --new-file v2.3.0/linux/drivers/usb/Config.in linux/drivers/usb/Config.in --- v2.3.0/linux/drivers/usb/Config.in Mon May 10 10:18:34 1999 +++ linux/drivers/usb/Config.in Thu May 13 14:14:18 1999 @@ -11,20 +11,18 @@ mainmenu_option next_comment comment 'USB drivers - not for the faint of heart' -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Support for USB (EXPERIMENTAL!)' CONFIG_USB - if [ ! "$CONFIG_USB" = "n" ]; then - bool 'UHCI (intel PIIX4 and others) support?' CONFIG_USB_UHCI - bool 'OHCI (compaq and some others) support?' CONFIG_USB_OHCI - bool 'OHCI-HCD (other OHCI opt. Virt. Root Hub) support?' CONFIG_USB_OHCI_HCD - if [ "$CONFIG_USB_OHCI_HCD" = "y" ]; then - bool 'OHCI-HCD Virtual Root Hub' CONFIG_USB_OHCI_VROOTHUB - fi - - bool 'USB mouse support' CONFIG_USB_MOUSE - bool 'USB keyboard support' CONFIG_USB_KBD - bool 'USB audio parsing support' CONFIG_USB_AUDIO +tristate 'Support for USB (EXPERIMENTAL!)' CONFIG_USB +if [ ! "$CONFIG_USB" = "n" ]; then + bool 'UHCI (intel PIIX4 and others) support?' CONFIG_USB_UHCI + bool 'OHCI (compaq and some others) support?' CONFIG_USB_OHCI + bool 'OHCI-HCD (other OHCI opt. Virt. Root Hub) support?' CONFIG_USB_OHCI_HCD + if [ "$CONFIG_USB_OHCI_HCD" = "y" ]; then + bool 'OHCI-HCD Virtual Root Hub' CONFIG_USB_OHCI_VROOTHUB fi + + bool 'USB mouse support' CONFIG_USB_MOUSE + bool 'USB keyboard support' CONFIG_USB_KBD + bool 'USB audio parsing support' CONFIG_USB_AUDIO fi endmenu diff -u --recursive --new-file v2.3.0/linux/drivers/usb/Makefile linux/drivers/usb/Makefile --- v2.3.0/linux/drivers/usb/Makefile Mon May 10 10:18:34 1999 +++ linux/drivers/usb/Makefile Thu May 13 14:32:06 1999 @@ -32,6 +32,10 @@ USBX_OBJS += audio.o endif +ifeq ($(CONFIG_USB_CPIA),y) + USBX_OBJS += cpia.o +endif + ifeq ($(CONFIG_USB), y) L_OBJS += $(USBX_OBJS) endif diff -u --recursive --new-file v2.3.0/linux/drivers/usb/cpia.c linux/drivers/usb/cpia.c --- v2.3.0/linux/drivers/usb/cpia.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/usb/cpia.c Thu May 13 14:19:00 1999 @@ -0,0 +1,1255 @@ +/* + * USB CPiA Video Camera driver + * + * Supports CPiA based Video Camera's. Many manufacturers use this chipset. + * There's a good chance, if you have a USB video camera, it's a CPiA based + * one + * + * (C) Copyright 1999 Johannes Erdfelt + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "usb.h" +#include "uhci.h" +#include "cpia.h" + +#define MAX_FRAME_SIZE (384 * 288 * 3) + +/*******************************/ +/* Memory management functions */ +/*******************************/ + +/* convert virtual user memory address to physical address */ +/* (virt_to_phys only works for kmalloced kernel memory) */ + +static inline unsigned long uvirt_to_phys(unsigned long adr) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; + + pgd = pgd_offset(current->mm, adr); + if (pgd_none(*pgd)) + return 0; + pmd = pmd_offset(pgd, adr); + if (pmd_none(*pmd)) + return 0; + ptep = pte_offset(pmd, adr/*&(~PGDIR_MASK)*/); + pte = *ptep; + if(pte_present(pte)) + return + virt_to_phys((void *)(pte_page(pte)|(adr&(PAGE_SIZE-1)))); + return 0; +} + +static inline unsigned long uvirt_to_bus(unsigned long adr) +{ + return virt_to_bus(phys_to_virt(uvirt_to_phys(adr))); +} + +/* convert virtual kernel memory address to physical address */ +/* (virt_to_phys only works for kmalloced kernel memory) */ + +static inline unsigned long kvirt_to_phys(unsigned long adr) +{ + return uvirt_to_phys(VMALLOC_VMADDR(adr)); +} + +static inline unsigned long kvirt_to_bus(unsigned long adr) +{ + return uvirt_to_bus(VMALLOC_VMADDR(adr)); +} + + +static void * rvmalloc(unsigned long size) +{ + void * mem; + unsigned long adr, page; + + size += (PAGE_SIZE - 1); + size &= ~(PAGE_SIZE - 1); + + mem=vmalloc(size); + if (mem) + { + memset(mem, 0, size); /* Clear the ram out, no junk to the user */ + adr=(unsigned long) mem; + while (size > 0) + { + page = kvirt_to_phys(adr); + mem_map_reserve(MAP_NR(phys_to_virt(page))); + adr+=PAGE_SIZE; + if (size > PAGE_SIZE) + size-=PAGE_SIZE; + else + size=0; + } + } + return mem; +} + +static void rvfree(void * mem, unsigned long size) +{ + unsigned long adr, page; + + size += (PAGE_SIZE - 1); + size &= ~(PAGE_SIZE - 1); + + if (mem) + { + adr=(unsigned long) mem; + while (size > 0) + { + page = kvirt_to_phys(adr); + mem_map_unreserve(MAP_NR(phys_to_virt(page))); + adr+=PAGE_SIZE; + if (size > PAGE_SIZE) + size-=PAGE_SIZE; + else + size=0; + } + vfree(mem); + } +} + +int usb_cpia_get_version(struct usb_device *dev, void *buf) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE) | 0x80; + dr.request = USB_REQ_CPIA_GET_VERSION; + dr.value = 0; + dr.index = 0; + dr.length = 4; + + return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, 4); +} + +int usb_cpia_get_pnp_id(struct usb_device *dev, void *buf) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE) | 0x80; + dr.request = USB_REQ_CPIA_GET_PNP_ID; + dr.value = 0; + dr.index = 0; + dr.length = 6; + + return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, 6); +} + +int usb_cpia_get_camera_status(struct usb_device *dev, void *buf) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE) | 0x80; + dr.request = USB_REQ_CPIA_GET_CAMERA_STATUS; + dr.value = 0; + dr.index = 0; + dr.length = 8; + + return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, 8); +} + +int usb_cpia_goto_hi_power(struct usb_device *dev) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_GOTO_HI_POWER; + dr.value = 0; + dr.index = 0; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +int usb_cpia_get_vp_version(struct usb_device *dev, void *buf) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_GET_VP_VERSION; + dr.value = 0; + dr.index = 0; + dr.length = 4; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, buf, 4); +} + +int usb_cpia_set_sensor_fps(struct usb_device *dev, int sensorbaserate, int sensorclkdivisor) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_SET_SENSOR_FPS; + dr.value = (sensorclkdivisor << 8) + sensorbaserate; + dr.index = 0; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +int usb_cpia_grab_frame(struct usb_device *dev, int streamstartline) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_GRAB_FRAME; + dr.value = streamstartline << 8; + dr.index = 0; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +int usb_cpia_upload_frame(struct usb_device *dev, int forceupload) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_UPLOAD_FRAME; + dr.value = forceupload; + dr.index = 0; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +int usb_cpia_set_grab_mode(struct usb_device *dev, int continuousgrab) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_SET_GRAB_MODE; + dr.value = continuousgrab; + dr.index = 0; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +int usb_cpia_set_format(struct usb_device *dev, int size, int subsample, int order) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_SET_FORMAT; + dr.value = (subsample << 8) + size; + dr.index = order; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +int usb_cpia_set_compression(struct usb_device *dev, int compmode, int decimation) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_SET_COMPRESSION; + dr.value = (decimation << 8) + compmode; + dr.index = 0; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +int usb_cpia_initstreamcap(struct usb_device *dev, int skipframes, int streamstartline) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_INIT_STREAM_CAP; + dr.value = (streamstartline << 8) + skipframes; + dr.index = 0; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +int usb_cpia_finistreamcap(struct usb_device *dev) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_FINI_STREAM_CAP; + dr.value = 0; + dr.index = 0; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +int usb_cpia_startstreamcap(struct usb_device *dev) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_START_STREAM_CAP; + dr.value = 0; + dr.index = 0; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +int usb_cpia_endstreamcap(struct usb_device *dev) +{ + devrequest dr; + + dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); + dr.request = USB_REQ_CPIA_END_STREAM_CAP; + dr.value = 0; + dr.index = 0; + dr.length = 0; + + return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +} + +#define scratch_left(x) (cpia->scratchlen - (int)((char *)x - (char *)cpia->scratch)) + +static void cpia_parse_data(struct usb_cpia *cpia) +{ + unsigned char *data = cpia->scratch; + int done; + + done = 0; + while (!done && scratch_left(data)) { + switch (cpia->state) { + case STATE_SCANNING: + { + unsigned char *begin = data; + + /* We need atleast 2 bytes for the magic value */ + if (scratch_left(data) < 2) { + done = 1; + break; + } + + printk("header: %X\n", (*data << 8) + *(data + 1)); + if ((*data == 0x19) && (*(data + 1) == 0x68)) { + cpia->state = STATE_HEADER; + printk("moving to header\n"); + break; + } + + if (scratch_left(data) < 4) { + done = 1; + break; + } + + printk("Scanning for end of frame\n"); + while (scratch_left(data) >= 4) { + if ((*data == 0xFF) && + (*(data + 1) == 0xFF) && + (*(data + 2) == 0xFF) && + (*(data + 3) == 0xFF)) { + data += 4; + break; + } + data++; + } +printk("scan: scanned %d bytes\n", data-begin); + break; + } + case STATE_HEADER: + /* We need atleast 64 bytes for the header */ + if (scratch_left(data) < 64) { + done = 1; + break; + } + +printk("header: framerate %d\n", data[41]); + + data += 64; + + cpia->state = STATE_LINES; + + break; + case STATE_LINES: + { + unsigned char *begin = data; + int found = 0; + + while (scratch_left(data)) { + if (*data == 0xFD) { + data++; + found = 1; + break; + } else if ((*data == 0xFF) && + (scratch_left(data) >= 3) && + (*(data + 1) == 0xFF) && + (*(data + 2) == 0xFF) && + (*(data + 3) == 0xFF)) { + data+=4; + cpia->curline = 144; + found = 1; + break; + } + + data++; + } +#if 0 +printk("line %d: scanned %d bytes\n", cpia->curline, data-begin); +#endif +if (data-begin == 355 && cpia->frame[cpia->curframe].width != 64) { + int i; + char *f = cpia->frame[cpia->curframe].data, *b = begin; + +#if 0 +printk("copying\n"); +#endif + + b+=2; + f+=(cpia->frame[cpia->curframe].width*3)*cpia->curline; + for (i = 0; i < 176; i++) + f[(i * 3) + 0] = + f[(i * 3) + 1] = + f[(i * 3) + 2] = + b[(i * 2)]; +} + if (found) { + cpia->curline++; + if (cpia->curline >= 144) { + wake_up(&cpia->wq); + cpia->state = STATE_SCANNING; + cpia->curline = 0; + cpia->curframe = -1; + done = 1; + } + } else { + data = begin; + done = 1; + } + + break; + } + } + } + + { + int l; + + l = scratch_left(data); + memmove(cpia->scratch, data, l); + cpia->scratchlen = l; + } +} + +static int cpia_isoc_irq(int status, void *__buffer, void *dev_id) +{ + struct usb_cpia *cpia = dev_id; + struct usb_device *dev = cpia->dev; + struct cpia_sbuf *sbuf; + int i; + char *p; + + if (!cpia->streaming) { + printk("oops, not streaming, but interrupt\n"); + return 0; + } + + if (cpia->curframe < 0) { + if (cpia->frame[0].state == FRAME_READY) { + cpia->curframe = 0; + cpia->frame[0].state = FRAME_GRABBING; +printk("capturing to frame 0\n"); + } else if (cpia->frame[1].state == FRAME_READY) { + cpia->curframe = 1; + cpia->frame[1].state = FRAME_GRABBING; +printk("capturing to frame 1\n"); + } else +printk("no frame available\n"); + } + + sbuf = &cpia->sbuf[cpia->receivesbuf]; + + uhci_unsched_isochronous(dev, sbuf->isodesc); + + /* Do something to it now */ + sbuf->len = uhci_compress_isochronous(dev, sbuf->isodesc); + + if (sbuf->len) + printk("%d bytes received\n", sbuf->len); + + if (sbuf->len && cpia->curframe >= 0) { + if (sbuf->len > (SCRATCH_BUF_SIZE - cpia->scratchlen)) { + printk("overflow!\n"); + return 0; + } + memcpy(cpia->scratch + cpia->scratchlen, sbuf->data, sbuf->len); + cpia->scratchlen += sbuf->len; + + cpia_parse_data(cpia); + } + + /* Reschedule this block of Isochronous desc */ + uhci_sched_isochronous(dev, sbuf->isodesc, cpia->sbuf[(cpia->receivesbuf + 2) % 3].isodesc); + + /* Move to the next one */ + cpia->receivesbuf = (cpia->receivesbuf + 1) % 3; + + return 1; +} + +int cpia_init_isoc(struct usb_cpia *cpia) +{ + struct usb_device *dev = cpia->dev; + + cpia->receivesbuf = 0; + +#if 0 + cpia->parsesbuf = 0; + cpia->parsepos = 0; +#endif + cpia->scratchlen = 0; + cpia->curline = 0; + cpia->state = STATE_SCANNING; + + /* Allocate all of the memory necessary */ + cpia->sbuf[0].isodesc = uhci_alloc_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[0].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia); + cpia->sbuf[1].isodesc = uhci_alloc_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[1].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia); + cpia->sbuf[2].isodesc = uhci_alloc_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[2].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia); + + printk("isodesc[0] @ %p\n", cpia->sbuf[0].isodesc); + printk("isodesc[1] @ %p\n", cpia->sbuf[1].isodesc); + printk("isodesc[2] @ %p\n", cpia->sbuf[2].isodesc); + + /* Schedule the queues */ + uhci_sched_isochronous(dev, cpia->sbuf[0].isodesc, NULL); + uhci_sched_isochronous(dev, cpia->sbuf[1].isodesc, cpia->sbuf[0].isodesc); + uhci_sched_isochronous(dev, cpia->sbuf[2].isodesc, cpia->sbuf[1].isodesc); + + if (usb_set_interface(cpia->dev, 1, 3)) { + printk("cpia_set_interface error\n"); + return -EINVAL; + } + + usb_cpia_startstreamcap(cpia->dev); + + cpia->streaming = 1; + + return 0; +} + +void cpia_stop_isoc(struct usb_cpia *cpia) +{ + struct usb_device *dev = cpia->dev; + + if (!cpia->streaming) + return; + + cpia->streaming = 0; + + /* Stop the streaming */ + usb_cpia_endstreamcap(cpia->dev); + + /* Set packet size to 0 */ + if (usb_set_interface(cpia->dev, 1, 0)) { + printk("cpia_set_interface error\n"); + return -EINVAL; + } + + /* Unschedule all of the iso td's */ + uhci_unsched_isochronous(dev, cpia->sbuf[2].isodesc); + uhci_unsched_isochronous(dev, cpia->sbuf[1].isodesc); + uhci_unsched_isochronous(dev, cpia->sbuf[0].isodesc); + + /* Delete them all */ + uhci_delete_isochronous(dev, cpia->sbuf[2].isodesc); + uhci_delete_isochronous(dev, cpia->sbuf[1].isodesc); + uhci_delete_isochronous(dev, cpia->sbuf[0].isodesc); +} + +/* Video 4 Linux API */ +static int cpia_open(struct video_device *dev, int flags) +{ + struct usb_cpia *cpia = (struct usb_cpia *)dev; + +printk("cpia_open\n"); + + cpia->fbuf = rvmalloc(2 * MAX_FRAME_SIZE); + if (!cpia->fbuf) + return -ENOMEM; + + cpia->frame[0].state = FRAME_DONE; + cpia->frame[1].state = FRAME_DONE; + + cpia->frame[0].data = cpia->fbuf; + cpia->frame[1].data = cpia->fbuf + MAX_FRAME_SIZE; + printk("frame [0] @ %p\n", cpia->frame[0].data); + printk("frame [1] @ %p\n", cpia->frame[1].data); + + cpia->sbuf[0].data = kmalloc(STREAM_BUF_SIZE, GFP_KERNEL); + if (!cpia->sbuf[0].data) + return -ENOMEM; + + cpia->sbuf[1].data = kmalloc(STREAM_BUF_SIZE, GFP_KERNEL); + if (!cpia->sbuf[1].data) + return -ENOMEM; + + cpia->sbuf[2].data = kmalloc(STREAM_BUF_SIZE, GFP_KERNEL); + if (!cpia->sbuf[2].data) + return -ENOMEM; + + printk("sbuf[0] @ %p\n", cpia->sbuf[0].data); + printk("sbuf[1] @ %p\n", cpia->sbuf[1].data); + printk("sbuf[2] @ %p\n", cpia->sbuf[2].data); + + cpia->curframe = -1; + cpia->receivesbuf = 0; + + usb_cpia_initstreamcap(cpia->dev, 0, 60); + + cpia_init_isoc(cpia); + + return 0; +} + +static void cpia_close(struct video_device *dev) +{ + struct usb_cpia *cpia = (struct usb_cpia *)dev; + +printk("cpia_close\n"); + + cpia_stop_isoc(cpia); + + usb_cpia_finistreamcap(cpia->dev); + + rvfree(cpia->fbuf, 2 * MAX_FRAME_SIZE); + + kfree(cpia->sbuf[2].data); + kfree(cpia->sbuf[1].data); + kfree(cpia->sbuf[0].data); +} + +static int cpia_init_done(struct video_device *dev) +{ + return 0; +} + +static long cpia_write(struct video_device *dev, const char *buf, unsigned long count, int noblock) +{ + return -EINVAL; +} + +#if 0 + if (usb_set_interface(dev, 1, 3)) { + printk("cpia_set_interface error\n"); + return -EINVAL; + } + + if (usb_cpia_grab_frame(dev, 0)) { + printk("cpia_grab_frame error\n"); + return -EINVAL; + } + + if (usb_cpia_upload_frame(dev, 0)) { + printk("cpia_upload_frame error\n"); + return -EINVAL; + } + + buf = cpia->ibuf; + uhci_receive_isochronous(dev, usb_rcvisocpipe(dev,1), buf, 176*144*4); + + { + printk("header magic: %X\n", (buf[0] << 8) + buf[1]); + + while ((buf[0] != 0x19) || (buf[1] != 0x68)) { + int i; + + printk("resync'ing\n"); + for (i=0;i<(176*144*4)-4;i++, buf++) + if ( + (buf[0] == 0xFF) && + (buf[1] == 0xFF) && + (buf[2] == 0xFF) && + (buf[3] == 0xFF)) { + buf+=4; + i+=4; + break; + } + + memmove(cpia->ibuf, buf, (176*144*4) - i); + uhci_receive_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->ibuf + (176*144*4) - i, i); + buf = cpia->ibuf; + +#if 0 + printk("header magic: %X\n", (buf[0] << 8) + buf[1]); +#endif + } + + printk("size: %d, sample: %d, order: %d\n", buf[16], buf[17], buf[18]); + printk("comp: %d, decimation: %d\n", buf[28], buf[29]); + printk("roi: top left: %d, %d bottom right: %d, %d\n", + buf[26] * 4, buf[24] * 8, + buf[27] * 4, buf[25] * 8); + + printk("vm->frame: %d\n", vm->frame); + + { + int i, i1; + char *b = buf + 64, *fbuf = &cpia->fbuffer[MAX_FRAME_SIZE * (vm->frame & 1)]; + for (i=0;i<144;i++) { +#if 0 + printk("line len: %d\n", (b[1] << 8) + b[0]); +#endif + b += 2; + for (i1=0;i1<176;i1++) { + fbuf[(i * vm->width * 3) + (i1 * 3)] = + fbuf[(i * vm->width * 3) + (i1 * 3) + 1] = + fbuf[(i * vm->width * 3) + (i1 * 3) + 2] = + b[i1 * 2]; +#if 0 + *((short *)&fbuf[(i * vm->width * 2) + (i1 * 2)]) = + ((b[i1 * 2] >> 3) << 11) + ((b[i1 * 2] >> 2) << 6) + (b[i1 * 2] >> 3); +#endif + } + b += (176 * 2) + 1; + } + } + + } + + if (usb_set_interface(dev, 1, 0)) { + printk("cpia_set_interface error\n"); + return -EINVAL; + } +#endif + +static int cpia_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +{ + struct usb_cpia *cpia = (struct usb_cpia *)dev; + + switch (cmd) { + case VIDIOCGCAP: + { + struct video_capability b; + + strcpy(b.name, "CPiA USB Camera"); + b.type = VID_TYPE_CAPTURE /* | VID_TYPE_SUBCAPTURE */; + b.channels = 1; + b.audios = 0; + b.maxwidth = 176 /* 352 */; + b.maxheight = 144 /* 240 */; + b.minwidth = 176 /* (Something small?) */; + b.minheight = 144 /* " " */; + + if (copy_to_user(arg, &b, sizeof(b))) + return -EFAULT; + return 0; + } + case VIDIOCGCHAN: + { + struct video_channel v; + + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if (v.channel != 0) + return -EINVAL; + + v.flags = 0; + v.tuners = 0; + v.type = VIDEO_TYPE_CAMERA; + strcpy(v.name, "Camera"); + + if (copy_to_user(arg, &v, sizeof(v))) + return -EFAULT; + return 0; + } + case VIDIOCSCHAN: + { + int v; + + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + + if (v != 0) + return -EINVAL; + + return 0; + } + case VIDIOCGTUNER: + { + struct video_tuner v; + + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + + if (v.tuner) + return -EINVAL; + + strcpy(v.name, "Format"); + + v.rangelow = 0; + v.rangehigh = 0; + v.flags = 0; + v.mode = VIDEO_MODE_AUTO; + + if (copy_to_user(arg, &v, sizeof(v))) + return -EFAULT; + + return 0; + } + case VIDIOCSTUNER: + { + struct video_tuner v; + + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + + if (v.tuner) + return -EINVAL; + + if (v.mode != VIDEO_MODE_AUTO) + return -EINVAL; + + return 0; + } + case VIDIOCGPICT: + { + struct video_picture p; + + p.colour = 0x8000; /* Damn British people :) */ + p.hue = 0x8000; + p.brightness = 180 << 8; /* XXX */ + p.contrast = 192 << 8; /* XXX */ + p.whiteness = 105 << 8; /* XXX */ +#if 0 + p.depth = 24; +#endif + p.depth = 16; + p.palette = VIDEO_PALETTE_YUYV; + + if (copy_to_user(arg, &p, sizeof(p))) + return -EFAULT; + + return 0; + } + case VIDIOCSPICT: + { + struct video_picture p; + + if (copy_from_user(&p, arg, sizeof(p))) + return -EFAULT; + +printk("Attempting to set palette %d, depth %d\n", p.palette, p.depth); + +#if 0 + if (p.palette != VIDEO_PALETTE_YUYV) + return -EINVAL; + if (p.depth != 16) + return -EINVAL; +#endif + + return 0; + } + case VIDIOCSWIN: + { + struct video_window vw; + +printk("VIDIOCSWIN\n"); + if (copy_from_user(&vw, arg, sizeof(vw))) + return -EFAULT; + if (vw.flags) + return -EINVAL; + if (vw.clipcount) + return -EINVAL; + if (vw.height != 176) + return -EINVAL; + if (vw.width != 144) + return -EINVAL; + + return 0; + } + case VIDIOCGWIN: + { + struct video_window vw; + +printk("VIDIOCGWIN\n"); + vw.x = 0; + vw.y = 0; + vw.width = 176; + vw.height = 144; + vw.chromakey = 0; + vw.flags = 0; + + if (copy_to_user(arg, &vw, sizeof(vw))) + return -EFAULT; + + return 0; + } + case VIDIOCGMBUF: + { + struct video_mbuf vm; + + memset(&vm, 0, sizeof(vm)); + vm.size = MAX_FRAME_SIZE * 2; + vm.frames = 2; + vm.offsets[0] = 0; + vm.offsets[1] = MAX_FRAME_SIZE; + + if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm))) + return -EFAULT; + + return 0; + } + case VIDIOCMCAPTURE: + { + struct video_mmap vm; + + if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) + return -EFAULT; + +printk("MCAPTURE\n"); +printk("frame: %d, size: %dx%d, format: %d\n", vm.frame, vm.width, vm.height, vm.format); + + if (vm.format != VIDEO_PALETTE_RGB24) + return -EINVAL; + + if ((vm.frame != 0) && (vm.frame != 1)) + return -EINVAL; + + cpia->frame[vm.frame].width = vm.width; + cpia->frame[vm.frame].height = vm.height; + + /* Mark it as free */ + cpia->frame[vm.frame].state = FRAME_READY; + + return 0; + } + case VIDIOCSYNC: + { + int frame; + + if (copy_from_user((void *)&frame, arg, sizeof(int))) + return -EFAULT; + + printk("syncing to frame %d\n", frame); + switch (cpia->frame[frame].state) { + case FRAME_UNUSED: + return -EINVAL; + case FRAME_READY: + case FRAME_GRABBING: + interruptible_sleep_on(&cpia->wq); + case FRAME_DONE: + cpia->frame[frame].state = FRAME_UNUSED; + break; + } + printk("synced to frame %d\n", frame); + return 0; + } + case VIDIOCCAPTURE: + return -EINVAL; + case VIDIOCGFBUF: + return -EINVAL; + case VIDIOCSFBUF: + return -EINVAL; + case VIDIOCKEY: + return 0; + case VIDIOCGFREQ: + return -EINVAL; + case VIDIOCSFREQ: + return -EINVAL; + case VIDIOCGAUDIO: + return -EINVAL; + case VIDIOCSAUDIO: + return -EINVAL; + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static long cpia_read(struct video_device *dev, char *buf, unsigned long count, int noblock) +{ + struct usb_cpia *cpia = (struct usb_cpia *)dev; + int len; + + printk("cpia_read: %d bytes\n", count); +#if 0 + len = cpia_capture(cpia, buf, count); + + return len; +#endif + return 0; +} + +static int cpia_mmap(struct video_device *dev, const char *adr, unsigned long size) +{ + struct usb_cpia *cpia = (struct usb_cpia *)dev; + unsigned long start = (unsigned long)adr; + unsigned long page, pos; + + printk("mmap: %d (%X) bytes\n", size, size); + if (size > (((2 * MAX_FRAME_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) + return -EINVAL; + +#if 0 + if (!cpia->fbuffer) { + if ((cpia->fbuffer = rvmalloc(2 * MAX_FRAME_SIZE)) == NULL) + return -EINVAL; + } +#endif + + pos = (unsigned long)cpia->fbuf; + while (size > 0) + { + page = kvirt_to_phys(pos); + if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) + return -EAGAIN; + start+=PAGE_SIZE; + pos+=PAGE_SIZE; + if (size > PAGE_SIZE) + size-=PAGE_SIZE; + else + size=0; + } + + return 0; +} + +static struct video_device cpia_template = { + "CPiA USB Camera", + VID_TYPE_CAPTURE, + VID_HARDWARE_CPIA, + cpia_open, + cpia_close, + cpia_read, + cpia_write, + NULL, + cpia_ioctl, + cpia_mmap, + cpia_init_done, + NULL, + 0, + 0 +}; + +static void usb_cpia_configure(struct usb_cpia *cpia) +{ + struct usb_device *dev = cpia->dev; + unsigned char version[4]; + unsigned char pnpid[6]; + unsigned char camerastat[8]; + unsigned char *buf; + + usb_set_configuration(dev, dev->config[0].bConfigurationValue); + + if (usb_cpia_get_version(dev, version)) { + printk("cpia_get_version error\n"); + return; + } + + printk("cpia: Firmware v%d.%d, VC Hardware v%d.%d\n", + version[0], version[1], version[2], version[3]); + + if (usb_cpia_get_pnp_id(dev, pnpid)) { + printk("cpia_get_pnp_id error\n"); + return; + } + + printk("cpia: PnP Id: Vendor: %X, Product: %X, Revision: %X\n", + (pnpid[1] << 8) + pnpid[0], (pnpid[3] << 8) + pnpid[2], + (pnpid[5] << 8) + pnpid[4]); + + memcpy(&cpia->vdev, &cpia_template, sizeof(cpia_template)); + + init_waitqueue_head(&cpia->wq); + + if (video_register_device(&cpia->vdev, VFL_TYPE_GRABBER) == -1) { + printk("video_register_device failed\n"); + return; + } + + if (usb_cpia_goto_hi_power(dev)) { + printk("cpia_goto_hi_power error\n"); + return; + } + + if (usb_cpia_get_vp_version(dev, version)) { + printk("cpia_get_vp_version error\n"); + return; + } + + printk("cpia: VP v%d rev %d\n", version[0], version[1]); + printk("cpia: Camera Head ID %04X\n", (version[3] << 8) + version[2]); + + /* Turn off continuous grab */ + if (usb_cpia_set_grab_mode(dev, 1)) { + printk("cpia_set_grab_mode error\n"); + return; + } + + /* Set up the sensor to be 30fps */ + if (usb_cpia_set_sensor_fps(dev, 1, 0)) { + printk("cpia_set_sensor_fps error\n"); + return; + } + + /* Set video into QCIF mode, and order into YUYV mode */ + if (usb_cpia_set_format(dev, CPIA_QCIF, 1, CPIA_YUYV)) { + printk("cpia_set_format error\n"); + return; + } + + /* Turn off compression */ + if (usb_cpia_set_compression(dev, 0, 0)) { + printk("cpia_set_compression error\n"); + return; + } + +#if 0 + if (usb_cpia_grab_frame(dev, 0)) { + printk("cpia_grab_frame error\n"); + return; + } + + if (usb_cpia_upload_frame(dev, 1)) { + printk("cpia_upload_frame error\n"); + return; + } + + buf = (void *)__get_free_page(GFP_KERNEL); + + { + int i; + for (i=0;i<448;i++) + buf[i]=0; + } + uhci_receive_isochronous(dev, usb_rcvisocpipe(dev,1), buf, 448); + + { + int i; + for (i=0;i<448;i++) { + printk("%02X ", buf[i]); + if ((i % 16) == 15) + printk("\n"); + } + printk("\n"); + } + + free_page((unsigned long)buf); +#endif +} + +static int cpia_probe(struct usb_device *dev) +{ + struct usb_interface_descriptor *interface; + struct usb_endpoint_descriptor *endpoint; + struct usb_cpia *cpia; + + /* We don't handle multi-config cameras */ + if (dev->descriptor.bNumConfigurations != 1) + return -1; + +#if 0 + /* We don't handle multi-interface hubs */ + if (dev->config[0].bNumInterfaces != 1) + return -1; +#endif + + interface = &dev->config[0].interface[0]; + + /* Is it a CPiA? */ +/* +Apr 24 17:49:04 bjorn kernel: Vendor: 0545 +Apr 24 17:49:04 bjorn kernel: Product: 8080 +*/ +/* + if (dev->descriptor.idVendor != 0x0545) + return -1; + if (dev->descriptor.idProduct != 0x8080) + return -1; + if (interface->bInterfaceClass != 0xFF) + return -1; + if (interface->bInterfaceSubClass != 0xFF) + return -1; +*/ + if (dev->descriptor.idVendor != 0x0553) + return -1; + if (dev->descriptor.idProduct != 0x0002) + return -1; + if (interface->bInterfaceClass != 0xFF) + return -1; + if (interface->bInterfaceSubClass != 0x00) + return -1; + +#if 0 + /* Multiple endpoints? What kind of mutant ninja-hub is this? */ + if (interface->bNumEndpoints != 1) + return -1; + + endpoint = &interface->endpoint[0]; + + /* Output endpoint? Curiousier and curiousier.. */ + if (!(endpoint->bEndpointAddress & 0x80)) + return -1; + + /* If it's not an interrupt endpoint, we'd better punt! */ + if ((endpoint->bmAttributes & 3) != 3) + return -1; +#endif + + /* We found a CPiA */ + printk("USB CPiA camera found\n"); + + if ((cpia = kmalloc(sizeof(*cpia), GFP_KERNEL)) == NULL) { + printk("couldn't kmalloc cpia struct\n"); + return -1; + } + + memset(cpia, 0, sizeof(*cpia)); + + dev->private = cpia; + cpia->dev = dev; + + usb_cpia_configure(cpia); + +#if 0 + usb_request_irq(dev, usb_rcvctrlpipe(dev, endpoint->bEndpointAddress), pport_irq, endpoint->bInterval, pport); +#endif + + return 0; +} + +static void cpia_disconnect(struct usb_device *dev) +{ + struct usb_cpia *cpia = dev->private; + + video_unregister_device(&cpia->vdev); + + /* Free the memory */ + kfree(cpia); +} + +static struct usb_driver cpia_driver = { + "cpia", + cpia_probe, + cpia_disconnect, + { NULL, NULL } +}; + +/* + * This should be a separate module. + */ +int cpia_init(void) +{ + usb_register(&cpia_driver); + + return 0; +} + diff -u --recursive --new-file v2.3.0/linux/drivers/usb/cpia.h linux/drivers/usb/cpia.h --- v2.3.0/linux/drivers/usb/cpia.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/usb/cpia.h Thu May 13 14:18:09 1999 @@ -0,0 +1,139 @@ +#ifndef __LINUX_CPIA_H +#define __LINUX_CPIA_H + +#include + +#define USB_REQ_CPIA_GET_VERSION 0x01 +#define USB_REQ_CPIA_GET_PNP_ID 0x02 +#define USB_REQ_CPIA_GET_CAMERA_STATUS 0x03 +#define USB_REQ_CPIA_GOTO_HI_POWER 0x04 +#define USB_REQ_CPIA_GOTO_LO_POWER 0x05 +/* No 0x06 */ +#define USB_REQ_CPIA_GOTO_SUSPEND 0x07 +#define USB_REQ_CPIA_GOTO_PASS_THROUGH 0x08 +/* No 0x09 */ +#define USB_REQ_CPIA_MODIFY_CAMERA_STATUS 0x0A + +#define USB_REQ_CPIA_READ_VC_REGS 0x21 +#define USB_REQ_CPIA_WRITE_BC_REG 0x22 +#define USB_REQ_CPIA_READ_MC_PORTS 0x23 +#define USB_REQ_CPIA_WRITE_MC_PORT 0x24 +#define USB_REQ_CPIA_SET_BAUD_RATE 0x25 +#define USB_REQ_CPIA_SET_ECP_TIMING 0x26 +#define USB_REQ_CPIA_READ_IDATA 0x27 +#define USB_REQ_CPIA_WRITE_IDATA 0x28 +#define USB_REQ_CPIA_GENERIC_CALL 0x29 +#define USB_REQ_CPIA_I2CSTART 0x2A +#define USB_REQ_CPIA_I2CSTOP 0x2B +#define USB_REQ_CPIA_I2CWRITE 0x2C +#define USB_REQ_CPIA_I2CREAD 0x2D + +#define USB_REQ_CPIA_GET_VP_VERSION 0xA1 +#define USB_REQ_CPIA_SET_COLOUR_PARAMS 0xA3 +#define USB_REQ_CPIA_SET_EXPOSURE 0xA4 +/* No 0xA5 */ +#define USB_REQ_CPIA_SET_COLOUR_BALANCE 0xA6 +#define USB_REQ_CPIA_SET_SENSOR_FPS 0xA7 +#define USB_REQ_CPIA_SET_VP_DEFAULTS 0xA8 +#define USB_REQ_CPIA_SET_APCOR 0xA9 +#define USB_REQ_CPIA_SET_FLICKER_CTRL 0xAA +#define USB_REQ_CPIA_SET_VL_OFFSET 0xAB + +#define USB_REQ_CPIA_GET_COLOUR_PARAMETERS 0xB0 +#define USB_REQ_CPIA_GET_COLOUR_BALANCE 0xB1 +#define USB_REQ_CPIA_GET_EXPOSURE 0xB2 +#define USB_REQ_CPIA_SET_SENSOR_MATRIX 0xB3 + +#define USB_REQ_CPIA_COLOUR_BARS 0xBD +#define USB_REQ_CPIA_READ_VP_REGS 0xBE +#define USB_REQ_CPIA_WRITE_VP_REGS 0xBF + +#define USB_REQ_CPIA_GRAB_FRAME 0xC1 +#define USB_REQ_CPIA_UPLOAD_FRAME 0xC2 +#define USB_REQ_CPIA_SET_GRAB_MODE 0xC3 +#define USB_REQ_CPIA_INIT_STREAM_CAP 0xC4 +#define USB_REQ_CPIA_FINI_STREAM_CAP 0xC5 +#define USB_REQ_CPIA_START_STREAM_CAP 0xC6 +#define USB_REQ_CPIA_END_STREAM_CAP 0xC7 +#define USB_REQ_CPIA_SET_FORMAT 0xC8 +#define USB_REQ_CPIA_SET_ROI 0xC9 +#define USB_REQ_CPIA_SET_COMPRESSION 0xCA +#define USB_REQ_CPIA_SET_COMPRESSION_TARGET 0xCB +#define USB_REQ_CPIA_SET_YUV_THRESH 0xCC +#define USB_REQ_CPIA_SET_COMPRESSION_PARAMS 0xCD +#define USB_REQ_CPIA_DISCARD_FRAME 0xCE + +#define USB_REQ_CPIA_OUTPUT_RS232 0xE1 +#define USB_REQ_CPIA_ABORT_PROCESS 0xE4 +#define USB_REQ_CPIA_SET_DRAM_PAGE 0xE5 +#define USB_REQ_CPIA_START_DRAM_UPLOAD 0xE6 +#define USB_REQ_CPIA_START_DUMMY_STREAM 0xE8 +#define USB_REQ_CPIA_ABORT_STREAM 0xE9 +#define USB_REQ_CPIA_DOWNLOAD_DRAM 0xEA +/* #define USB_REQ_CPIA_NULL_CMD 0x?? */ + +#define CPIA_QCIF 0 +#define CPIA_CIF 1 + +#define CPIA_YUYV 0 +#define CPIA_UYVY 1 + +#define STREAM_BUF_SIZE (PAGE_SIZE * 4) + +#define SCRATCH_BUF_SIZE (STREAM_BUF_SIZE * 2) + +enum { + STATE_SCANNING, /* Scanning for start */ + STATE_HEADER, /* Parsing header */ + STATE_LINES, /* Parsing lines */ +}; + +struct usb_device; + +struct cpia_sbuf { + char *data; + int len; + void *isodesc; +}; + +enum { + FRAME_READY, /* Ready to grab into */ + FRAME_GRABBING, /* In the process of being grabbed into */ + FRAME_DONE, /* Finished grabbing, but not been synced yet */ + FRAME_UNUSED, /* Unused (no MCAPTURE) */ +}; + +struct cpia_frame { + char *data; + int width; + int height; + int state; +}; + +struct usb_cpia { + struct video_device vdev; + + /* Device structure */ + struct usb_device *dev; + + int streaming; + + char *fbuf; /* Videodev buffer area */ + + int curframe; + struct cpia_frame frame[2]; /* Double buffering */ + + int receivesbuf; /* Current receiving sbuf */ + struct cpia_sbuf sbuf[3]; /* Triple buffering */ + + int state; /* Current scanning state */ + int curline; + + char scratch[SCRATCH_BUF_SIZE]; + int scratchlen; + + wait_queue_head_t wq; +}; + +#endif + diff -u --recursive --new-file v2.3.0/linux/drivers/usb/hub.c linux/drivers/usb/hub.c --- v2.3.0/linux/drivers/usb/hub.c Fri Apr 30 08:20:01 1999 +++ linux/drivers/usb/hub.c Tue May 11 23:09:42 1999 @@ -24,7 +24,7 @@ extern struct usb_operations uhci_device_operations; /* Wakes up khubd */ -static struct wait_queue *usb_hub_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(usb_hub_wait); static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED; /* List of hubs needing servicing */ diff -u --recursive --new-file v2.3.0/linux/drivers/usb/mouse.c linux/drivers/usb/mouse.c --- v2.3.0/linux/drivers/usb/mouse.c Fri Apr 30 08:20:49 1999 +++ linux/drivers/usb/mouse.c Thu May 13 14:17:20 1999 @@ -48,7 +48,7 @@ int present; /* this mouse is plugged in */ int active; /* someone is has this mouse's device open */ int ready; /* the mouse has changed state since the last read */ - struct wait_queue *wait; /* for polling */ + wait_queue_head_t wait; /* for polling */ struct fasync_struct *fasync; /* later, add a list here to support multiple mice */ /* but we will also need a list of file pointers to identify it */ @@ -277,7 +277,7 @@ misc_register(&usb_mouse); mouse->present = mouse->active = 0; - mouse->wait = NULL; + init_waitqueue_head(&mouse->wait); mouse->fasync = NULL; usb_register(&mouse_driver); diff -u --recursive --new-file v2.3.0/linux/drivers/usb/ohci-hcd.c linux/drivers/usb/ohci-hcd.c --- v2.3.0/linux/drivers/usb/ohci-hcd.c Tue May 11 09:55:45 1999 +++ linux/drivers/usb/ohci-hcd.c Tue May 11 23:18:20 1999 @@ -63,8 +63,8 @@ -static struct wait_queue *control_wakeup; -static struct wait_queue *root_hub = NULL; +static DECLARE_WAIT_QUEUE_HEAD(control_wakeup); +static DECLARE_WAIT_QUEUE_HEAD(root_hub); static __u8 cc_to_status[16] = { /* mapping of the OHCI CC to the UHCI status codes; first guess */ /* Activ, Stalled, Data Buffer Err, Babble Detected : NAK recvd, CRC/Timeout, Bitstuff, reservd */ @@ -145,7 +145,7 @@ static int sohci_control_msg(struct usb_device *usb_dev, unsigned int pipe, void *cmd, void *data, int len) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); struct ohci * ohci = usb_dev->bus->hcpriv; int status; union ep_addr_ ep_addr; diff -u --recursive --new-file v2.3.0/linux/drivers/usb/ohci.c linux/drivers/usb/ohci.c --- v2.3.0/linux/drivers/usb/ohci.c Tue May 11 10:27:04 1999 +++ linux/drivers/usb/ohci.c Tue May 11 23:17:31 1999 @@ -57,7 +57,7 @@ static int apm_resume = 0; #endif -static struct wait_queue *ohci_configure = NULL; +static DECLARE_WAIT_QUEUE_HEAD(ohci_configure); #ifdef OHCI_TIMER static struct timer_list ohci_timer; /* timer for root hub polling */ @@ -476,7 +476,7 @@ /* * Control thread operations: */ -static struct wait_queue *control_wakeup; +static DECLARE_WAIT_QUEUE_HEAD(control_wakeup); /* * This is the handler that gets called when a control transaction @@ -515,7 +515,7 @@ */ struct ohci_ed *control_ed = &dev->ohci->root_hub->ed[ED_CONTROL]; struct ohci_td *setup_td, *data_td, *status_td; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); #if 0 printk(KERN_DEBUG "entering ohci_control_msg %p (ohci_dev: %p) pipe 0x%x, cmd %p, data %p, len %d\n", usb, dev, pipe, cmd, data, len); diff -u --recursive --new-file v2.3.0/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c --- v2.3.0/linux/drivers/usb/uhci.c Fri Apr 30 08:20:53 1999 +++ linux/drivers/usb/uhci.c Thu May 13 14:34:01 1999 @@ -47,7 +47,7 @@ #define compile_assert(x) do { switch (0) { case 1: case !(x): } } while (0) -static struct wait_queue *uhci_configure = NULL; +static DECLARE_WAIT_QUEUE_HEAD(uhci_configure); /* * Return the result of a TD.. @@ -61,15 +61,17 @@ /* Some debugging code */ if (status) { int i = 10; - struct uhci_td *tmp = dev->control_td; + struct uhci_td *tmp = td->first; printk("uhci_td_result() failed with status %d\n", status); show_status(dev->uhci); do { show_td(tmp); - tmp++; + if ((tmp->link & 1) || (tmp->link & 2)) + break; + tmp = bus_to_virt(tmp->link & ~0xF); if (!--i) break; - } while (tmp <= td); + } while (1); } return status; } @@ -279,7 +281,7 @@ unsigned int destination, status; /* Destination: pipe destination with INPUT */ - destination = (pipe & 0x0007ff00) | 0x69; + destination = (pipe & 0x0007ff00) | 0x69; /* Status: slow/fast, Interrupt, Active, Short Packet Detect Infinite Errors */ status = (pipe & (1 << 26)) | (1 << 24) | (1 << 23) | (1 << 29) | (0 << 27); @@ -292,6 +294,7 @@ td->status = status; /* In */ td->info = destination | (7 << 21); /* 8 bytes of data */ td->buffer = virt_to_bus(dev->data); + td->first = td; td->qh = interrupt_qh; interrupt_qh->skel = &dev->uhci->root_hub->skel_int8_qh; @@ -305,6 +308,202 @@ } /* + * Isochronous thread operations + */ + +int uhci_compress_isochronous(struct usb_device *usb_dev, void *_isodesc) +{ + struct uhci_iso_td *isodesc = (struct uhci_iso_td *)_isodesc; + char *data = isodesc->data; + int i, totlen = 0; + + for (i = 0; i < isodesc->num; i++) { + char *cdata = bus_to_virt(isodesc->td[i].buffer & ~0xF); + int n = (isodesc->td[i].status + 1) & 0x7FF; + + if ((cdata != data) && (n)) + memmove(data, cdata, n); + +#if 0 +if (n && n != 960) + printk("underrun: %d %d\n", i, n); +#endif +if ((isodesc->td[i].status >> 16) & 0xFF) + printk("error: %d %X\n", i, (isodesc->td[i].status >> 16)); + + data += n; + totlen += n; + } + + return totlen; +} + +int uhci_unsched_isochronous(struct usb_device *usb_dev, void *_isodesc) +{ + struct uhci_device *dev = usb_to_uhci(usb_dev); + struct uhci *uhci = dev->uhci; + struct uhci_iso_td *isodesc = (struct uhci_iso_td *)_isodesc; + int i; + + if ((isodesc->frame < 0) || (isodesc->frame > 1023)) + return 1; + + /* Remove from previous frames */ + for (i = 0; i < isodesc->num; i++) { + /* Turn off Active and IOC bits */ + isodesc->td[i].status &= ~(3 << 23); + uhci->fl->frame[(isodesc->frame + i) % 1024] = isodesc->td[i].link; + } + + isodesc->frame = -1; + + return 0; +} + +/* td points to the one td we allocated for isochronous transfers */ +int uhci_sched_isochronous(struct usb_device *usb_dev, void *_isodesc, void *_pisodesc) +{ + struct uhci_device *dev = usb_to_uhci(usb_dev); + struct uhci *uhci = dev->uhci; + struct uhci_iso_td *isodesc = (struct uhci_iso_td *)_isodesc; + struct uhci_iso_td *pisodesc = (struct uhci_iso_td *)_pisodesc; + int frame, i; + + if (isodesc->frame != -1) { + printk("isoc queue not removed\n"); + uhci_unsched_isochronous(usb_dev, isodesc); + } + + /* Insert TD into list */ + if (!pisodesc) { + frame = inw(uhci->io_addr + USBFRNUM) % 1024; + /* HACK: Start 2 frames from now */ + frame = (frame + 2) % 1024; + } else + frame = (pisodesc->endframe + 1) % 1024; + +#if 0 +printk("scheduling first at frame %d\n", frame); +#endif + + for (i = 0; i < isodesc->num; i++) { + /* Active */ + isodesc->td[i].status |= (1 << 23); + isodesc->td[i].backptr = &uhci->fl->frame[(frame + i) % 1024]; + isodesc->td[i].link = uhci->fl->frame[(frame + i) % 1024]; + uhci->fl->frame[(frame + i) % 1024] = virt_to_bus(&isodesc->td[i]); + } + +#if 0 +printk("last at frame %d\n", (frame + i - 1) % 1024); +#endif + + /* Interrupt */ + isodesc->td[i - 1].status |= (1 << 24); + + isodesc->frame = frame; + isodesc->endframe = (frame + isodesc->num - 1) % 1024; + +#if 0 + return uhci_td_result(dev, td[num - 1]); +#endif + return 0; +} + +/* + * Initialize isochronous queue + */ +void *uhci_alloc_isochronous(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int maxsze, usb_device_irq completed, void *dev_id) +{ + struct uhci_device *dev = usb_to_uhci(usb_dev); + unsigned long destination, status; + struct uhci_td *td; + int ret, i; + struct uhci_iso_td *isodesc; + + isodesc = kmalloc(sizeof(*isodesc), GFP_KERNEL); + if (!isodesc) { + printk("Couldn't allocate isodesc!\n"); + return NULL; + } + memset(isodesc, 0, sizeof(*isodesc)); + + /* Carefully work around the non contiguous pages */ + isodesc->num = (len / PAGE_SIZE) * (PAGE_SIZE / maxsze); + isodesc->td = kmalloc(sizeof(struct uhci_td) * isodesc->num, GFP_KERNEL); + isodesc->frame = isodesc->endframe = -1; + isodesc->data = data; + isodesc->maxsze = maxsze; + + if (!isodesc->td) { + printk("Couldn't allocate td's\n"); + kfree(isodesc); + return NULL; + } + + isodesc->frame = isodesc->endframe = -1; + + /* + * Build the DATA TD's + */ + i = 0; + do { + /* Build the TD for control status */ + td = &isodesc->td[i]; + + /* The "pipe" thing contains the destination in bits 8--18 */ + destination = (pipe & 0x0007ff00); + + if (usb_pipeout(pipe)) + destination |= 0xE1; /* OUT */ + else + destination |= 0x69; /* IN */ + + /* Status: slow/fast, Active, Isochronous */ + status = (pipe & (1 << 26)) | (1 << 23) | (1 << 25); + + /* + * Build the TD for the control request + */ + td->status = status; + td->info = destination | ((maxsze - 1) << 21); + td->buffer = virt_to_bus(data); + td->first = td; + td->backptr = NULL; + + i++; + + data += maxsze; + + if (((int)data % PAGE_SIZE) + maxsze >= PAGE_SIZE) + data = (char *)(((int)data + maxsze) & ~(PAGE_SIZE - 1)); + + len -= maxsze; + } while (i < isodesc->num); + + /* IOC on the last TD */ + td->status |= (1 << 24); + uhci_add_irq_list(dev->uhci, td, completed, dev_id); + + return isodesc; +} + +void uhci_delete_isochronous(struct usb_device *usb_dev, void *_isodesc) +{ + struct uhci_iso_td *isodesc = (struct uhci_iso_td *)_isodesc; + + /* If it's still scheduled, unschedule them */ + if (isodesc->frame) + uhci_unsched_isochronous(usb_dev, isodesc); + + /* Remove it from the IRQ list */ + uhci_remove_irq_list(&isodesc->td[isodesc->num - 1]); + + kfree(isodesc->td); + kfree(isodesc); +} + +/* * Control thread operations: we just mark the last TD * in a control thread as an interrupt TD, and wake up * the front-end on completion. @@ -312,7 +511,7 @@ * We need to remove the TD from the lists (both interrupt * list and TD lists) by hand if something bad happens! */ -static struct wait_queue *control_wakeup; +static DECLARE_WAIT_QUEUE_HEAD(control_wakeup); static int uhci_control_completed(int status, void *buffer, void *dev_id) { @@ -323,7 +522,7 @@ /* td points to the last td in the list, which interrupts on completion */ static int uhci_run_control(struct uhci_device *dev, struct uhci_td *first, struct uhci_td *last) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); struct uhci_qh *ctrl_qh = uhci_qh_allocate(dev); struct uhci_td *curtd; @@ -420,6 +619,7 @@ td->status = status; /* Try forever */ td->info = destination | (7 << 21); /* 8 bytes of data */ td->buffer = virt_to_bus(cmd); + td->first = td; /* * If direction is "send", change the frame from SETUP (0x2D) @@ -450,6 +650,7 @@ td->status = status; /* Status */ td->info = destination | ((pktsze-1) << 21); /* pktsze bytes of data */ td->buffer = virt_to_bus(data); + td->first = first; td->backptr = &prevtd->link; prevtd = td; @@ -470,6 +671,7 @@ td->status = status | (1 << 24); /* IOC */ td->info = destination | (0x7ff << 21); /* 0 bytes of data */ td->buffer = 0; + td->first = first; td->backptr = &prevtd->link; /* Start it up.. */ @@ -554,12 +756,16 @@ for (i = 0; i < UHCI_MAXTD; ++i) { struct uhci_td *td = dev->td + i; - /* And remove it from the irq list, if it's active */ - if (td->status & (1 << 23)) - uhci_remove_irq_list(td); - - if (td->inuse) + if (td->inuse) { uhci_remove_td(td); + + /* And remove it from the irq list, if it's active */ + if (td->status & (1 << 23)) + td->status &= ~(1 << 23); +#if 0 + uhci_remove_irq_list(td); +#endif + } } /* Remove the td from any queues */ @@ -710,15 +916,18 @@ __list_del(tmp->prev, next); INIT_LIST_HEAD(tmp); if (td->completed(td->status, bus_to_virt(td->buffer), td->dev_id)) { - struct uhci_qh *interrupt_qh = td->qh; - list_add(&td->irq_list, &uhci->interrupt_list); - td->info ^= 1 << 19; /* toggle between data0 and data1 */ - td->status = (td->status & 0x2f000000) | (1 << 23) | (1 << 24); /* active */ - /* Remove then readd? Is that necessary */ - uhci_remove_td(td); - uhci_insert_td_in_qh(interrupt_qh, td); + if (!(td->status & (1 << 25))) { + struct uhci_qh *interrupt_qh = td->qh; + + td->info ^= 1 << 19; /* toggle between data0 and data1 */ + td->status = (td->status & 0x2f000000) | (1 << 23) | (1 << 24); /* active */ + + /* Remove then readd? Is that necessary */ + uhci_remove_td(td); + uhci_insert_td_in_qh(interrupt_qh, td); + } } /* If completed wants to not reactivate, then it's */ /* responsible for free'ing the TD's and QH's */ @@ -764,6 +973,9 @@ status = inw(io_addr + USBSTS); outw(status, io_addr + USBSTS); + if ((status & ~0x21) != 0) + printk("interrupt: %X\n", status); + /* Walk the list of pending TD's to see which ones completed.. */ uhci_interrupt_notify(uhci); @@ -787,6 +999,7 @@ td->status = (1 << 24); /* interrupt on completion */ td->info = (15 << 21) | 0x7f69; /* (ignored) input packet, 16 bytes, device 127 */ td->buffer = 0; + td->first = td; td->qh = NULL; uhci->fl->frame[0] = virt_to_bus(td); @@ -1047,11 +1260,12 @@ } } -#if 0 + { + int i; if(uhci->root_hub) for(i = 0; i < uhci->root_hub->usb->maxchild; i++) usb_disconnect(uhci->root_hub->usb->children + i); -#endif + } cleanup_drivers(); @@ -1195,6 +1409,9 @@ #ifdef CONFIG_USB_AUDIO usb_audio_init(); #endif +#ifdef CONFIG_USB_CPIA + cpia_init(); +#endif #ifdef CONFIG_APM apm_register_callback(&handle_apm_event); #endif diff -u --recursive --new-file v2.3.0/linux/drivers/usb/uhci.h linux/drivers/usb/uhci.h --- v2.3.0/linux/drivers/usb/uhci.h Wed Apr 28 11:14:03 1999 +++ linux/drivers/usb/uhci.h Thu May 13 14:42:51 1999 @@ -91,8 +91,20 @@ void *dev_id; int inuse; /* Inuse? */ struct uhci_qh *qh; + struct uhci_td *first; } __attribute__((aligned(32))); +struct uhci_iso_td { + int num; + char *data; + int maxsze; + + struct uhci_td *td; + + int frame; + int endframe; +}; + /* * Note the alignment requirements of the entries * @@ -102,7 +114,7 @@ */ struct uhci; -#define UHCI_MAXTD 64 +#define UHCI_MAXTD 64 #define UHCI_MAXQH 16 @@ -124,9 +136,11 @@ * The root hub pre-allocated QH's and TD's have * some special global uses.. */ +#if 0 #define control_td td /* Td's 0-30 */ /* This is only for the root hub's TD list */ #define tick_td td[31] +#endif /* * There are various standard queues. We set up several different @@ -224,6 +238,12 @@ void show_td(struct uhci_td * td); void show_status(struct uhci *uhci); void show_queues(struct uhci *uhci); + +int uhci_compress_isochronous(struct usb_device *usb_dev, void *_isodesc); +int uhci_unsched_isochronous(struct usb_device *usb_dev, void *_isodesc); +int uhci_sched_isochronous(struct usb_device *usb_dev, void *_isodesc, void *_pisodesc); +void *uhci_alloc_isochronous(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int maxsze, usb_device_irq completed, void *dev_id); +void uhci_delete_isochronous(struct usb_device *dev, void *_isodesc); #endif diff -u --recursive --new-file v2.3.0/linux/drivers/usb/usb.c linux/drivers/usb/usb.c --- v2.3.0/linux/drivers/usb/usb.c Fri May 7 15:16:04 1999 +++ linux/drivers/usb/usb.c Thu May 13 11:31:31 1999 @@ -124,7 +124,7 @@ if (n_len < 2 || n_len > len) { - printk("Short descriptor.\n"); + printk("Short descriptor\n"); return -1; } printk( @@ -152,9 +152,12 @@ { int n_len = ptr[0]; + if (len <= 0) + return -1; + if (n_len < 2 || n_len > len) { - printk("Short descriptor.\n"); + printk("Short descriptor. (%d, %d)\n", len, n_len); return -1; } @@ -247,6 +250,11 @@ len -= *ptr; parsed += *ptr; + if (config->MaxPower == 200) { + printk("bNumInterfaces kludge\n"); + config->bNumInterfaces += 3; + } + if (config->bNumInterfaces > USB_MAXINTERFACES) { printk(KERN_WARNING "usb: too many interfaces.\n"); @@ -298,8 +306,10 @@ if (retval < 0) return retval; ptr += retval; - bytes += retval; + bytes -= retval; } + if (bytes) + printk(KERN_WARNING "usb: %d bytes of extra configuration data left\n", bytes); return 0; } @@ -533,6 +543,23 @@ return 0; } + +int usb_set_interface(struct usb_device *dev, int interface, int alternate) +{ + devrequest dr; + + dr.requesttype = 1; + dr.request = USB_REQ_SET_INTERFACE; + dr.value = alternate; + dr.index = interface; + dr.length = 0; + + if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0)) + return -1; + + return 0; +} + int usb_set_configuration(struct usb_device *dev, int configuration) { diff -u --recursive --new-file v2.3.0/linux/drivers/usb/usb.h linux/drivers/usb/usb.h --- v2.3.0/linux/drivers/usb/usb.h Tue May 11 10:04:03 1999 +++ linux/drivers/usb/usb.h Thu May 13 14:42:48 1999 @@ -326,6 +326,8 @@ /* Create control pipes.. */ #define usb_sndctrlpipe(dev,endpoint) ((2 << 30) | __create_pipe(dev,endpoint)) #define usb_rcvctrlpipe(dev,endpoint) ((2 << 30) | __create_pipe(dev,endpoint) | 0x80) +#define usb_sndisocpipe(dev,endpoint) ((0 << 30) | __create_pipe(dev,endpoint)) +#define usb_rcvisocpipe(dev,endpoint) ((0 << 30) | __create_pipe(dev,endpoint) | 0x80) #define usb_snddefctrl(dev) ((2 << 30) | __default_pipe(dev)) #define usb_rcvdefctrl(dev) ((2 << 30) | __default_pipe(dev) | 0x80) diff -u --recursive --new-file v2.3.0/linux/drivers/video/Config.in linux/drivers/video/Config.in --- v2.3.0/linux/drivers/video/Config.in Wed Mar 17 09:17:22 1999 +++ linux/drivers/video/Config.in Tue May 11 16:30:45 1999 @@ -21,6 +21,9 @@ if [ "$CONFIG_ARCH_ACORN" = "y" ]; then bool 'Acorn VIDC support' CONFIG_FB_ACORN fi + if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then + tristate 'Cyber2000 support' CONFIG_FB_CYBER2000 + fi if [ "$CONFIG_APOLLO" = "y" ]; then define_bool CONFIG_FB_APOLLO y fi @@ -177,8 +180,8 @@ "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ - "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ - "$CONFIG_FB_SGIVW" = "y" ]; then + "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ + "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" ]; then define_bool CONFIG_FBCON_CFB8 y else if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ @@ -191,8 +194,8 @@ "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ - "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ - "$CONFIG_FB_SGIVW" = "m" ]; then + "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ + "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" ]; then define_bool CONFIG_FBCON_CFB8 m fi fi @@ -204,7 +207,8 @@ "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ - "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" ]; then + "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ + "$CONFIG_FB_CYBER2000" = "y" ]; then define_bool CONFIG_FBCON_CFB16 y else if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ @@ -214,19 +218,22 @@ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ - "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ - "$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" ]; then + "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ + "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "m" -o \ + "$CONFIG_FB_CYBER2000" = "m" ]; then define_bool CONFIG_FBCON_CFB16 m fi fi if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ - "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" ]; then + "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ + "$CONFIG_FB_CYBER2000" = "y" ]; then define_bool CONFIG_FBCON_CFB24 y else if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ "$CONFIG_FB_CLGEN" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ - "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" ]; then + "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ + "$CONFIG_FB_CYBER2000" = "m" ]; then define_bool CONFIG_FBCON_CFB24 m fi fi @@ -323,7 +330,7 @@ if [ "$CONFIG_AMIGA" = "y" ]; then define_bool CONFIG_FONT_PEARL_8x8 y fi - if [ "$CONFIG_ARM" = "y" ]; then + if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_ACORN" = "y" ]; then define_bool CONFIG_FONT_ACORN_8x8 y fi fi diff -u --recursive --new-file v2.3.0/linux/drivers/video/Makefile linux/drivers/video/Makefile --- v2.3.0/linux/drivers/video/Makefile Wed Mar 17 09:17:22 1999 +++ linux/drivers/video/Makefile Tue May 11 16:30:45 1999 @@ -132,6 +132,14 @@ endif endif +ifeq ($(CONFIG_FB_CYBER2000),y) +L_OBJS += cyber2000fb.o +else + ifeq ($(CONFIG_FB_CYBER2000),m) + M_OBJS += cyber2000fb.o + endif +endif + ifeq ($(CONFIG_FB_SGIVW),y) L_OBJS += sgivwfb.o else diff -u --recursive --new-file v2.3.0/linux/drivers/video/acornfb.c linux/drivers/video/acornfb.c --- v2.3.0/linux/drivers/video/acornfb.c Thu Oct 1 10:02:21 1998 +++ linux/drivers/video/acornfb.c Tue May 11 16:30:45 1999 @@ -1,15 +1,22 @@ /* * linux/drivers/video/acorn.c * - * Copyright (C) 1998 Russell King + * Copyright (C) 1998,1999 Russell King * * Frame buffer code for Acorn platforms + * + * NOTE: Most of the modes with X!=640 will disappear shortly. + * NOTE: Startup setting of HS & VS polarity not supported. + * (do we need to support it if we're coming up in 640x480?) */ + +#include #include #include #include #include #include +#include #include #include #include @@ -21,245 +28,898 @@ #include #include +#include