diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-02 02:36:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-02 02:36:47 +0000 |
commit | 8624512aa908741ba2795200133eae0d7f4557ea (patch) | |
tree | d5d3036fccf2604f4c98dedc11e8adb929d6b52e /drivers/block | |
parent | 7b8f5d6f1d45d9f9de1d26e7d3c32aa5af11b488 (diff) |
Merge with 2.3.48.
Diffstat (limited to 'drivers/block')
52 files changed, 1879 insertions, 1383 deletions
diff --git a/drivers/block/Config.in b/drivers/block/Config.in index 01fc28943..d4ba3f06b 100644 --- a/drivers/block/Config.in +++ b/drivers/block/Config.in @@ -44,6 +44,7 @@ else bool ' RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 bool ' Generic PCI IDE chipset support' CONFIG_BLK_DEV_IDEPCI if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then + bool ' Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO @@ -54,38 +55,43 @@ else define_bool CONFIG_IDEDMA_PCI_EXPERIMENTAL n fi fi + if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then + bool ' ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP + fi bool ' Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD bool ' AEC6210 chipset support' CONFIG_BLK_DEV_AEC6210 - if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_AEC6210" = "y" ]; then - bool ' AEC6210 Tuning support (EXPERIMENTAL)' CONFIG_BLK_DEV_AEC6210_TUNING + if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" -a "$CONFIG_BLK_DEV_AEC6210" = "y" ]; then + bool ' AEC6210 Tuning support (WIP)' CONFIG_AEC6210_TUNING fi if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 - if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then - bool ' AMD Viper support (EXPERIMENTAL)' CONFIG_BLK_DEV_AMD7409 + bool ' AMD Viper support' CONFIG_BLK_DEV_AMD7409 + if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" -a "$CONFIG_BLK_DEV_AMD7409" = "y" ]; then + bool ' AMD Viper ATA-66 Override (WIP)' CONFIG_AMD7409_OVERRIDE fi fi bool ' CMD64X chipset support' CONFIG_BLK_DEV_CMD64X - if [ "$CONFIG_BLK_DEV_CMD64X" = "y" -a "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then - bool ' CMD64X chipset RAID support (EXPERIMENTAL) (WIP)' CONFIG_BLK_DEV_CMD64X_RAID + if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" -a "$CONFIG_BLK_DEV_CMD64X" = "y" ]; then + bool ' CMD64X chipset RAID (WIP)' CONFIG_CMD64X_RAID fi if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then bool ' CY82C693 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CY82C693 fi + bool ' Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X - if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then - bool ' HPT34X DMA support (EXPERIMENTAL)' CONFIG_BLK_DEV_HPT34X_DMA + if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" -a "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then + bool ' HPT34X AUTODMA support (WIP)' CONFIG_HPT34X_AUTODMA fi bool ' HPT366 chipset support' CONFIG_BLK_DEV_HPT366 - if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_HPT366" = "y" ]; then - bool ' HPT366 Fast Interrupt support (EXPERIMENTAL) (WIP)' CONFIG_HPT366_FAST_IRQ_PREDICTION - bool ' HPT366 mode three unsupported (EXPERIMENTAL) (WIP)' CONFIG_HPT366_MODE3 + if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" -a "$CONFIG_BLK_DEV_HPT366" = "y" ]; then + bool ' HPT366 Fast Interrupts (WIP)' CONFIG_HPT366_FIP + bool ' HPT366 mode Three (WIP)' CONFIG_HPT366_MODE3 fi - if [ "$CONFIG_X86" = "y" ]; then + if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then bool ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX if [ "$CONFIG_BLK_DEV_PIIX" = "y" -a "$CONFIG_IDEDMA_PCI_AUTO" = "y" ]; then - bool ' PIIXn Tuning support' CONFIG_BLK_DEV_PIIX_TUNING + bool ' PIIXn Tuning support' CONFIG_PIIX_TUNING fi fi fi @@ -98,21 +104,18 @@ else if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then bool ' PROMISE PDC20246/PDC20262 support' CONFIG_BLK_DEV_PDC202XX if [ "$CONFIG_BLK_DEV_PDC202XX" = "y" ]; then - bool ' Special UDMA Feature' CONFIG_PDC202XX_FORCE_BURST_BIT - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' Special Mode Feature (EXPERIMENTAL)' CONFIG_PDC202XX_FORCE_MASTER_MODE + bool ' Special UDMA Feature' CONFIG_PDC202XX_BURST + if [ "$CONFIG_IDEDMA_PCI_WIP" = "y" ]; then + bool ' Special Mode Feature (WIP)' CONFIG_PDC202XX_MASTER fi fi if [ "$CONFIG_X86" = "y" ]; then bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 fi - bool ' Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 fi if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 - if [ "$CONFIG_X86" = "y" ]; then - bool ' VIA82CXXX chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82CXXX - fi + bool ' VIA82CXXX chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82CXXX fi fi if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then @@ -232,6 +235,7 @@ if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ "$CONFIG_BLK_DEV_AMD7409" = "y" -o \ "$CONFIG_BLK_DEV_CMD640" = "y" -o \ "$CONFIG_BLK_DEV_CMD64X" = "y" -o \ + "$CONFIG_BLK_DEV_CS5530" = "y" -o \ "$CONFIG_BLK_DEV_CY82C693" = "y" -o \ "$CONFIG_BLK_DEV_HPT34X" = "y" -o \ "$CONFIG_BLK_DEV_HPT366" = "y" -o \ @@ -240,7 +244,6 @@ if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ "$CONFIG_BLK_DEV_PDC202XX" = "y" -o \ "$CONFIG_BLK_DEV_PIIX" = "y" -o \ "$CONFIG_BLK_DEV_SIS5513" = "y" -o \ - "$CONFIG_BLK_DEV_CS5530" = "y" -o \ "$CONFIG_BLK_DEV_SL82C105" = "y" ]; then define_bool CONFIG_BLK_DEV_IDE_MODES y else diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 9f313de8f..be158ca1a 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -130,6 +130,10 @@ ifeq ($(CONFIG_BLK_DEV_CMD64X),y) IDE_OBJS += cmd64x.o endif +ifeq ($(CONFIG_BLK_DEV_CS5530),y) +IDE_OBJS += cs5530.o +endif + ifeq ($(CONFIG_BLK_DEV_CY82C693),y) IDE_OBJS += cy82c693.o endif @@ -198,10 +202,6 @@ ifeq ($(CONFIG_BLK_DEV_PDC202XX),y) IDE_OBJS += pdc202xx.o endif -ifeq ($(CONFIG_BLK_DEV_CS5530),y) -IDE_OBJS += cs5530.o -endif - ifeq ($(CONFIG_BLK_DEV_PDC4030),y) IDE_OBJS += pdc4030.o endif diff --git a/drivers/block/README.buddha b/drivers/block/README.buddha deleted file mode 100644 index d3b7bc73f..000000000 --- a/drivers/block/README.buddha +++ /dev/null @@ -1,210 +0,0 @@ - -The Amiga Buddha and Catweasel IDE Driver (part of ide.c) was written by -Geert Uytterhoeven based on the following specifications: - ------------------------------------------------------------------------- - -Register map of the Buddha IDE controller and the -Buddha-part of the Catweasel Zorro-II version - -The Autoconfiguration has been implemented just as Commodore -described in their manuals, no tricks have been used (for -example leaving some address lines out of the equations...). -If you want to configure the board yourself (for example let -a Linux kernel configure the card), look at the Commodore -Docs. Reading the nibbles should give this information: - -Vendor number: 4626 ($1212) -product number: 0 (42 for Catweasel Z-II) -Serial number: 0 -Rom-vector: $1000 - -The card should be a Z-II board, size 64K, not for freemem -list, Rom-Vektor is valid, no second Autoconfig-board on the -same card, no space preferrence, supports "Shutup_forever". - -Setting the base address should be done in two steps, just -as the Amiga Kickstart does: The lower nibble of the 8-Bit -address is written to $4a, then the whole Byte is written to -$48, while it doesn't matter how often you're writing to $4a -as long as $48 is not touched. After $48 has been written, -the whole card disappears from $e8 and is mapped to the new -addrress just written. Make shure $4a is written befor $48, -otherwise your chance is only 1:16 to find the board :-). - -The local memory-map is even active when mapped to $e8: - -$0-$7e Autokonfig-space, see Z-II docs. - -$80-$7fd reserved - -$7fe Speed-select Register: Read & Write - (description see further down) - -$800-$8ff IDE-Select 0 (Port 0, Register set 0) - -$900-$9ff IDE-Select 1 (Port 0, Register set 1) - -$a00-$aff IDE-Select 2 (Port 1, Register set 0) - -$b00-$bff IDE-Select 3 (Port 1, Register set 1) - -$c00-$cff IDE-Select 4 (Port 2, Register set 0, - Catweasel only!) - -$d00-$dff IDE-Select 5 (Port 3, Register set 1, - Catweasel only!) - -$e00-$eff local expansion port, on Catweasel Z-II the - Catweasel registers are also mapped here. - Never touch, use multidisk.device! - -$f00 read only, Byte-access: Bit 7 shows the - level of the IRQ-line of IDE port 0. - -$f01-$f3f mirror of $f00 - -$f40 read only, Byte-access: Bit 7 shows the - level of the IRQ-line of IDE port 1. - -$f41-$f7f mirror of $f40 - -$f80 read only, Byte-access: Bit 7 shows the - level of the IRQ-line of IDE port 2. - (Catweasel only!) - -$f81-$fbf mirror of $f80 - -$fc0 write-only: Writing any value to this - register enables IRQs to be passed from the - IDE ports to the Zorro bus. This mechanism - has been implemented to be compatible with - harddisks that are either defective or have - a buggy firmware and pull the IRQ line up - while starting up. If interrupts would - always be passed to the bus, the computer - might not start up. Once enabled, this flag - can not be disabled again. The level of the - flag can not be determined by software - (what for? Write to me if it's necessary!). - -$fc1-$fff mirror of $fc0 - -$1000-$ffff Buddha-Rom with offset $1000 in the rom - chip. The addresses $0 to $fff of the rom - chip cannot be read. Rom is Byte-wide and - mapped to even addresses. - -The IDE ports issue an INT2. You can read the level of the -IRQ-lines of the IDE-ports by reading from the three (two -for Buddha-only) registers $f00, $f40 and $f80. This way -more than one I/O request can be handled and you can easily -determine what driver has to serve the INT2. Buddha and -Catweasel expansion boards can issue an INT6. A seperate -memory map is available for the I/O module and the sysop's -I/O module. - -The IDE ports are fed by the address lines A2 to A4, just as -the Amiga 1200 and Amiga 4000 IDE ports are. This way -existing drivers can be easily ported to Buddha. A move.l -polls two words out of the same address of IDE port since -every word is mirrored once. movem is not possible, but -it's not necessary either, because you can only speedup -68000 systems with this technique. A 68020 system with -fastmem is faster with move.l. - -If you're using the mirrored registers of the IDE-ports with -A6=1, the Buddha doesn't care about the speed that you have -selected in the speed register (see further down). With -A6=1 (for example $840 for port 0, register set 0), a 780ns -access is being made. These registers should be used for a -command access to the harddisk/CD-Rom, since command -accesses are Byte-wide and have to be made slower according -to the ATA-X3T9 manual. - -Now for the speed-register: The register is byte-wide, and -only the upper three bits are used (Bits 7 to 5). Bit 4 -must always be set to 1 to be compatible with later Buddha -versions (if I'll ever update this one). I presume that -I'll never use the lower four bits, but they have to be set -to 1 by definition. - The values in this table have to be shifted 5 bits to the -left and or'd with $1f (this sets the lower 5 bits). - -All the timings have in common: Select and IOR/IOW rise at -the same time. IOR and IOW have a propagation delay of -about 30ns to the clocks on the Zorro bus, that's why the -values are no multiple of 71. One clock-cycle is 71ns long -(exactly 70,5 at 14,18 Mhz on PAL systems). - -value 0 (Default after reset) - -497ns Select (7 clock cycles) , IOR/IOW after 172ns (2 clock cycles) -(same timing as the Amiga 1200 does on it's IDE port without -accelerator card) - -value 1 - -639ns Select (9 clock cycles), IOR/IOW after 243ns (3 clock cycles) - -value 2 - -781ns Select (11 clock cycles), IOR/IOW after 314ns (4 clock cycles) - -value 3 - -355ns Select (5 clock cycles), IOR/IOW after 101ns (1 clock cycle) - -value 4 - -355ns Select (5 clock cycles), IOR/IOW after 172ns (2 clock cycles) - -value 5 - -355ns Select (5 clock cycles), IOR/IOW after 243ns (3 clock cycles) - -value 6 - -1065ns Select (15 clock cycles), IOR/IOW after 314ns (4 clock cycles) - -value 7 - -355ns Select, (5 clock cycles), IOR/IOW after 101ns (1 clock cycle) - -When accessing IDE registers with A6=1 (for example $84x), -the timing will always be mode 0 8-bit compatible, no matter -what you have selected in the speed register: - -781ns select, IOR/IOW after 4 clock cycles (=314ns) aktive. - -All the timings with a very short select-signal (the 355ns -fast accesses) depend on the accelerator card used in the -system: Sometimes two more clock cycles are inserted by the -bus interface, making the whole access 497ns long. This -doesn't affect the reliability of the controller nor the -performance of the card, since this doesn't happen very -often. - -All the timings are calculated and only confirmed by -measurements that allowed me to count the clock cycles. If -the system is clocked by an oscillator other than 28,37516 -Mhz (for example the NTSC-frequency 28,63636 Mhz), each -clock cycle is shortened to a bit less than 70ns (not worth -mentioning). You could think of a small performance boost -by overclocking the system, but you would either need a -multisync monitor, or a graphics card, and your internal -diskdrive would go crazy, that's why you shouldn't tune your -Amiga this way. - -Giving you the possibility to write software that is -compatible with both the Buddha and the Catweasel Z-II, The -Buddha acts just like a Catweasel Z-II with no device -connected to the third IDE-port. The IRQ-register $f80 -always shows a "no IRQ here" on the Buddha, and accesses to -the third IDE port are going into data's Nirwana on the -Buddha. - - Jens Schönfeld february 19th, 1997 - updated may 27th, 1997 - eMail: sysop@nostlgic.tng.oche.de - diff --git a/drivers/block/README.fd b/drivers/block/README.fd deleted file mode 100644 index 38f0b85a5..000000000 --- a/drivers/block/README.fd +++ /dev/null @@ -1,222 +0,0 @@ -This Readme file describes the floppy driver. - -FAQ list: -========= - - A FAQ list may be found in the fdutils package (see below), and also -at http://fdutils.linux.lu/FAQ.html - - -LILO configuration options (Thinkpad users, read this) -====================================================== - - The floppy driver is configured using the 'floppy=' option in -lilo. This option can be typed at the boot prompt, or entered in the -lilo configuration file. - Example: If your kernel is called linux-2.2.13, type the following line -at the lilo boot prompt (if you have a thinkpad): - linux-2.2.13 floppy=thinkpad -You may also enter the following line in /etc/lilo.conf, in the description -of linux-2.2.13: - append = "floppy=thinkpad" - - Several floppy related options may be given, example: - linux-2.2.13 floppy=daring floppy=two_fdc - append = "floppy=daring floppy=two_fdc" - - If you give options both in the lilo config file and on the boot -prompt, the option strings of both places are concatenated, the boot -prompt options coming last. That's why there are also options to -restore the default behavior. - - If you use the floppy driver as a module, use the following syntax: - insmod floppy <options> - -Example: - insmod floppy daring two_fdc - - Some versions of insmod are buggy in one way or another. If you have -any problems (options not being passed correctly, segfaults during -insmod), first check whether there is a more recent version. - - The floppy related options include: - - floppy=asus_pci - Sets the bit mask to allow only units 0 and 1. (default) - - floppy=daring - Tells the floppy driver that you have a well behaved floppy controller. - This allows more efficient and smoother operation, but may fail on - certain controllers. This may speed up certain operations. - - floppy=0,daring - Tells the floppy driver that your floppy controller should be used - with caution. - - floppy=one_fdc - Tells the floppy driver that you have only one floppy controller. - (default) - - floppy=two_fdc - floppy=<address>,two_fdc - Tells the floppy driver that you have two floppy controllers. - The second floppy controller is assumed to be at <address>. - This option is not needed if the second controller is at address - 0x370, and if you use the 'cmos' option. - - floppy=thinkpad - Tells the floppy driver that you have a Thinkpad. Thinkpads use an - inverted convention for the disk change line. - - floppy=0,thinkpad - Tells the floppy driver that you don't have a Thinkpad. - - floppy=omnibook - floppy=nodma - Tells the floppy driver not to use Dma for data transfers. - This is needed on HP Omnibooks, which don't have a workable - DMA channel for the floppy driver. This option is also useful - if you frequently get "Unable to allocate DMA memory" messages. - Indeed, dma memory needs to be continuous in physical memory, - and is thus harder to find, whereas non-dma buffers may be - allocated in virtual memory. However, I advise against this if - you have an FDC without a FIFO (8272A or 82072). 82072A and - later are OK. You also need at least a 486 to use nodma. - If you use nodma mode, I suggest you also set the FIFO - threshold to 10 or lower, in order to limit the number of data - transfer interrupts. - - If you have a FIFO-able FDC, the floppy driver automatically - falls back on non DMA mode if no DMA-able memory can be found. - If you want to avoid this, explicitely ask for 'yesdma'. - - floppy=yesdma - Tells the floppy driver that a workable DMA channel is available. - (default) - - floppy=nofifo - Disables the FIFO entirely. This is needed if you get "Bus - master arbitration error" messages from your Ethernet card (or - from other devices) while accessing the floppy. - - floppy=fifo - Enables the FIFO. (default) - - floppy=<threshold>,fifo_depth - Sets the FIFO threshold. This is mostly relevant in DMA - mode. If this is higher, the floppy driver tolerates more - interrupt latency, but it triggers more interrupts (i.e. it - imposes more load on the rest of the system). If this is - lower, the interrupt latency should be lower too (faster - processor). The benefit of a lower threshold is less - interrupts. - To tune the fifo threshold, switch on over/underrun messages - using 'floppycontrol --messages'. Then access a floppy - disk. If you get a huge amount of "Over/Underrun - retrying" - messages, then the fifo threshold is too low. Try with a - higher value, until you only get an occasional Over/Underrun. - It is a good idea to compile the floppy driver as a module - when doing this tuning. Indeed, it allows to try different - fifo values without rebooting the machine for each test. Note - that you need to do 'floppycontrol --messages' every time you - re-insert the module. - Usually, tuning the fifo threshold should not be needed, as - the default (0xa) is reasonable. - - floppy=<drive>,<type>,cmos - Sets the CMOS type of <drive> to <type>. This is mandatory if - you have more than two floppy drives (only two can be - described in the physical CMOS), or if your BIOS uses - non-standard CMOS types. The CMOS types are: - 0 - Use the value of the physical CMOS - 1 - 5 1/4 DD - 2 - 5 1/4 HD - 3 - 3 1/2 DD - 4 - 3 1/2 HD - 5 - 3 1/2 ED - 6 - 3 1/2 ED - 16 - unknown or not installed - (Note: there are two valid types for ED drives. This is because 5 was - initially chosen to represent floppy *tapes*, and 6 for ED drives. - AMI ignored this, and used 5 for ED drives. That's why the floppy - driver handles both.) - - floppy=unexpected_interrupts - Print a warning message when an unexpected interrupt is received. - (default) - - floppy=no_unexpected_interrupts - floppy=L40SX - Don't print a message when an unexpected interrupt is received. This - is needed on IBM L40SX laptops in certain video modes. (There seems - to be an interaction between video and floppy. The unexpected - interrupts affect only performance, and can be safely ignored.) - - floppy=broken_dcl - Don't use the disk change line, but assume that the disk was - changed whenever the device node is reopened. Needed on some - boxes where the disk change line is broken or unsupported. - This should be regarded as a stopgap measure, indeed it makes - floppy operation less efficient due to unneeded cache - flushings, and slightly more unreliable. Please verify your - cable, connection and jumper settings if you have any DCL - problems. However, some older drives, and also some laptops - are known not to have a DCL. - - floppy=debug - Print debugging messages. - - floppy=messages - Print informational messages for some operations (disk change - notifications, warnings about over and underruns, and about - autodetection). - - floppy=silent_dcl_clear - Uses a less noisy way to clear the disk change line (which - doesn't involve seeks). Implied by 'daring' option. - - floppy=<nr>,irq - Sets the floppy IRQ to <nr> instead of 6. - - floppy=<nr>,dma - Sets the floppy DMA channel to <nr> instead of 2. - - floppy=slow - Use PS/2 stepping rate: - " PS/2 floppies have much slower step rates than regular floppies. - It's been recommended that take about 1/4 of the default speed - in some more extreme cases." - - - -Supporting utilities and additional documentation: -================================================== - - Additional parameters of the floppy driver can be configured at -runtime. Utilities which do this can be found in the fdutils package. -This package also contains a new version of mtools which allows to -access high capacity disks (up to 1992K on a high density 3 1/2 disk!). -It also contains additional documentation about the floppy driver. - -The latest version can be found at fdutils homepage: - http://fdutils.linux.lu - -The fdutils-5.3 release can be found at: - http://fdutils.linux.lu/fdutils-5.3.src.tar.gz - http://www.tux.org/pub/knaff/fdutils/fdutils-5.3.src.tar.gz - ftp://tsx-11.mit.edu/pub/linux/sources/sbin/fdutils-5.3.src.tar.gz - ftp://metalab.unc.edu/pub/Linux/utils/disk-management/fdutils-5.3.src.tar.gz - -Reporting problems about the floppy driver -========================================== - - If you have a question or a bug report about the floppy driver, mail -me at Alain.Knaff@poboxes.com . If you post to Usenet, preferably use -comp.os.linux.hardware. As the volume in these groups is rather high, -be sure to include the word "floppy" (or "FLOPPY") in the subject -line. If the reported problem happens when mounting floppy disks, be -sure to mention also the type of the filesystem in the subject line. - - Be sure to read the FAQ before mailing/posting any bug reports! - - Alain diff --git a/drivers/block/README.lvm b/drivers/block/README.lvm deleted file mode 100644 index 3d652457f..000000000 --- a/drivers/block/README.lvm +++ /dev/null @@ -1,8 +0,0 @@ - -This is the Logical Volume Manager driver for Linux, - -Tools, library that manage logical volumes can be found -at <http://linux.msede.com/lvm>. - -There you can obtain actual driver versions too. - diff --git a/drivers/block/README.md b/drivers/block/README.md deleted file mode 100644 index 6ad19ac99..000000000 --- a/drivers/block/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Tools that manage md devices can be found at sweet-smoke.ufr-info-p7.ibp.fr -in public/Linux/md035.tar.gz. - - Marc ZYNGIER <zyngier@ufr-info-p7.ibp.fr> diff --git a/drivers/block/aec6210.c b/drivers/block/aec6210.c index f74103d9a..30be6a7cc 100644 --- a/drivers/block/aec6210.c +++ b/drivers/block/aec6210.c @@ -1,7 +1,7 @@ /* - * linux/drivers/block/aec6210.c Version 0.04 Dec. 13, 1999 + * linux/drivers/block/aec6210.c Version 0.05 Feb. 10, 2000 * - * Copyright (C) 1998-99 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) * May be copied or modified under the terms of the GNU General Public License * * pio 0 :: 40: 00 07 00 00 00 00 00 00 02 07 a6 04 00 02 00 02 @@ -56,7 +56,52 @@ #define ACARD_DEBUG_DRIVE_INFO 1 -#ifdef CONFIG_BLK_DEV_AEC6210_TUNING +#define DISPLAY_AEC6210_TIMINGS + +#if defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static int aec6210_get_info(char *, char **, off_t, int); +extern int (*aec6210_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static struct pci_dev *bmide_dev; + +static int aec6210_get_info (char *buffer, char **addr, off_t offset, int count) +{ + char *p = buffer; + + u32 bibma = bmide_dev->resource[4].start; + u8 c0 = 0, c1 = 0; + + p += sprintf(p, "\n AEC6210 Chipset.\n"); + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\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 " ); + + p += sprintf(p, "UDMA\n"); + p += sprintf(p, "DMA\n"); + p += sprintf(p, "PIO\n"); + return p-buffer;/* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS) */ + +byte aec6210_proc = 0; + +#ifdef CONFIG_AEC6210_TUNING struct chipset_bus_clock_list_entry { byte xfer_speed; @@ -269,7 +314,7 @@ int aec6210_dmaproc (ide_dma_action_t func, ide_drive_t *drive) } return ide_dmaproc(func, drive); /* use standard DMA stuff */ } -#endif /* CONFIG_BLK_DEV_AEC6210_TUNING */ +#endif /* CONFIG_AEC6210_TUNING */ unsigned int __init pci_init_aec6210 (struct pci_dev *dev, const char *name) { @@ -277,12 +322,19 @@ unsigned int __init pci_init_aec6210 (struct pci_dev *dev, const char *name) pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); } + +#if defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS) + aec6210_proc = 1; + bmide_dev = dev; + aec6210_display_info = &aec6210_get_info; +#endif /* DISPLAY_AEC6210_TIMINGS && CONFIG_PROC_FS */ + return dev->irq; } void __init ide_init_aec6210 (ide_hwif_t *hwif) { -#ifdef CONFIG_BLK_DEV_AEC6210_TUNING +#ifdef CONFIG_AEC6210_TUNING hwif->tuneproc = &aec6210_tune_drive; if (hwif->dma_base) { @@ -291,7 +343,7 @@ void __init ide_init_aec6210 (ide_hwif_t *hwif) hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; } -#endif /* CONFIG_BLK_DEV_AEC6210_TUNING */ +#endif /* CONFIG_AEC6210_TUNING */ } void __init ide_dmacapable_aec6210 (ide_hwif_t *hwif, unsigned long dmabase) diff --git a/drivers/block/ali14xx.c b/drivers/block/ali14xx.c index e86fe61db..e7fd203b4 100644 --- a/drivers/block/ali14xx.c +++ b/drivers/block/ali14xx.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ali14xx.c Version 0.03 Feb 09, 1996 + * linux/drivers/block/ali14xx.c Version 0.03 Feb 09, 1996 * * Copyright (C) 1996 Linus Torvalds & author (see below) */ @@ -55,12 +55,12 @@ /* port addresses for auto-detection */ #define ALI_NUM_PORTS 4 -static int ports[ALI_NUM_PORTS] = {0x074, 0x0f4, 0x034, 0x0e4}; +static int __init ports[ALI_NUM_PORTS] = {0x074, 0x0f4, 0x034, 0x0e4}; /* register initialization data */ typedef struct { byte reg, data; } RegInitializer; -static RegInitializer initData[] = { +static RegInitializer __init initData[] = { {0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00}, @@ -150,7 +150,7 @@ static void ali14xx_tune_drive (ide_drive_t *drive, byte pio) /* * Auto-detect the IDE controller port. */ -static int findPort (void) +static int __init findPort (void) { int i; byte t; @@ -183,7 +183,7 @@ static int findPort (void) /* * Initialize controller registers with default values. */ -static int initRegisters (void) { +static int __init initRegisters (void) { RegInitializer *p; byte t; unsigned long flags; @@ -200,7 +200,7 @@ static int initRegisters (void) { return t; } -void init_ali14xx (void) +void __init init_ali14xx (void) { /* auto-detect IDE controller port */ if (!findPort()) { diff --git a/drivers/block/alim15x3.c b/drivers/block/alim15x3.c index 4b9b28e3b..bc3d2b9e3 100644 --- a/drivers/block/alim15x3.c +++ b/drivers/block/alim15x3.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/alim15x3.c Version 0.08 Jan. 14, 2000 + * linux/drivers/block/alim15x3.c Version 0.08 Jan. 14, 2000 * * Copyright (C) 1998-2000 Michel Aubry, Maintainer * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer @@ -493,7 +493,6 @@ static int ali15x3_dmaproc (ide_dma_action_t func, ide_drive_t *drive) default: break; } - return ide_dmaproc(func, drive); /* use standard DMA stuff */ } @@ -518,6 +517,13 @@ unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name) if (inb(fixdma_base+2) & 0x80) printk("%s: simplex device: DMA will fail!!\n", name); } + +#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) + ali_proc = 1; + bmide_dev = dev; + ali_display_info = &ali_get_info; +#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */ + return 0; } @@ -666,22 +672,11 @@ void __init ide_init_ali15x3 (ide_hwif_t *hwif) */ hwif->dmaproc = &ali15x3_dmaproc; hwif->autodma = 1; - hwif->drives[0].autotune = 0; - hwif->drives[1].autotune = 0; } else { hwif->autodma = 0; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; } - -#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) - if (!ali_proc) { - ali_proc = 1; - bmide_dev = hwif->pci_dev; - ali_display_info = &ali_get_info; - } -#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */ - return; } diff --git a/drivers/block/amd7409.c b/drivers/block/amd7409.c index 46d5f36af..b12847843 100644 --- a/drivers/block/amd7409.c +++ b/drivers/block/amd7409.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/amd7409.c Version 0.01 Jan. 10, 2000 + * linux/drivers/block/amd7409.c Version 0.03 Feb. 10, 2000 * * Copyright (C) 2000 Andre Hedrick <andre@suse.com> * May be copied or modified under the terms of the GNU General Public License @@ -24,6 +24,51 @@ #include "ide_modes.h" +#define DISPLAY_VIPER_TIMINGS + +#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static int amd7409_get_info(char *, char **, off_t, int); +extern int (*amd7409_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static struct pci_dev *bmide_dev; + +static int amd7409_get_info (char *buffer, char **addr, off_t offset, int count) +{ + char *p = buffer; + u32 bibma = bmide_dev->resource[4].start; + u8 c0 = 0, c1 = 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + + p += sprintf(p, "\n AMD 7409 VIPER Chipset.\n"); + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\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 " ); + p += sprintf(p, "UDMA\n"); + p += sprintf(p, "DMA\n"); + p += sprintf(p, "PIO\n"); + + return p-buffer; /* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) */ + +byte amd7409_proc = 0; + +extern char *ide_xfer_verbose (byte xfer_rate); + /* * Here is where all the hard work goes to program the chipset. * @@ -33,11 +78,13 @@ static int amd7409_tune_chipset (ide_drive_t *drive, byte speed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; int err = 0; - int drive_number = ((HWIF(drive)->channel ? 2 : 0) + - (drive->select.b.unit & 0x01)); + byte unit = (drive->select.b.unit & 0x01); + int drive_number = ((HWIF(drive)->channel ? 2 : 0) + unit); + unsigned long dma_base = hwif->dma_base; byte drive_pci = 0x00; byte drive_pci2 = 0x00; - byte drive_timing = 0x00; + byte ultra_timing = 0x00; + byte dma_pio_timing = 0x00; byte pio_timing = 0x00; switch (drive_number) { @@ -49,54 +96,99 @@ static int amd7409_tune_chipset (ide_drive_t *drive, byte speed) return ((int) ide_dma_off_quietly); } - pci_read_config_byte(dev, drive_pci, &drive_timing); - pci_read_config_byte(dev, drive_pci2, &pio_timing); + pci_read_config_byte(dev, drive_pci, &ultra_timing); + pci_read_config_byte(dev, drive_pci2, &dma_pio_timing); + pci_read_config_byte(dev, 0x4c, &pio_timing); - printk("%s: UDMA 0x%02x PIO 0x%02x ", - drive->name, drive_timing, pio_timing); +#ifdef DEBUG + printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ", + drive->name, ultra_timing, dma_pio_timing, pio_timing); +#endif + + ultra_timing &= ~0xC7; + dma_pio_timing &= ~0xFF; + pio_timing &= ~(0x03 << drive_number); + +#ifdef DEBUG + printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ", + ultra_timing, dma_pio_timing, pio_timing); +#endif switch(speed) { case XFER_UDMA_4: - drive_timing &= ~0xC7; - drive_timing |= 0x45; - pci_write_config_byte(dev, drive_pci, drive_timing); + ultra_timing |= 0x45; + dma_pio_timing |= 0x20; + pio_timing |= (0x03 << drive_number); break; case XFER_UDMA_3: - drive_timing &= ~0xC7; - drive_timing |= 0x44; - pci_write_config_byte(dev, drive_pci, drive_timing); + ultra_timing |= 0x44; + dma_pio_timing |= 0x20; + pio_timing |= (0x03 << drive_number); break; case XFER_UDMA_2: - drive_timing &= ~0xC7; - drive_timing |= 0x40; - pci_write_config_byte(dev, drive_pci, drive_timing); + ultra_timing |= 0x40; + dma_pio_timing |= 0x20; + pio_timing |= (0x03 << drive_number); break; case XFER_UDMA_1: - drive_timing &= ~0xC7; - drive_timing |= 0x41; - pci_write_config_byte(dev, drive_pci, drive_timing); + ultra_timing |= 0x41; + dma_pio_timing |= 0x20; + pio_timing |= (0x03 << drive_number); break; case XFER_UDMA_0: - drive_timing &= ~0xC7; - drive_timing |= 0x42; - pci_write_config_byte(dev, drive_pci, drive_timing); + ultra_timing |= 0x42; + dma_pio_timing |= 0x20; + pio_timing |= (0x03 << drive_number); + break; + case XFER_MW_DMA_2: + dma_pio_timing |= 0x20; + pio_timing |= (0x03 << drive_number); + break; + case XFER_MW_DMA_1: + dma_pio_timing |= 0x21; + pio_timing |= (0x03 << drive_number); + break; + case XFER_MW_DMA_0: + dma_pio_timing |= 0x77; + pio_timing |= (0x03 << drive_number); + break; + case XFER_PIO_4: + dma_pio_timing |= 0x20; + pio_timing |= (0x03 << drive_number); + break; + case XFER_PIO_3: + dma_pio_timing |= 0x22; + pio_timing |= (0x03 << drive_number); + break; + case XFER_PIO_2: + dma_pio_timing |= 0x42; + pio_timing |= (0x03 << drive_number); + break; + case XFER_PIO_1: + dma_pio_timing |= 0x65; + pio_timing |= (0x03 << drive_number); + break; + case XFER_PIO_0: + default: + dma_pio_timing |= 0xA8; + pio_timing |= (0x03 << drive_number); break; - case XFER_MW_DMA_2:break; - case XFER_MW_DMA_1:break; - case XFER_MW_DMA_0:break; - case XFER_SW_DMA_2:break; - case XFER_SW_DMA_1:break; - case XFER_SW_DMA_0:break; - case XFER_PIO_4:break; - case XFER_PIO_3:break; - case XFER_PIO_2:break; - case XFER_PIO_1:break; - case XFER_PIO_0:break; - default: break; } - printk(":: UDMA 0x%02x PIO 0x%02x\n", drive_timing, pio_timing); + pci_write_config_byte(dev, drive_pci, ultra_timing); + pci_write_config_byte(dev, drive_pci2, dma_pio_timing); + pci_write_config_byte(dev, 0x4c, pio_timing); + +#ifdef DEBUG + printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n", + ultra_timing, dma_pio_timing, pio_timing); +#endif + if (speed > XFER_PIO_4) { + outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); + } else { + outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); + } err = ide_config_drive_speed(drive, speed); return (err); } @@ -109,12 +201,14 @@ static int amd7409_tune_chipset (ide_drive_t *drive, byte speed) static int config_chipset_for_dma (ide_drive_t *drive) { struct hd_driveid *id = drive->id; + byte udma_66 = ((id->hw_config & 0x2000) && + (HWIF(drive)->udma_four)) ? 1 : 0; byte speed = 0x00; int rval; - if ((id->dma_ultra & 0x0010) && (HWIF(drive)->udma_four)) { + if ((id->dma_ultra & 0x0010) && (udma_66)) { speed = XFER_UDMA_4; - } else if ((id->dma_ultra & 0x0008) && (HWIF(drive)->udma_four)) { + } else if ((id->dma_ultra & 0x0008) && (udma_66)) { speed = XFER_UDMA_3; } else if (id->dma_ultra & 0x0004) { speed = XFER_UDMA_2; @@ -128,12 +222,6 @@ static int config_chipset_for_dma (ide_drive_t *drive) speed = XFER_MW_DMA_1; } else if (id->dma_mword & 0x0001) { speed = XFER_MW_DMA_0; - } else if (id->dma_1word & 0x0004) { - speed = XFER_SW_DMA_2; - } else if (id->dma_1word & 0x0002) { - speed = XFER_SW_DMA_1; - } else if (id->dma_1word & 0x0001) { - speed = XFER_SW_DMA_0; } else { return ((int) ide_dma_off_quietly); } @@ -143,7 +231,6 @@ static int config_chipset_for_dma (ide_drive_t *drive) rval = (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); return rval; @@ -222,8 +309,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } } else if (id->field_valid & 2) { try_dma_modes: - if ((id->dma_mword & 0x0007) || - (id->dma_1word & 0x0007)) { + if (id->dma_mword & 0x0007) { /* Force if Capable regular DMA modes */ dma_func = config_chipset_for_dma(drive); if (dma_func != ide_dma_on) @@ -265,16 +351,45 @@ int amd7409_dmaproc (ide_dma_action_t func, ide_drive_t *drive) return ide_dmaproc(func, drive); /* use standard DMA stuff */ } +unsigned int __init pci_init_amd7409 (struct pci_dev *dev, const char *name) +{ + unsigned long fixdma_base = dev->resource[4].start; + + if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) { + /* + * + */ + } else { + /* + * enable DMA capable bit, and "not" simplex only + */ + outb(inb(fixdma_base+2) & 0x60, fixdma_base+2); + + if (inb(fixdma_base+2) & 0x80) + printk("%s: simplex device: DMA will fail!!\n", name); + } +#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) + amd7409_proc = 1; + bmide_dev = dev; + amd7409_display_info = &amd7409_get_info; +#endif /* DISPLAY_VIPER_TIMINGS && CONFIG_PROC_FS */ + + return 0; +} + unsigned int __init ata66_amd7409 (ide_hwif_t *hwif) { -#if 0 +#ifdef CONFIG_AMD7409_OVERRIDE + byte ata66 = 1; +#else byte ata66 = 0; +#endif /* CONFIG_AMD7409_OVERRIDE */ +#if 0 pci_read_config_byte(hwif->pci_dev, 0x48, &ata66); return ((ata66 & 0x02) ? 0 : 1); -#else - return 0; #endif + return ata66; } void __init ide_init_amd7409 (ide_hwif_t *hwif) @@ -288,3 +403,8 @@ void __init ide_init_amd7409 (ide_hwif_t *hwif) hwif->drives[1].autotune = 1; } } + +void ide_dmacapable_amd7409 (ide_hwif_t *hwif, unsigned long dmabase) +{ + ide_setup_dma(hwif, dmabase, 8); +} diff --git a/drivers/block/buddha.c b/drivers/block/buddha.c index e5862cd31..3e1cfcd33 100644 --- a/drivers/block/buddha.c +++ b/drivers/block/buddha.c @@ -42,7 +42,7 @@ #define BUDDHA_BASE2 0xa00 #define BUDDHA_BASE3 0xc00 -static const u_int buddha_bases[CATWEASEL_NUM_HWIFS] = { +static const u_int __init buddha_bases[CATWEASEL_NUM_HWIFS] = { BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3 }; @@ -61,7 +61,7 @@ static const u_int buddha_bases[CATWEASEL_NUM_HWIFS] = { #define BUDDHA_STATUS 0x1e /* see status-bits */ #define BUDDHA_CONTROL 0x11a -static int buddha_offsets[IDE_NR_PORTS] = { +static int __init buddha_offsets[IDE_NR_PORTS] = { BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL, BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, BUDDHA_CONTROL }; @@ -75,7 +75,7 @@ static int buddha_offsets[IDE_NR_PORTS] = { #define BUDDHA_IRQ2 0xf40 /* interrupt */ #define BUDDHA_IRQ3 0xf80 -static const int buddha_irqports[CATWEASEL_NUM_HWIFS] = { +static const int __init buddha_irqports[CATWEASEL_NUM_HWIFS] = { BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3 }; @@ -109,7 +109,7 @@ static int buddha_ack_intr(ide_hwif_t *hwif) * Any Buddha or Catweasel boards present? */ -static int find_buddha(void) +static int __init find_buddha(void) { struct zorro_dev *z = NULL; @@ -143,7 +143,7 @@ static int find_buddha(void) * We support only _one_ of them, no multiple boards! */ -void buddha_init(void) +void __init buddha_init(void) { hw_regs_t hw; int i, index; diff --git a/drivers/block/cmd640.c b/drivers/block/cmd640.c index 3e5f56cec..b2077df6d 100644 --- a/drivers/block/cmd640.c +++ b/drivers/block/cmd640.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/cmd640.c Version 1.02 Sep 01, 1996 + * linux/drivers/block/cmd640.c Version 1.02 Sep 01, 1996 * * Copyright (C) 1995-1996 Linus Torvalds & authors (see below) */ @@ -290,7 +290,7 @@ static byte get_cmd640_reg_vlb (unsigned short reg) return b; } -static int match_pci_cmd640_device (void) +static int __init match_pci_cmd640_device (void) { const byte ven_dev[4] = {0x95, 0x10, 0x40, 0x06}; unsigned int i; @@ -310,7 +310,7 @@ static int match_pci_cmd640_device (void) /* * Probe for CMD640x -- pci method 1 */ -static int probe_for_cmd640_pci1 (void) +static int __init probe_for_cmd640_pci1 (void) { get_cmd640_reg = get_cmd640_reg_pci1; put_cmd640_reg = put_cmd640_reg_pci1; @@ -324,7 +324,7 @@ static int probe_for_cmd640_pci1 (void) /* * Probe for CMD640x -- pci method 2 */ -static int probe_for_cmd640_pci2 (void) +static int __init probe_for_cmd640_pci2 (void) { get_cmd640_reg = get_cmd640_reg_pci2; put_cmd640_reg = put_cmd640_reg_pci2; @@ -338,7 +338,7 @@ static int probe_for_cmd640_pci2 (void) /* * Probe for CMD640x -- vlb */ -static int probe_for_cmd640_vlb (void) +static int __init probe_for_cmd640_vlb (void) { byte b; @@ -359,7 +359,7 @@ static int probe_for_cmd640_vlb (void) * Returns 1 if an IDE interface/drive exists at 0x170, * Returns 0 otherwise. */ -static int secondary_port_responding (void) +static int __init secondary_port_responding (void) { unsigned long flags; @@ -403,7 +403,7 @@ void cmd640_dump_regs (void) * Check whether prefetch is on for a drive, * and initialize the unmask flags for safe operation. */ -static void check_prefetch (unsigned int index) +static void __init check_prefetch (unsigned int index) { ide_drive_t *drive = cmd_drives[index]; byte b = get_cmd640_reg(prefetch_regs[index]); @@ -424,7 +424,7 @@ static void check_prefetch (unsigned int index) /* * Figure out which devices we control */ -static void setup_device_ptrs (void) +static void __init setup_device_ptrs (void) { unsigned int i; @@ -507,7 +507,7 @@ inline static byte pack_nibbles (byte upper, byte lower) /* * This routine retrieves the initial drive timings from the chipset. */ -static void retrieve_drive_counts (unsigned int index) +static void __init retrieve_drive_counts (unsigned int index) { byte b; @@ -694,7 +694,7 @@ static void cmd640_tune_drive (ide_drive_t *drive, byte mode_wanted) /* * Probe for a cmd640 chipset, and initialize it if found. Called from ide.c */ -int ide_probe_for_cmd640x (void) +int __init ide_probe_for_cmd640x (void) { #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED int second_port_toggled = 0; diff --git a/drivers/block/cmd64x.c b/drivers/block/cmd64x.c index 8f5f04aea..4e98893ec 100644 --- a/drivers/block/cmd64x.c +++ b/drivers/block/cmd64x.c @@ -1,4 +1,4 @@ -/* $Id: cmd64x.c,v 1.20 1999/12/30 03:48:37 +/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * Note, this driver is not used at all on other systems because @@ -8,7 +8,7 @@ * * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1998 David S. Miller (davem@redhat.com) - * Copyright (C) 1999 Andre Hedrick (andre@suse.com) + * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com) */ #include <linux/types.h> @@ -18,8 +18,10 @@ #include <linux/ide.h> #include <asm/io.h> +#include "ide_modes.h" #define CMD_DEBUG 0 +#undef NO_WRITE #if CMD_DEBUG #define cmdprintk(x...) printk(##x) @@ -27,6 +29,235 @@ #define cmdprintk(x...) #endif +/* + * CMD64x specific registers definition. + */ + +#define CNTRL 0x51 +#define CNTRL_DIS_RA0 0x40 +#define CNTRL_DIS_RA1 0x80 +#define CNTRL_ENA_2ND 0x08 + +#define CMDTIM 0x52 +#define ARTTIM0 0x53 +#define DRWTIM0 0x54 +#define ARTTIM1 0x55 +#define DRWTIM1 0x56 +#define ARTTIM23 0x57 +#define ARTTIM23_DIS_RA2 0x04 +#define ARTTIM23_DIS_RA3 0x08 +#define DRWTIM23 0x58 +#define DRWTIM2 0x58 +#define BRST 0x59 +#define DRWTIM3 0x5b + +#define MRDMODE 0x71 + +#define DISPLAY_CMD64X_TIMINGS + +#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static int cmd64x_get_info(char *, char **, off_t, int); +extern int (*cmd64x_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static struct pci_dev *bmide_dev; + +static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) +{ + char *p = buffer; + u32 bibma = bmide_dev->resource[4].start; + u8 c0 = 0, c1 = 0; + + switch(bmide_dev->device) { + case PCI_DEVICE_ID_CMD_648: + p += sprintf(p, "\n CMD648 Chipset.\n"); + break; + case PCI_DEVICE_ID_CMD_646: + p += sprintf(p, "\n CMD646 Chipset.\n"); + break; + case PCI_DEVICE_ID_CMD_643: + p += sprintf(p, "\n CMD643 Chipset.\n"); + break; + default: + p += sprintf(p, "\n CMD64? Chipse.\n"); + break; + } + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\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 " ); + + p += sprintf(p, "UDMA\n"); + p += sprintf(p, "DMA\n"); + p += sprintf(p, "PIO\n"); + + return p-buffer; /* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ + +byte cmd64x_proc = 0; + +/* + * Registers and masks for easy access by drive index: + */ +#if 0 +static byte prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23}; +static byte prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3}; +#endif + +/* + * This routine writes the prepared setup/active/recovery counts + * for a drive into the cmd646 chipset registers to active them. + */ +static void program_drive_counts (ide_drive_t *drive, int setup_count, int active_count, int recovery_count) +{ + unsigned long flags; + ide_drive_t *drives = HWIF(drive)->drives; + byte temp_b; + static const byte setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; + static const byte recovery_counts[] = + {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; + static const byte arttim_regs[2][2] = { + { ARTTIM0, ARTTIM1 }, + { ARTTIM23, ARTTIM23 } + }; + static const byte drwtim_regs[2][2] = { + { DRWTIM0, DRWTIM1 }, + { DRWTIM2, DRWTIM3 } + }; + int channel = (int) HWIF(drive)->channel; + int slave = (drives != drive); /* Is this really the best way to determine this?? */ + + cmdprintk("program_drive_count parameters = s(%d),a(%d),r(%d),p(%d)\n", setup_count, + active_count, recovery_count, drive->present); + /* + * Set up address setup count registers. + * Primary interface has individual count/timing registers for + * each drive. Secondary interface has one common set of registers, + * for address setup so we merge these timings, using the slowest + * value. + */ + if (channel) { + drive->drive_data = setup_count; + setup_count = IDE_MAX(drives[0].drive_data, drives[1].drive_data); + cmdprintk("Secondary interface, setup_count = %d\n", setup_count); + } + + /* + * Convert values to internal chipset representation + */ + setup_count = (setup_count > 5) ? 0xc0 : (int) setup_counts[setup_count]; + active_count &= 0xf; /* Remember, max value is 16 */ + recovery_count = (int) recovery_counts[recovery_count]; + + cmdprintk("Final values = %d,%d,%d\n", setup_count, active_count, recovery_count); + + /* + * Now that everything is ready, program the new timings + */ + __save_flags (flags); + __cli(); + /* + * Program the address_setup clocks into ARTTIM reg, + * and then the active/recovery counts into the DRWTIM reg + */ + (void) pci_read_config_byte(HWIF(drive)->pci_dev, arttim_regs[channel][slave], &temp_b); +#ifndef NO_WRITE + (void) pci_write_config_byte(HWIF(drive)->pci_dev, arttim_regs[channel][slave], + ((byte) setup_count) | (temp_b & 0x3f)); + (void) pci_write_config_byte(HWIF(drive)->pci_dev, drwtim_regs[channel][slave], + (byte) ((active_count << 4) | recovery_count)); +#endif + cmdprintk ("Write %x to %x\n", ((byte) setup_count) | (temp_b & 0x3f), arttim_regs[channel][slave]); + cmdprintk ("Write %x to %x\n", (byte) ((active_count << 4) | recovery_count), drwtim_regs[channel][slave]); + __restore_flags(flags); +} + +/* + * Attempts to set the interface PIO mode. + * The preferred method of selecting PIO modes (e.g. mode 4) is + * "echo 'piomode:4' > /proc/ide/hdx/settings". Special cases are + * 8: prefetch off, 9: prefetch on, 255: auto-select best mode. + * Called with 255 at boot time. + */ +static void cmd64x_tuneproc (ide_drive_t *drive, byte mode_wanted) +{ + int setup_time, active_time, recovery_time, clock_time, pio_mode, cycle_time; + byte recovery_count2, cycle_count; + int setup_count, active_count, recovery_count; + int bus_speed = ide_system_bus_speed(); + /*byte b;*/ + ide_pio_data_t d; + + switch (mode_wanted) { + case 8: /* set prefetch off */ + case 9: /* set prefetch on */ + mode_wanted &= 1; + /*set_prefetch_mode(index, mode_wanted);*/ + cmdprintk("%s: %sabled cmd640 prefetch\n", drive->name, mode_wanted ? "en" : "dis"); + return; + } + + (void) ide_get_best_pio_mode (drive, mode_wanted, 5, &d); + pio_mode = d.pio_mode; + cycle_time = d.cycle_time; + + /* + * I copied all this complicated stuff from cmd640.c and made a few minor changes. + * For now I am just going to pray that it is correct. + */ + if (pio_mode > 5) + pio_mode = 5; + setup_time = ide_pio_timings[pio_mode].setup_time; + active_time = ide_pio_timings[pio_mode].active_time; + recovery_time = cycle_time - (setup_time + active_time); + clock_time = 1000 / bus_speed; + cycle_count = (cycle_time + clock_time - 1) / clock_time; + + setup_count = (setup_time + clock_time - 1) / clock_time; + + active_count = (active_time + clock_time - 1) / clock_time; + + recovery_count = (recovery_time + clock_time - 1) / clock_time; + recovery_count2 = cycle_count - (setup_count + active_count); + if (recovery_count2 > recovery_count) + recovery_count = recovery_count2; + if (recovery_count > 16) { + active_count += recovery_count - 16; + recovery_count = 16; + } + if (active_count > 16) + active_count = 16; /* maximum allowed by cmd646 */ + + /* + * In a perfect world, we might set the drive pio mode here + * (using WIN_SETFEATURE) before continuing. + * + * But we do not, because: + * 1) this is the wrong place to do it (proper is do_special() in ide.c) + * 2) in practice this is rarely, if ever, necessary + */ + program_drive_counts (drive, setup_count, active_count, recovery_count); + + printk ("%s: selected cmd646 PIO mode%d (%dns)%s, clocks=%d/%d/%d\n", + drive->name, pio_mode, cycle_time, + d.overridden ? " (overriding vendor mode)" : "", + setup_count, active_count, recovery_count); +} + static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66) { struct hd_driveid *id = drive->id; @@ -123,7 +354,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ul static void config_chipset_for_pio (ide_drive_t *drive, unsigned int rev) { - /* FIXME!! figure out some PIOing junk.... */ + cmd64x_tuneproc(drive, 5); } static int cmd64x_config_drive_for_dma (ide_drive_t *drive) @@ -198,7 +429,7 @@ fast_ata_pio: no_dma_set: config_chipset_for_pio(drive, class_rev); } - return hwif->dmaproc(dma_func, drive); + return HWIF(drive)->dmaproc(dma_func, drive); } static int cmd64x_dmaproc (ide_dma_action_t func, ide_drive_t *drive) @@ -277,9 +508,9 @@ unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name) #endif /* Setup interrupts. */ - (void) pci_read_config_byte(dev, 0x71, &mrdmode); + (void) pci_read_config_byte(dev, MRDMODE, &mrdmode); mrdmode &= ~(0x30); - (void) pci_write_config_byte(dev, 0x71, mrdmode); + (void) pci_write_config_byte(dev, MRDMODE, mrdmode); /* Use MEMORY READ LINE for reads. * NOTE: Although not mentioned in the PCI0646U specs, @@ -287,16 +518,26 @@ unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name) * back as set or not. The PCI0646U2 specs clarify * this point. */ - (void) pci_write_config_byte(dev, 0x71, mrdmode | 0x02); - + (void) pci_write_config_byte(dev, MRDMODE, mrdmode | 0x02); +#if 0 /* Set reasonable active/recovery/address-setup values. */ - (void) pci_write_config_byte(dev, 0x53, 0x40); - (void) pci_write_config_byte(dev, 0x54, 0x3f); - (void) pci_write_config_byte(dev, 0x55, 0x40); - (void) pci_write_config_byte(dev, 0x56, 0x3f); - (void) pci_write_config_byte(dev, 0x57, 0x5c); - (void) pci_write_config_byte(dev, 0x58, 0x3f); - (void) pci_write_config_byte(dev, 0x5b, 0x3f); + (void) pci_write_config_byte(dev, ARTTIM0, 0x40); + (void) pci_write_config_byte(dev, DRWTIM0, 0x3f); + (void) pci_write_config_byte(dev, ARTTIM1, 0x40); + (void) pci_write_config_byte(dev, DRWTIM1, 0x3f); + (void) pci_write_config_byte(dev, ARTTIM23, 0x5c); + (void) pci_write_config_byte(dev, DRWTIM23, 0x3f); + (void) pci_write_config_byte(dev, DRWTIM3, 0x3f); +#else + (void) pci_write_config_byte(dev, ARTTIM23, 0x1c); +#endif + +#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) + cmd64x_proc = 1; + bmide_dev = dev; + cmd64x_display_info = &cmd64x_get_info; +#endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */ + return 0; } @@ -317,8 +558,13 @@ void __init ide_init_cmd64x (ide_hwif_t *hwif) pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; - if (!hwif->dma_base) + hwif->tuneproc = &cmd64x_tuneproc; + + if (!hwif->dma_base) { + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; return; + } switch(dev->device) { case PCI_DEVICE_ID_CMD_643: diff --git a/drivers/block/cs5530.c b/drivers/block/cs5530.c index 3e26b8006..0f2f04990 100644 --- a/drivers/block/cs5530.c +++ b/drivers/block/cs5530.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/cs5530.c Version 0.5 Feb 13, 2000 + * linux/drivers/block/cs5530.c Version 0.5 Feb 13, 2000 * * Copyright (C) 2000 Mark Lord <mlord@pobox.com> * May be copied or modified under the terms of the GNU General Public License @@ -24,130 +24,63 @@ #include <asm/irq.h> #include "ide_modes.h" -/* - * Return the mode name for a drive transfer mode value: - */ -static const char *strmode (byte mode) +#define DISPLAY_CS5530_TIMINGS + +#if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static int cs5530_get_info(char *, char **, off_t, int); +extern int (*cs5530_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static struct pci_dev *bmide_dev; + +static int cs5530_get_info (char *buffer, char **addr, off_t offset, int count) { - switch (mode) { - case XFER_UDMA_4: return("UDMA4"); - case XFER_UDMA_3: return("UDMA3"); - case XFER_UDMA_2: return("UDMA2"); - case XFER_UDMA_1: return("UDMA1"); - case XFER_UDMA_0: return("UDMA0"); - case XFER_MW_DMA_2: return("MDMA2"); - case XFER_MW_DMA_1: return("MDMA1"); - case XFER_MW_DMA_0: return("MDMA0"); - case XFER_SW_DMA_2: return("SDMA2"); - case XFER_SW_DMA_1: return("SDMA1"); - case XFER_SW_DMA_0: return("SDMA0"); - case XFER_PIO_4: return("PIO4"); - case XFER_PIO_3: return("PIO3"); - case XFER_PIO_2: return("PIO2"); - case XFER_PIO_1: return("PIO1"); - case XFER_PIO_0: return("PIO0"); - default: return("???"); - } + char *p = buffer; + u32 bibma = bmide_dev->resource[4].start; + u8 c0 = 0, c1 = 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + + p += sprintf(p, "\n Cyrix 5530 Chipset.\n"); + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\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 " ); + + p += sprintf(p, "UDMA\n"); + p += sprintf(p, "DMA\n"); + p += sprintf(p, "PIO\n"); + + return p-buffer; } +#endif /* DISPLAY_CS5530_TIMINGS && CONFIG_PROC_FS */ + +byte cs5530_proc = 0; + +extern char *ide_xfer_verbose (byte xfer_rate); /* * Set a new transfer mode at the drive */ int cs5530_set_xfer_mode (ide_drive_t *drive, byte mode) { - int i, error = 1; - byte stat; - ide_hwif_t *hwif = HWIF(drive); - - printk("%s: cs5530_set_xfer_mode(%s)\n", drive->name, strmode(mode)); - /* - * If this is a DMA mode setting, then turn off all DMA bits. - * We will set one of them back on afterwards, if all goes well. - * - * Not sure why this is needed (it looks very silly), - * but other IDE chipset drivers also do this fiddling. ???? -ml - */ - switch (mode) { - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_MW_DMA_0: - case XFER_SW_DMA_2: - case XFER_SW_DMA_1: - case XFER_SW_DMA_0: - drive->id->dma_ultra &= ~0xFF00; - drive->id->dma_mword &= ~0x0F00; - drive->id->dma_1word &= ~0x0F00; - } + int error = 0; - /* - * Select the drive, and issue the SETFEATURES command - */ - disable_irq(hwif->irq); - udelay(1); - SELECT_DRIVE(HWIF(drive), drive); - udelay(1); - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG); - OUT_BYTE(mode, IDE_NSECTOR_REG); - OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG); - OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); - udelay(1); /* spec allows drive 400ns to assert "BUSY" */ + printk("%s: cs5530_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode)); + error = ide_config_drive_speed(drive, mode); - /* - * Wait for drive to become non-BUSY - */ - if ((stat = GET_STAT()) & BUSY_STAT) { - unsigned long flags, timeout; - __save_flags(flags); /* local CPU only */ - ide__sti(); /* local CPU only -- for jiffies */ - timeout = jiffies + WAIT_CMD; - while ((stat = GET_STAT()) & BUSY_STAT) { - if (0 < (signed long)(jiffies - timeout)) - break; - } - __restore_flags(flags); /* local CPU only */ - } - - /* - * Allow status to settle, then read it again. - * A few rare drives vastly violate the 400ns spec here, - * so we'll wait up to 10usec for a "good" status - * rather than expensively fail things immediately. - */ - for (i = 0; i < 10; i++) { - udelay(1); - if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) { - error = 0; - break; - } - } - enable_irq(hwif->irq); - - /* - * Turn dma bit on if all is okay - */ - if (error) { - (void) ide_dump_status(drive, "cs5530_set_xfer_mode", stat); - } else { - switch (mode) { - case XFER_UDMA_4: drive->id->dma_ultra |= 0x1010; break; - case XFER_UDMA_3: drive->id->dma_ultra |= 0x0808; break; - case XFER_UDMA_2: drive->id->dma_ultra |= 0x0404; break; - case XFER_UDMA_1: drive->id->dma_ultra |= 0x0202; break; - case XFER_UDMA_0: drive->id->dma_ultra |= 0x0101; break; - case XFER_MW_DMA_2: drive->id->dma_mword |= 0x0404; break; - case XFER_MW_DMA_1: drive->id->dma_mword |= 0x0202; break; - case XFER_MW_DMA_0: drive->id->dma_mword |= 0x0101; break; - case XFER_SW_DMA_2: drive->id->dma_1word |= 0x0404; break; - case XFER_SW_DMA_1: drive->id->dma_1word |= 0x0202; break; - case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break; - } - } return error; } @@ -302,8 +235,10 @@ int cs5530_dmaproc (ide_dma_action_t func, ide_drive_t *drive) case ide_dma_check: return cs5530_config_dma(drive); default: - return ide_dmaproc(func, drive); + break; } + /* Other cases are done by generic IDE-DMA code. */ + return ide_dmaproc(func, drive); } /* @@ -384,6 +319,13 @@ unsigned int __init pci_init_cs5530 (struct pci_dev *dev, const char *name) pci_write_config_byte(master_0, 0x43, 0xc1); restore_flags(flags); + +#if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS) + cs5530_proc = 1; + bmide_dev = dev; + cs5530_display_info = &cs5530_get_info; +#endif /* DISPLAY_CS5530_TIMINGS && CONFIG_PROC_FS */ + return 0; } diff --git a/drivers/block/cy82c693.c b/drivers/block/cy82c693.c index 412f403c3..cfff0381c 100644 --- a/drivers/block/cy82c693.c +++ b/drivers/block/cy82c693.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/cy82c693.c Version 0.34 Dec. 13, 1999 + * linux/drivers/block/cy82c693.c Version 0.34 Dec. 13, 1999 * * Copyright (C) 1998-99 Andreas S. Krebs (akrebs@altavista.net), Maintainer * Copyright (C) 1998-99 Andre Hedrick, Integrater @@ -54,7 +54,7 @@ #include "ide_modes.h" /* the current version */ -#define CY82_VERSION "CY82C693U driver v0.34 99-09-03 Andreas S. Krebs (akrebs@altavista.net)" +#define CY82_VERSION "CY82C693U driver v0.34 99-13-12 Andreas S. Krebs (akrebs@altavista.net)" /* * The following are used to debug the driver. @@ -439,4 +439,3 @@ void __init ide_init_cy82c693(ide_hwif_t *hwif) hwif->drives[1].autotune = 1; } } - diff --git a/drivers/block/dtc2278.c b/drivers/block/dtc2278.c index d805dec75..d8838e111 100644 --- a/drivers/block/dtc2278.c +++ b/drivers/block/dtc2278.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/dtc2278.c Version 0.02 Feb 10, 1996 + * linux/drivers/block/dtc2278.c Version 0.02 Feb 10, 1996 * * Copyright (C) 1996 Linus Torvalds & author (see below) */ @@ -95,7 +95,7 @@ static void tune_dtc2278 (ide_drive_t *drive, byte pio) HWIF(drive)->drives[!drive->select.b.unit].io_32bit = 1; } -void init_dtc2278 (void) +void __init init_dtc2278 (void) { unsigned long flags; diff --git a/drivers/block/falconide.c b/drivers/block/falconide.c index 321569eb1..7bce07517 100644 --- a/drivers/block/falconide.c +++ b/drivers/block/falconide.c @@ -40,7 +40,7 @@ #define ATA_HD_STATUS 0x1d /* see status-bits */ #define ATA_HD_CONTROL 0x39 -static int falconide_offsets[IDE_NR_PORTS] = { +static int __init 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 }; @@ -50,7 +50,7 @@ static int falconide_offsets[IDE_NR_PORTS] = { * Probe for a Falcon IDE interface */ -void falconide_init(void) +void __init falconide_init(void) { if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) { hw_regs_t hw; diff --git a/drivers/block/gayle.c b/drivers/block/gayle.c index 920f2ee0a..29cceb20e 100644 --- a/drivers/block/gayle.c +++ b/drivers/block/gayle.c @@ -41,7 +41,7 @@ #define GAYLE_STATUS 0x1e /* see status-bits */ #define GAYLE_CONTROL 0x101a -static int gayle_offsets[IDE_NR_PORTS] = { +static int __init gayle_offsets[IDE_NR_PORTS] = { GAYLE_DATA, GAYLE_ERROR, GAYLE_NSECTOR, GAYLE_SECTOR, GAYLE_LCYL, GAYLE_HCYL, GAYLE_SELECT, GAYLE_STATUS, -1, -1 }; @@ -105,7 +105,7 @@ static int gayle_ack_intr_a1200(ide_hwif_t *hwif) * Probe for a Gayle IDE interface (and optionally for an IDE doubler) */ -void gayle_init(void) +void __init gayle_init(void) { int a4000, i; diff --git a/drivers/block/hpt34x.c b/drivers/block/hpt34x.c index 10fe3ebc1..7a077368e 100644 --- a/drivers/block/hpt34x.c +++ b/drivers/block/hpt34x.c @@ -1,7 +1,7 @@ /* - * linux/drivers/block/hpt34x.c Version 0.28 Dec. 13, 1999 + * linux/drivers/block/hpt34x.c Version 0.29 Feb. 10, 2000 * - * Copyright (C) 1998-99 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) * May be copied or modified under the terms of the GNU General Public License * * @@ -16,6 +16,12 @@ * hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070) * hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0) * + * ide-pci.c reference + * + * 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 */ #include <linux/config.h> @@ -27,7 +33,6 @@ #include <linux/ioport.h> #include <linux/blkdev.h> #include <linux/hdreg.h> - #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/init.h> @@ -35,16 +40,56 @@ #include <asm/io.h> #include <asm/irq.h> - #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 +#define HPT343_DEBUG_DRIVE_INFO 1 + +#define DISPLAY_HPT34X_TIMINGS +#if defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static int hpt34x_get_info(char *, char **, off_t, int); +extern int (*hpt34x_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static struct pci_dev *bmide_dev; + +static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count) +{ + char *p = buffer; + u32 bibma = bmide_dev->resource[4].start; + u8 c0 = 0, c1 = 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + + p += sprintf(p, "\n HPT34X Chipset.\n"); + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\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 " ); + + p += sprintf(p, "UDMA\n"); + p += sprintf(p, "DMA\n"); + p += sprintf(p, "PIO\n"); + + return p-buffer; /* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS) */ + +byte hpt34x_proc = 0; extern char *ide_xfer_verbose (byte xfer_rate); @@ -109,12 +154,8 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) 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 */ hpt34x_clear_chipset(drive); @@ -249,14 +290,13 @@ try_dma_modes: fast_ata_pio: dma_func = ide_dma_off_quietly; no_dma_set: - config_chipset_for_pio(drive); } -#if 0 +#ifndef CONFIG_HPT34X_AUTODMA if (dma_func == ide_dma_on) dma_func = ide_dma_off; -#endif +#endif /* CONFIG_HPT34X_AUTODMA */ return HWIF(drive)->dmaproc(dma_func, drive); } @@ -273,18 +313,10 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); unsigned long dma_base = hwif->dma_base; - byte unit = (drive->select.b.unit & 0x01); unsigned int count, reading = 0; byte dma_stat; switch (func) { - case ide_dma_off: - case ide_dma_off_quietly: - outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); - break; - case ide_dma_on: - outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); - break; case ide_dma_check: return config_drive_xfer_rate(drive); case ide_dma_read: @@ -357,11 +389,16 @@ unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name) pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start); pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, dev->resource[2].start); pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, dev->resource[3].start); - pci_write_config_word(dev, PCI_COMMAND, cmd); __restore_flags(flags); /* local CPU only */ +#if defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS) + hpt34x_proc = 1; + bmide_dev = dev; + hpt34x_display_info = &hpt34x_get_info; +#endif /* DISPLAY_HPT34X_TIMINGS && CONFIG_PROC_FS */ + return dev->irq; } @@ -372,11 +409,7 @@ void __init ide_init_hpt34x (ide_hwif_t *hwif) unsigned short pcicmd = 0; pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd); -#ifdef CONFIG_BLK_DEV_HPT34X_DMA -#if 0 hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0; -#endif -#endif /* CONFIG_BLK_DEV_HPT34X_DMA */ hwif->dmaproc = &hpt34x_dmaproc; } else { hwif->drives[0].autotune = 1; diff --git a/drivers/block/hpt366.c b/drivers/block/hpt366.c index 7328ea7b8..02c9c16dd 100644 --- a/drivers/block/hpt366.c +++ b/drivers/block/hpt366.c @@ -1,7 +1,7 @@ /* - * linux/drivers/block/hpt366.c Version 0.15 Dec. 22, 1999 + * linux/drivers/block/hpt366.c Version 0.16 Feb. 10, 2000 * - * Copyright (C) 1999 Andre Hedrick <andre@suse.com> + * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com> * May be copied or modified under the terms of the GNU General Public License * * Thanks to HighPoint Technologies for their assistance, and hardware. @@ -30,6 +30,13 @@ #include "ide_modes.h" +#define DISPLAY_HPT366_TIMINGS + +#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> +#endif /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */ + const char *bad_ata66_4[] = { "WDC AC310200R", NULL @@ -120,6 +127,48 @@ struct chipset_bus_clock_list_entry twenty_five_base [] = { #define HPT366_ALLOW_ATA66_4 1 #define HPT366_ALLOW_ATA66_3 1 +#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) +static int hpt366_get_info(char *, char **, off_t, int); +extern int (*hpt366_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static struct pci_dev *bmide_dev; +static struct pci_dev *bmide2_dev; + +static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count) +{ + char *p = buffer; + u32 bibma = bmide_dev->resource[4].start; + u32 bibma2 = bmide2_dev->resource[4].start; + u8 c0 = 0, c1 = 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + if (bmide2_dev) + c1 = inb_p((unsigned short)bibma2 + 0x02); + + p += sprintf(p, "\n HPT366 Chipset.\n"); + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\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 " ); + + p += sprintf(p, "UDMA\n"); + p += sprintf(p, "DMA\n"); + p += sprintf(p, "PIO\n"); + + return p-buffer;/* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */ + +byte hpt366_proc = 0; + extern char *ide_xfer_verbose (byte xfer_rate); byte hpt363_shared_irq = 0; byte hpt363_shared_pin = 0; @@ -263,20 +312,20 @@ static int config_chipset_for_dma (ide_drive_t *drive) pci_read_config_byte(HWIF(drive)->pci_dev, 0x51, ®51h); -#ifdef CONFIG_HPT366_FAST_IRQ_PREDICTION +#ifdef CONFIG_HPT366_FIP /* * Some drives prefer/allow for the method of handling interrupts. */ if (!(reg51h & 0x80)) pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, reg51h|0x80); -#else /* ! CONFIG_HPT366_FAST_IRQ_PREDICTION */ +#else /* ! CONFIG_HPT366_FIP */ /* * Disable the "fast interrupt" prediction. * Instead, always wait for the real interrupt from the drive! */ if (reg51h & 0x80) pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, reg51h & ~0x80); -#endif /* CONFIG_HPT366_FAST_IRQ_PREDICTION */ +#endif /* CONFIG_HPT366_FIP */ /* * Preserve existing PIO settings: @@ -420,7 +469,6 @@ no_dma_set: * This is specific to the HPT366 UDMA bios chipset * by HighPoint|Triones Technologies, Inc. */ - int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive) { byte reg50h = 0; @@ -434,7 +482,6 @@ int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive) pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); /* ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); */ case ide_dma_timeout: - break; default: break; } @@ -464,6 +511,17 @@ unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name) if (test != 0x08) pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); +#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) + if (!hpt366_proc) { + hpt366_proc = 1; + bmide_dev = dev; + hpt366_display_info = &hpt366_get_info; + } + if ((hpt366_proc) && ((dev->devfn - bmide_dev->devfn) == 1)) { + bmide2_dev = dev; + } +#endif /* DISPLAY_HPT366_TIMINGS && CONFIG_PROC_FS */ + return dev->irq; } @@ -482,18 +540,6 @@ unsigned int __init ata66_hpt366 (ide_hwif_t *hwif) void __init ide_init_hpt366 (ide_hwif_t *hwif) { -#if 0 - if ((PCI_FUNC(hwif->pci_dev->devfn) & 1) && (hpt363_shared_irq)) { - hwif->mate = &ide_hwifs[hwif->index-1]; - hwif->mate->mate = hwif; - hwif->serialized = hwif->mate->serialized = 1; - } - - if ((PCI_FUNC(hwif->pci_dev->devfn) & 1) && (hpt363_shared_pin)) { - - } -#endif - hwif->tuneproc = &hpt366_tune_drive; if (hwif->dma_base) { hwif->dmaproc = &hpt366_dmaproc; diff --git a/drivers/block/ht6560b.c b/drivers/block/ht6560b.c index d9fb885c2..6b7d5af72 100644 --- a/drivers/block/ht6560b.c +++ b/drivers/block/ht6560b.c @@ -1,7 +1,7 @@ /* - * linux/drivers/block/ht6580.c Version 0.04 Mar 19, 1996 + * linux/drivers/block/ht6560b.c Version 0.07 Feb 1, 2000 * - * Copyright (C) 1995-1996 Linus Torvalds & author (see below) + * Copyright (C) 1995-2000 Linus Torvalds & author (see below) */ /* @@ -12,42 +12,31 @@ * * Version 0.03 Some cleanups * - * I reviewed some assembler source listings of htide drivers and found - * out how they setup those cycle time interfacing values, as they at Holtek - * call them. IDESETUP.COM that is supplied with the drivers figures out - * optimal values and fetches those values to drivers. I found out that - * they use IDE_SELECT_REG to fetch timings to the ide board right after - * interface switching. After that it was quite easy to add code to - * ht6560b.c. + * Version 0.05 PIO mode cycle timings auto-tune using bus-speed * - * IDESETUP.COM gave me values 0x24, 0x45, 0xaa, 0xff that worked fine - * for hda and hdc. But hdb needed higher values to work, so I guess - * that sometimes it is necessary to give higher value than IDESETUP - * gives. [see cmd640.c for an extreme example of this. -ml] + * Version 0.06 Prefetch mode now defaults no OFF. To set + * prefetch mode OFF/ON use "hdparm -p8/-p9". + * Unmask irq is disabled when prefetch mode + * is enabled. * - * Perhaps I should explain something about these timing values: - * The higher nibble of value is the Recovery Time (rt) and the lower nibble - * of the value is the Active Time (at). Minimum value 2 is the fastest and - * the maximum value 15 is the slowest. Default values should be 15 for both. - * So 0x24 means 2 for rt and 4 for at. Each of the drives should have - * both values, and IDESETUP gives automatically rt=15 st=15 for CDROMs or - * similar. If value is too small there will be all sorts of failures. - * - * Port 0x3e6 bit 0x20 sets these timings on/off. If 0x20 bit is set - * these timings are disabled. + * Version 0.07 Trying to fix CD-ROM detection problem. + * "Prefetch" mode bit OFF for ide disks and + * ON for anything else. * - * Mikko Ala-Fossi * - * More notes: + * HT-6560B EIDE-controller support + * To activate controller support use kernel parameter "ide0=ht6560b". + * Use hdparm utility to enable PIO mode support. * - * There's something still missing from the initialization code, though. - * If I have booted to dos sometime after power on, I can get smaller - * timing values working. Perhaps I could soft-ice the initialization. + * Author: Mikko Ala-Fossi <maf@iki.fi> + * Jan Evert van Grootheest <janevert@iae.nl> * - * -=- malafoss@snakemail.hut.fi -=- searching the marvels of universe -=- + * Try: http://www.maf.iki.fi/~maf/ht6560b/ */ -#undef REALLY_SLOW_IO /* most systems can safely undef this */ +#define HT6560B_VERSION "v0.07" + +#undef REALLY_SLOW_IO /* most systems can safely undef this */ #include <linux/types.h> #include <linux/kernel.h> @@ -63,175 +52,291 @@ #include "ide_modes.h" -/* - * This routine handles interface switching for the peculiar hardware design - * on the F.G.I./Holtek HT-6560B VLB IDE interface. - * The HT-6560B can only enable one IDE port at a time, and requires a - * silly sequence (below) whenever we switch between primary and secondary. - * - * This stuff is courtesy of malafoss@snakemail.hut.fi - * (or maf@nemesis.tky.hut.fi) - * - * At least one user has reported that this code can confuse the floppy - * controller and/or driver -- perhaps this should be changed to use - * a read-modify-write sequence, so as not to disturb other bits in the reg? - */ +/* #define DEBUG */ /* remove comments for DEBUG messages */ /* - * The special i/o-port that HT-6560B uses to select interfaces: + * The special i/o-port that HT-6560B uses to configuration: + * bit0 (0x01): "1" selects secondary interface + * bit2 (0x04): "1" enables FIFO function + * bit5 (0x20): "1" enables prefetched data read function (???) + * + * The special i/o-port that HT-6560A uses to configuration: + * bit0 (0x01): "1" selects secondary interface + * bit1 (0x02): "1" enables prefetched data read function + * bit2 (0x04): "0" enables multi-master system (?) + * bit3 (0x08): "1" 3 cycle time, "0" 2 cycle time (?) */ -#define HT_SELECT_PORT 0x3e6 - +#define HT_CONFIG_PORT 0x3e6 +#define HT_CONFIG(drivea) (byte)(((drivea)->drive_data & 0xff00) >> 8) /* - * We don't know what all of the bits are for, but we *do* know about these: - * bit5 (0x20): "1" selects slower speed by disabling use of timing values - * bit0 (0x01): "1" selects second interface + * FIFO + PREFETCH (both a/b-model) */ -static byte ht6560b_selects [2][MAX_DRIVES] = {{0x3c,0x3c}, {0x3d,0x3d}}; +#define HT_CONFIG_DEFAULT 0x1c /* no prefetch */ +/* #define HT_CONFIG_DEFAULT 0x3c */ /* with prefetch */ +#define HT_SECONDARY_IF 0x01 +#define HT_PREFETCH_MODE 0x20 /* - * VLB ht6560b Timing values: + * ht6560b Timing values: + * + * I reviewed some assembler source listings of htide drivers and found + * out how they setup those cycle time interfacing values, as they at Holtek + * call them. IDESETUP.COM that is supplied with the drivers figures out + * optimal values and fetches those values to drivers. I found out that + * they use IDE_SELECT_REG to fetch timings to the ide board right after + * interface switching. After that it was quite easy to add code to + * ht6560b.c. + * + * IDESETUP.COM gave me values 0x24, 0x45, 0xaa, 0xff that worked fine + * for hda and hdc. But hdb needed higher values to work, so I guess + * that sometimes it is necessary to give higher value than IDESETUP + * gives. [see cmd640.c for an extreme example of this. -ml] + * + * Perhaps I should explain something about these timing values: + * The higher nibble of value is the Recovery Time (rt) and the lower nibble + * of the value is the Active Time (at). Minimum value 2 is the fastest and + * the maximum value 15 is the slowest. Default values should be 15 for both. + * So 0x24 means 2 for rt and 4 for at. Each of the drives should have + * both values, and IDESETUP gives automatically rt=15 st=15 for CDROMs or + * similar. If value is too small there will be all sorts of failures. * * Timing byte consists of - * High nibble: Recovery Time (rt) - * The valid values range from 2 to 15. The default is 15. + * High nibble: Recovery Cycle Time (rt) + * The valid values range from 2 to 15. The default is 15. * - * Low nibble: Active Time (at) - * The valid values range from 2 to 15. The default is 15. + * Low nibble: Active Cycle Time (at) + * The valid values range from 2 to 15. The default is 15. * * You can obtain optimized timing values by running Holtek IDESETUP.COM * for DOS. DOS drivers get their timing values from command line, where * the first value is the Recovery Time and the second value is the * Active Time for each drive. Smaller value gives higher speed. * In case of failures you should probably fall back to a higher value. - * - * Here's an example to make it clearer: - * - * DOS: DEVICE=C:\bin\HTIDE\HTIDE.SYS /D0=2,4 /D1=4,5 /D2=10,10 /D3=15,15 - * Linux: byte ht6560b_timings [][] = {{0x24, 0x45}, {0xaa, 0xff}}; - * - * Note: There are no ioctls to change these values directly, - * but settings can be approximated as PIO modes, using "hdparm": - * - * rc.local: hdparm -p3 /dev/hda -p2 /dev/hdb -p1 /dev/hdc -p0 /dev/hdd */ +#define HT_TIMING(drivea) (byte)((drivea)->drive_data & 0x00ff) +#define HT_TIMING_DEFAULT 0xff -static byte ht6560b_timings [2][MAX_DRIVES] = {{0xff,0xff}, {0xff,0xff}}; - -static byte pio_to_timings[6] = {0xff, 0xaa, 0x45, 0x24, 0x13, 0x12}; +/* + * This routine handles interface switching for the peculiar hardware design + * on the F.G.I./Holtek HT-6560B VLB IDE interface. + * The HT-6560B can only enable one IDE port at a time, and requires a + * silly sequence (below) whenever we switch between primary and secondary. + */ /* * This routine is invoked from ide.c to prepare for access to a given drive. */ static void ht6560b_selectproc (ide_drive_t *drive) { - byte t; unsigned long flags; static byte current_select = 0; static byte current_timing = 0; - byte select = ht6560b_selects[HWIF(drive)->index][drive->select.b.unit]; - byte timing = ht6560b_timings[HWIF(drive)->index][drive->select.b.unit]; - + byte select, timing; + + __save_flags (flags); /* local CPU only */ + __cli(); /* local CPU only */ + + select = HT_CONFIG(drive); + timing = HT_TIMING(drive); + if (select != current_select || timing != current_timing) { current_select = select; current_timing = timing; - __save_flags (flags); /* local CPU only */ - __cli(); /* local CPU only */ - (void) inb(HT_SELECT_PORT); - (void) inb(HT_SELECT_PORT); - (void) inb(HT_SELECT_PORT); + if (drive->media != ide_disk || !drive->present) + select |= HT_PREFETCH_MODE; + (void) inb(HT_CONFIG_PORT); + (void) inb(HT_CONFIG_PORT); + (void) inb(HT_CONFIG_PORT); + (void) inb(HT_CONFIG_PORT); + outb(select, HT_CONFIG_PORT); /* - * Note: input bits are reversed to output bits!! + * Set timing for this drive: */ - t = inb(HT_SELECT_PORT) ^ 0x3f; - t &= (~0x21); - t |= (current_select & 0x21); - outb(t, HT_SELECT_PORT); - /* - * Set timing for this drive: - */ - outb (timing, IDE_SELECT_REG); - (void) inb (IDE_STATUS_REG); - __restore_flags (flags); /* local CPU only */ + outb(timing, IDE_SELECT_REG); + (void) inb(IDE_STATUS_REG); #ifdef DEBUG - printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, t, timing); + printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, select, timing); #endif } + __restore_flags (flags); /* local CPU only */ } /* * Autodetection and initialization of ht6560b */ -int try_to_init_ht6560b(void) +static int __init try_to_init_ht6560b(void) { byte orig_value; int i; - + /* Autodetect ht6560b */ - if ((orig_value=inb(HT_SELECT_PORT)) == 0xff) + if ((orig_value=inb(HT_CONFIG_PORT)) == 0xff) return 0; - + for (i=3;i>0;i--) { - outb(0x00, HT_SELECT_PORT); - if (!( (~inb(HT_SELECT_PORT)) & 0x3f )) { - outb(orig_value, HT_SELECT_PORT); - return 0; + outb(0x00, HT_CONFIG_PORT); + if (!( (~inb(HT_CONFIG_PORT)) & 0x3f )) { + outb(orig_value, HT_CONFIG_PORT); + return 0; } } - outb(0x00, HT_SELECT_PORT); - if ((~inb(HT_SELECT_PORT))& 0x3f) { - outb(orig_value, HT_SELECT_PORT); + outb(0x00, HT_CONFIG_PORT); + if ((~inb(HT_CONFIG_PORT))& 0x3f) { + outb(orig_value, HT_CONFIG_PORT); return 0; } /* - * Ht6560b autodetected: - * reverse input bits to output bits - * initialize bit1 to 0 + * Ht6560b autodetected */ - outb((orig_value ^ 0x3f) & 0xfd, HT_SELECT_PORT); - - printk("\nht6560b: detected and initialized"); + outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT); + outb(HT_TIMING_DEFAULT, 0x1f6); /* IDE_SELECT_REG */ + (void) inb(0x1f7); /* IDE_STATUS_REG */ + + printk("\nht6560b " HT6560B_VERSION + ": chipset detected and initialized" +#ifdef DEBUG + " with debug enabled" +#endif + ); return 1; } -static void tune_ht6560b (ide_drive_t *drive, byte pio) +static byte ht_pio2timings(ide_drive_t *drive, byte pio) { - unsigned int hwif, unit; + int bus_speed, active_time, recovery_time; + int active_cycles, recovery_cycles; + ide_pio_data_t d; + + if (pio) { + pio = ide_get_best_pio_mode(drive, pio, 5, &d); + + /* + * Just like opti621.c we try to calculate the + * actual cycle time for recovery and activity + * according system bus speed. + */ + bus_speed = ide_system_bus_speed(); + active_time = ide_pio_timings[pio].active_time; + recovery_time = d.cycle_time + - active_time + - ide_pio_timings[pio].setup_time; + /* + * Cycle times should be Vesa bus cycles + */ + active_cycles = (active_time * bus_speed + 999) / 1000; + recovery_cycles = (recovery_time * bus_speed + 999) / 1000; + /* + * Upper and lower limits + */ + if (active_cycles < 2) active_cycles = 2; + if (recovery_cycles < 2) recovery_cycles = 2; + if (active_cycles > 15) active_cycles = 15; + if (recovery_cycles > 15) recovery_cycles = 0; /* 0==16 */ + +#ifdef DEBUG + printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", drive->name, pio, recovery_cycles, recovery_time, active_cycles, active_time); +#endif + + return (byte)((recovery_cycles << 4) | active_cycles); + } else { + +#ifdef DEBUG + printk("ht6560b: drive %s setting pio=0\n", drive->name); +#endif + + return HT_TIMING_DEFAULT; /* default setting */ + } +} + +/* + * Enable/Disable so called prefetch mode + */ +static void ht_set_prefetch(ide_drive_t *drive, byte state) +{ + unsigned long flags; + int t = HT_PREFETCH_MODE << 8; + + save_flags (flags); /* all CPUs */ + cli(); /* all CPUs */ + + /* + * Prefetch mode and unmask irq seems to conflict + */ + if (state) { + drive->drive_data |= t; /* enable prefetch mode */ + drive->no_unmask = 1; + drive->unmask = 0; + } else { + drive->drive_data &= ~t; /* disable prefetch mode */ + drive->no_unmask = 0; + } + + restore_flags (flags); /* all CPUs */ + +#ifdef DEBUG + printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis")); +#endif +} - if (pio == 255) { /* auto-tune */ - if (drive->media != ide_disk) - pio = 0; /* some CDROMs don't like fast modes (?) */ - else - pio = ide_get_best_pio_mode(drive, pio, 5, NULL); +static void tune_ht6560b (ide_drive_t *drive, byte pio) +{ + unsigned long flags; + byte timing; + + switch (pio) { + case 8: /* set prefetch off */ + case 9: /* set prefetch on */ + ht_set_prefetch(drive, pio & 1); + return; } - unit = drive->select.b.unit; - hwif = HWIF(drive)->index; - ht6560b_timings[hwif][unit] = pio_to_timings[pio]; - if (pio == 0) - ht6560b_selects[hwif][unit] |= 0x20; - else - ht6560b_selects[hwif][unit] &= ~0x20; + + timing = ht_pio2timings(drive, pio); + + save_flags (flags); /* all CPUs */ + cli(); /* all CPUs */ + + drive->drive_data &= 0xff00; + drive->drive_data |= timing; + + restore_flags (flags); /* all CPUs */ + +#ifdef DEBUG + printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing); +#endif } -void init_ht6560b (void) +void __init init_ht6560b (void) { - if (check_region(HT_SELECT_PORT,1)) { - printk("\nht6560b: PORT 0x3e6 ALREADY IN USE\n"); + int t; + + if (check_region(HT_CONFIG_PORT,1)) { + printk(KERN_ERR "ht6560b: PORT %#x ALREADY IN USE\n", HT_CONFIG_PORT); } else { if (try_to_init_ht6560b()) { - request_region(HT_SELECT_PORT, 1, ide_hwifs[0].name); + request_region(HT_CONFIG_PORT, 1, ide_hwifs[0].name); ide_hwifs[0].chipset = ide_ht6560b; ide_hwifs[1].chipset = ide_ht6560b; ide_hwifs[0].selectproc = &ht6560b_selectproc; ide_hwifs[1].selectproc = &ht6560b_selectproc; ide_hwifs[0].tuneproc = &tune_ht6560b; ide_hwifs[1].tuneproc = &tune_ht6560b; - ide_hwifs[0].serialized = 1; - ide_hwifs[1].serialized = 1; + ide_hwifs[0].serialized = 1; /* is this needed? */ + ide_hwifs[1].serialized = 1; /* is this needed? */ ide_hwifs[0].mate = &ide_hwifs[1]; ide_hwifs[1].mate = &ide_hwifs[0]; ide_hwifs[1].channel = 1; + + /* + * Setting default configurations for drives + */ + t = (HT_CONFIG_DEFAULT << 8); + t |= HT_TIMING_DEFAULT; + ide_hwifs[0].drives[0].drive_data = t; + ide_hwifs[0].drives[1].drive_data = t; + t |= (HT_SECONDARY_IF << 8); + ide_hwifs[1].drives[0].drive_data = t; + ide_hwifs[1].drives[1].drive_data = t; } else - printk("\nht6560b: not found\n"); + printk(KERN_ERR "ht6560b: not found\n"); } } diff --git a/drivers/block/ide-cd.h b/drivers/block/ide-cd.h index 8891205ed..1eb48ef6c 100644 --- a/drivers/block/ide-cd.h +++ b/drivers/block/ide-cd.h @@ -1,11 +1,11 @@ -#ifndef _IDE_CD_H -#define _IDE_CD_H /* * linux/drivers/block/ide_cd.h * - * Copyright (C) 1996, 1997, 1998 Erik Andersen - * Copyright (C) 1998, 1999 Jens Axboe + * Copyright (C) 1996-98 Erik Andersen + * Copyright (C) 1998-2000 Jens Axboe */ +#ifndef _IDE_CD_H +#define _IDE_CD_H #include <linux/cdrom.h> #include <asm/byteorder.h> diff --git a/drivers/block/ide-disk.c b/drivers/block/ide-disk.c index e62295241..f766605bc 100644 --- a/drivers/block/ide-disk.c +++ b/drivers/block/ide-disk.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-disk.c Version 1.09 April 23, 1999 + * linux/drivers/block/ide-disk.c Version 1.09 April 23, 1999 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ diff --git a/drivers/block/ide-dma.c b/drivers/block/ide-dma.c index 3b6f5e56a..751424831 100644 --- a/drivers/block/ide-dma.c +++ b/drivers/block/ide-dma.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-dma.c Version 4.09 April 23, 1999 + * 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 @@ -91,6 +91,8 @@ #include <asm/io.h> #include <asm/irq.h> +extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc); + #ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS struct drive_list_entry { @@ -401,6 +403,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); unsigned long dma_base = hwif->dma_base; + byte unit = (drive->select.b.unit & 0x01); unsigned int count, reading = 0; byte dma_stat; @@ -408,8 +411,11 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) case ide_dma_off: printk("%s: DMA disabled\n", drive->name); case ide_dma_off_quietly: + outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); case ide_dma_on: drive->using_dma = (func == ide_dma_on); + if (drive->using_dma) + outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); return 0; case ide_dma_check: return config_drive_for_dma (drive); @@ -424,7 +430,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);/* issue cmd to drive */ + ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); case ide_dma_begin: /* Note that this is done *after* the cmd has @@ -449,12 +455,10 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) return check_drive_lists(drive, (func == ide_dma_good_drive)); case ide_dma_lostirq: case ide_dma_timeout: - /* - * printk("ide_dmaproc: chipset supported func only: %d\n", func); - */ + printk("ide_dmaproc: chipset supported %s func only: %d\n", ide_dmafunc_verbose(func), func); return 1; default: - printk("ide_dmaproc: unsupported func: %d\n", func); + printk("ide_dmaproc: unsupported %s func: %d\n", ide_dmafunc_verbose(func), func); return 1; } } @@ -541,14 +545,15 @@ unsigned long __init ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const } } if (dma_base) { - if (extra) /* PDC20246, PDC20262, & HPT343 */ + if (extra) /* PDC20246, PDC20262, HPT343, & HPT366 */ request_region(dma_base+16, extra, name); dma_base += hwif->channel ? 8 : 0; hwif->dma_extra = extra; switch(dev->device) { - case PCI_DEVICE_ID_CMD_643: case PCI_DEVICE_ID_AL_M5219: + case PCI_DEVICE_ID_AMD_VIPER_7409: + case PCI_DEVICE_ID_CMD_643: outb(inb(dma_base+2) & 0x60, dma_base+2); if (inb(dma_base+2) & 0x80) { printk("%s: simplex device: DMA forced\n", name); diff --git a/drivers/block/ide-features.c b/drivers/block/ide-features.c index 87b7cacb4..3f29ed591 100644 --- a/drivers/block/ide-features.c +++ b/drivers/block/ide-features.c @@ -1,16 +1,15 @@ /* - * linux/drivers/block/ide-features.c + * linux/drivers/block/ide-features.c Version 0.03 Feb. 10, 2000 * - * Copyright (C) 1999 Linus Torvalds & authors (see below) + * Copyright (C) 1999-2000 Linus Torvalds & authors (see below) * - * Andre Hedrick <andre@suse.com> + * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com> * * Extracts if ide.c to address the evolving transfer rate code for - * the SETFEATURES_XFER callouts. Below are original authors of some or - * various parts of any given function below. + * the SETFEATURES_XFER callouts. Various parts of any given function + * are credited to previous ATA-IDE maintainers. * - * Mark Lord <mlord@pobox.com> - * Gadi Oxman <gadio@netvision.net.il> + * May be copied or modified under the terms of the GNU General Public License */ #define __NO_VERSION__ @@ -36,12 +35,15 @@ #include <asm/io.h> #include <asm/bitops.h> +#define SETFEATURES_CONTROL_REG (0) /* some arch's may need */ + /* - * + * A Verbose noise maker for debugging on the attempted transfer rates. */ char *ide_xfer_verbose (byte xfer_rate) { switch(xfer_rate) { + case XFER_UDMA_7: return("UDMA 7"); case XFER_UDMA_6: return("UDMA 6"); case XFER_UDMA_5: return("UDMA 5"); case XFER_UDMA_4: return("UDMA 4"); @@ -71,14 +73,42 @@ char *ide_xfer_verbose (byte xfer_rate) char *ide_media_verbose (ide_drive_t *drive) { switch (drive->media) { - case ide_disk: return("disk "); - case ide_cdrom: return("cdrom "); - case ide_tape: return("tape "); - case ide_floppy: return("floppy"); - default: return("??????"); + case ide_scsi: return("scsi "); + case ide_disk: return("disk "); + case ide_optical: return("optical"); + case ide_cdrom: return("cdrom "); + case ide_tape: return("tape "); + case ide_floppy: return("floppy "); + default: return("???????"); } } +/* + * A Verbose noise maker for debugging on the attempted dmaing calls. + */ +char *ide_dmafunc_verbose (ide_dma_action_t dmafunc) +{ + switch (dmafunc) { + case ide_dma_read: return("ide_dma_read"); + case ide_dma_write: return("ide_dma_write"); + case ide_dma_begin: return("ide_dma_begin"); + case ide_dma_end: return("ide_dma_end:"); + case ide_dma_check: return("ide_dma_check"); + case ide_dma_on: return("ide_dma_on"); + case ide_dma_off: return("ide_dma_off"); + case ide_dma_off_quietly: return("ide_dma_off_quietly"); + case ide_dma_test_irq: return("ide_dma_test_irq"); + case ide_dma_bad_drive: return("ide_dma_bad_drive"); + case ide_dma_good_drive: return("ide_dma_good_drive"); + case ide_dma_lostirq: return("ide_dma_lostirq"); + case ide_dma_timeout: return("ide_dma_timeout"); + default: return("unknown"); + } +} + +/* + * Update the + */ int ide_driveid_update (ide_drive_t *drive) { /* @@ -129,50 +159,6 @@ int ide_driveid_update (ide_drive_t *drive) } /* - * Similar to ide_wait_stat(), except it never calls ide_error internally. - * This is a kludge to handle the new ide_config_drive_speed() function, - * and should not otherwise be used anywhere. Eventually, the tuneproc's - * should be updated to return ide_startstop_t, in which case we can get - * rid of this abomination again. :) -ml - */ -int ide_wait_noerr (ide_drive_t *drive, byte good, byte bad, unsigned long timeout) -{ - byte stat; - int i; - unsigned long flags; - - udelay(1); /* spec allows drive 400ns to assert "BUSY" */ - if ((stat = GET_STAT()) & BUSY_STAT) { - __save_flags(flags); /* local CPU only */ - ide__sti(); /* local CPU only */ - timeout += jiffies; - while ((stat = GET_STAT()) & BUSY_STAT) { - if (0 < (signed long)(jiffies - timeout)) { - __restore_flags(flags); /* local CPU only */ - (void)ide_dump_status(drive, "ide_wait_noerr", stat); - return 1; - } - } - __restore_flags(flags); /* local CPU only */ - } - /* - * Allow status to settle, then read it again. - * A few rare drives vastly violate the 400ns spec here, - * so we'll wait up to 10usec for a "good" status - * rather than expensively fail things immediately. - * This fix courtesy of Matthew Faupel & Niccolo Rigacci. - */ - for (i = 0; i < 10; i++) { - udelay(1); - if (OK_STAT((stat = GET_STAT()), good, bad)) - return 0; - } - (void)ide_dump_status(drive, "ide_wait_noerr", stat); - return 1; -} - - -/* * Verify that we are doing an approved SETFEATURES_XFER with respect * to the hardware being able to support request. Since some hardware * can improperly report capabilties, we check to see if the host adapter @@ -213,70 +199,96 @@ int set_transfer (ide_drive_t *drive, int cmd, int nsect, int feature) return 0; } -#if 0 -ide_startstop_t set_drive_speed_intr (ide_drive_t *drive) -{ - byte stat; - - if (!OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) /* - * if (!OK_STAT(stat=GET_STAT(),DRIVE_READY,BAD_STAT)) - * if (stat != DRIVE_READY) + * Similar to ide_wait_stat(), except it never calls ide_error internally. + * This is a kludge to handle the new ide_config_drive_speed() function, + * and should not otherwise be used anywhere. Eventually, the tuneproc's + * should be updated to return ide_startstop_t, in which case we can get + * rid of this abomination again. :) -ml + * + * It is gone.......... + * + * const char *msg == consider adding for verbose errors. */ - (void) ide_dump_status(drive, "set_drive_speed_status", stat); - - return ide_stopped; -} -#endif - int ide_config_drive_speed (ide_drive_t *drive, byte speed) { - unsigned long flags; - int err; + ide_hwif_t *hwif = HWIF(drive); + int i, error = 1; + byte unit = (drive->select.b.unit & 0x01); byte stat; - __save_flags(flags); /* local CPU only */ - __cli(); /* local CPU only */ - /* * Don't use ide_wait_cmd here - it will * attempt to set_geometry and recalibrate, * but for some reason these don't work at * this point (lost interrupt). */ + /* + * Select the drive, and issue the SETFEATURES command + */ + disable_irq(hwif->irq); /* disable_irq_nosync ?? */ + udelay(1); SELECT_DRIVE(HWIF(drive), drive); + udelay(1); if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG); OUT_BYTE(speed, IDE_NSECTOR_REG); OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG); OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); - - err = ide_wait_noerr(drive, DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD); - -#if 0 - if (IDE_CONTROL_REG) + if ((IDE_CONTROL_REG) && (SETFEATURES_CONTROL_REG)) OUT_BYTE(drive->ctl, IDE_CONTROL_REG); -#endif + udelay(1); + /* + * Wait for drive to become non-BUSY + */ + if ((stat = GET_STAT()) & BUSY_STAT) { + unsigned long flags, timeout; + __save_flags(flags); /* local CPU only */ + ide__sti(); /* local CPU only -- for jiffies */ + timeout = jiffies + WAIT_CMD; + while ((stat = GET_STAT()) & BUSY_STAT) { + if (0 < (signed long)(jiffies - timeout)) + break; + } + __restore_flags(flags); /* local CPU only */ + } - __restore_flags(flags); /* local CPU only */ + /* + * Allow status to settle, then read it again. + * A few rare drives vastly violate the 400ns spec here, + * so we'll wait up to 10usec for a "good" status + * rather than expensively fail things immediately. + * This fix courtesy of Matthew Faupel & Niccolo Rigacci. + */ + for (i = 0; i < 10; i++) { + udelay(1); + if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) { + error = 0; + break; + } + } -#if 0 - ide_set_handler(drive, &set_drive_speed_intr, WAIT_CMD, NULL); -#endif + enable_irq(hwif->irq); - stat = GET_STAT(); - if (stat != DRIVE_READY) + if (error) { (void) ide_dump_status(drive, "set_drive_speed_status", stat); + return error; + } drive->id->dma_ultra &= ~0xFF00; drive->id->dma_mword &= ~0x0F00; drive->id->dma_1word &= ~0x0F00; + if (speed > XFER_PIO_4) { + outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2); + } else { + outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); + } + switch(speed) { -#if 0 - case XFER_UDMA_6: drive->id->dma_ultra |= 0x1010; break; - case XFER_UDMA_5: drive->id->dma_ultra |= 0x1010; break; -#endif + case XFER_UDMA_7: drive->id->dma_ultra |= 0x8080; break; + case XFER_UDMA_6: drive->id->dma_ultra |= 0x4040; break; + case XFER_UDMA_5: drive->id->dma_ultra |= 0x2020; break; case XFER_UDMA_4: drive->id->dma_ultra |= 0x1010; break; case XFER_UDMA_3: drive->id->dma_ultra |= 0x0808; break; case XFER_UDMA_2: drive->id->dma_ultra |= 0x0404; break; @@ -290,11 +302,10 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break; default: break; } - return(err); + return error; } EXPORT_SYMBOL(ide_driveid_update); -EXPORT_SYMBOL(ide_wait_noerr); EXPORT_SYMBOL(ide_ata66_check); EXPORT_SYMBOL(set_transfer); EXPORT_SYMBOL(ide_config_drive_speed); diff --git a/drivers/block/ide-floppy.c b/drivers/block/ide-floppy.c index e2977c754..bee6a4c6c 100644 --- a/drivers/block/ide-floppy.c +++ b/drivers/block/ide-floppy.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-floppy.c Version 0.9 Jul 4, 1999 + * linux/drivers/block/ide-floppy.c Version 0.9 Jul 4, 1999 * * Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il> */ @@ -1264,8 +1264,11 @@ static int idefloppy_get_capacity (ide_drive_t *drive) blocks = descriptor->blocks = ntohl (descriptor->blocks); length = descriptor->length = ntohs (descriptor->length); if (!i && descriptor->dc == CAPACITY_CURRENT) { - if (memcmp (descriptor, &floppy->capacity, sizeof (idefloppy_capacity_descriptor_t))) - printk (KERN_INFO "%s: %dkB, %d blocks, %d sector size\n", drive->name, blocks * length / 1024, blocks, length); + if (memcmp (descriptor, &floppy->capacity, sizeof (idefloppy_capacity_descriptor_t))) { + printk (KERN_INFO "%s: %dkB, %d blocks, %d sector size, %s \n", + drive->name, blocks * length / 1024, blocks, length, + drive->using_dma ? ", DMA":""); + } floppy->capacity = *descriptor; if (!length || length % 512) printk (KERN_ERR "%s: %d bytes block size not supported\n", drive->name, length); diff --git a/drivers/block/ide-pci.c b/drivers/block/ide-pci.c index a5593dffb..2ddbbc8bd 100644 --- a/drivers/block/ide-pci.c +++ b/drivers/block/ide-pci.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-pci.c Version 1.04 July 27, 1999 + * linux/drivers/block/ide-pci.c Version 1.04 July 27, 1999 * * Copyright (c) 1998-1999 Andre Hedrick * @@ -31,6 +31,7 @@ #define DEVID_PIIX4 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB}) #define DEVID_PIIX4E ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1}) #define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1}) +#define DEVID_PIIX4U2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1}) #define DEVID_VIA_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561}) #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}) @@ -95,13 +96,19 @@ extern void ide_dmacapable_ali15x3(ide_hwif_t *, unsigned long); #endif #ifdef CONFIG_BLK_DEV_AMD7409 +extern unsigned int pci_init_amd7409(struct pci_dev *, const char *); extern unsigned int ata66_amd7409(ide_hwif_t *); extern void ide_init_amd7409(ide_hwif_t *); +extern void ide_dmacapable_amd7409(ide_hwif_t *, unsigned long); +#define PCI_AMD7409 &pci_init_amd7409 #define ATA66_AMD7409 &ata66_amd7409 #define INIT_AMD7409 &ide_init_amd7409 +#define DMA_AMD7409 &ide_dmacapable_amd7409 #else +#define PCI_AMD7409 NULL #define ATA66_AMD7409 NULL #define INIT_AMD7409 NULL +#define DMA_AMD7409 NULL #endif #ifdef CONFIG_BLK_DEV_CMD64X @@ -135,11 +142,11 @@ extern void ide_init_cy82c693(ide_hwif_t *); #ifdef CONFIG_BLK_DEV_CS5530 extern unsigned int pci_init_cs5530(struct pci_dev *, const char *); extern void ide_init_cs5530(ide_hwif_t *); -#define INIT_CS5530 &ide_init_cs5530 #define PCI_CS5530 &pci_init_cs5530 +#define INIT_CS5530 &ide_init_cs5530 #else -#define INIT_CS5530 NULL #define PCI_CS5530 NULL +#define INIT_CS5530 NULL #endif #ifdef CONFIG_BLK_DEV_HPT34X @@ -149,7 +156,7 @@ extern void ide_init_hpt34x(ide_hwif_t *); #define INIT_HPT34X &ide_init_hpt34x #else #define PCI_HPT34X NULL -#define INIT_HPT34X NULL +#define INIT_HPT34X IDE_IGNORE #endif #ifdef CONFIG_BLK_DEV_HPT366 @@ -289,6 +296,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_PIIX4, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4E, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4U, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_PIIX4U2, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_VP_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 }, @@ -318,7 +326,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_CY82C693,"CY82C693", PCI_CY82C693, NULL, INIT_CY82C693, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_HINT, "HINT_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_CS5530, "CS5530", PCI_CS5530, NULL, INIT_CS5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, - {DEVID_AMD7409, "AMD7409", NULL, ATA66_AMD7409, INIT_AMD7409, NULL, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, + {DEVID_AMD7409, "AMD7409", PCI_AMD7409, ATA66_AMD7409, INIT_AMD7409, DMA_AMD7409, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }}; /* @@ -329,27 +337,6 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { static unsigned int __init ide_special_settings (struct pci_dev *dev, const char *name) { switch(dev->device) { - case PCI_DEVICE_ID_TTI_HPT343: - { - int i; - unsigned long hpt34xIoBase = dev->resource[4].start; - unsigned short pcicmd = 0; - - pci_write_config_byte(dev, 0x80, 0x00); - pci_read_config_word(dev, PCI_COMMAND, &pcicmd); - if (!(pcicmd & PCI_COMMAND_MEMORY)) { - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); - } else { - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); - } - - dev->resource[0].start = (hpt34xIoBase + 0x20); - dev->resource[1].start = (hpt34xIoBase + 0x34); - dev->resource[2].start = (hpt34xIoBase + 0x28); - dev->resource[3].start = (hpt34xIoBase + 0x3c); - for(i=0; i<4; i++) - dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; - } case PCI_DEVICE_ID_TTI_HPT366: case PCI_DEVICE_ID_PROMISE_20246: case PCI_DEVICE_ID_PROMISE_20262: @@ -535,17 +522,8 @@ check_if_enabled: #endif } if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) { - /* - * 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; - } + /* see comments in hpt34x.c on why..... */ + d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD; } /* * Set up the IDE ports @@ -618,9 +596,7 @@ check_if_enabled: 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_HPT34X IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) || -#endif /* CONFIG_BLK_DEV_HPT34X */ IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) || diff --git a/drivers/block/ide-probe.c b/drivers/block/ide-probe.c index b57fa28da..24eef80b7 100644 --- a/drivers/block/ide-probe.c +++ b/drivers/block/ide-probe.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-probe.c Version 1.05 July 3, 1999 + * linux/drivers/block/ide-probe.c Version 1.05 July 3, 1999 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ @@ -57,7 +57,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ide__sti(); /* local CPU only */ ide_fix_driveid(id); if (!drive->forced_lun) - drive->last_lun = id->word126 & 0x7; + drive->last_lun = id->last_lun & 0x7; #if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA) /* * EATA SCSI controllers do a hardware ATA emulation: @@ -395,6 +395,56 @@ static inline byte probe_for_drive (ide_drive_t *drive) } /* + * Calculate the region that this interface occupies, + * handling interfaces where the registers may not be + * ordered sanely. We deal with the CONTROL register + * separately. + */ +static int hwif_check_regions (ide_hwif_t *hwif) +{ + int region_errors = 0; + + region_errors = ide_check_region(hwif->io_ports[IDE_DATA_OFFSET], 1); + region_errors += ide_check_region(hwif->io_ports[IDE_ERROR_OFFSET], 1); + region_errors += ide_check_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1); + region_errors += ide_check_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1); + region_errors += ide_check_region(hwif->io_ports[IDE_LCYL_OFFSET], 1); + region_errors += ide_check_region(hwif->io_ports[IDE_HCYL_OFFSET], 1); + region_errors += ide_check_region(hwif->io_ports[IDE_SELECT_OFFSET], 1); + region_errors += ide_check_region(hwif->io_ports[IDE_STATUS_OFFSET], 1); + if (hwif->io_ports[IDE_CONTROL_OFFSET]) + region_errors += ide_check_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1); + if (hwif->io_ports[IDE_IRQ_OFFSET]) + region_errors += ide_check_region(hwif->io_ports[IDE_IRQ_OFFSET], 1); + + return(region_errors); +} + +static void hwif_register (ide_hwif_t *hwif) +{ + if (hwif->io_ports[IDE_DATA_OFFSET]) + ide_request_region(hwif->io_ports[IDE_DATA_OFFSET], 1, hwif->name); + if (hwif->io_ports[IDE_ERROR_OFFSET]) + ide_request_region(hwif->io_ports[IDE_ERROR_OFFSET], 1, hwif->name); + if (hwif->io_ports[IDE_NSECTOR_OFFSET]) + ide_request_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1, hwif->name); + if (hwif->io_ports[IDE_SECTOR_OFFSET]) + ide_request_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1, hwif->name); + if (hwif->io_ports[IDE_LCYL_OFFSET]) + ide_request_region(hwif->io_ports[IDE_LCYL_OFFSET], 1, hwif->name); + if (hwif->io_ports[IDE_HCYL_OFFSET]) + ide_request_region(hwif->io_ports[IDE_HCYL_OFFSET], 1, hwif->name); + if (hwif->io_ports[IDE_SELECT_OFFSET]) + ide_request_region(hwif->io_ports[IDE_SELECT_OFFSET], 1, hwif->name); + if (hwif->io_ports[IDE_STATUS_OFFSET]) + ide_request_region(hwif->io_ports[IDE_STATUS_OFFSET], 1, hwif->name); + if (hwif->io_ports[IDE_CONTROL_OFFSET]) + ide_request_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1, hwif->name); + if (hwif->io_ports[IDE_IRQ_OFFSET]) + ide_request_region(hwif->io_ports[IDE_IRQ_OFFSET], 1, hwif->name); +} + +/* * This routine only knows how to look for drive units 0 and 1 * on an interface, so any setting of MAX_DRIVES > 2 won't work here. */ @@ -403,12 +453,6 @@ static void probe_hwif (ide_hwif_t *hwif) 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; - unsigned int region_request = 8; - int i; - if (hwif->noprobe) return; if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) { @@ -417,30 +461,11 @@ static void probe_hwif (ide_hwif_t *hwif) probe_cmos_for_drives (hwif); } - /* - * 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) && #endif /* CONFIG_BLK_DEV_PDC4030 */ - (ide_check_region(region_low, region_request) || - (ide_control_reg && ide_check_region(ide_control_reg,1)))) - { + (hwif_check_regions(hwif))) { int msgout = 0; for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; @@ -467,20 +492,18 @@ static void probe_hwif (ide_hwif_t *hwif) if (drive->present && !hwif->present) { hwif->present = 1; if (hwif->chipset != ide_4drives || !hwif->mate->present) { - ide_request_region(region_low, region_request, hwif->name); - if (ide_control_reg) - ide_request_region(ide_control_reg, 1, hwif->name); + hwif_register(hwif); } } } - if (ide_control_reg && hwif->reset) { + if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { unsigned long timeout = jiffies + WAIT_WORSTCASE; byte stat; printk("%s: reset\n", hwif->name); - OUT_BYTE(12, ide_control_reg); + OUT_BYTE(12, hwif->io_ports[IDE_CONTROL_OFFSET]); udelay(10); - OUT_BYTE(8, ide_control_reg); + OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]); do { ide_delay_50ms(); stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); @@ -594,7 +617,11 @@ static int init_irq (ide_hwif_t *hwif) * Allocate the irq, if not already obtained for another hwif */ if (!match || match->irq != hwif->irq) { +#ifdef CONFIG_IDEPCI_SHARE_IRQ + int sa = (hwif->chipset == ide_pci) ? SA_SHIRQ : SA_INTERRUPT; +#else /* !CONFIG_IDEPCI_SHARE_IRQ */ int sa = (hwif->chipset == ide_pci) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT; +#endif /* CONFIG_IDEPCI_SHARE_IRQ */ if (ide_request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwgroup)) { if (!match) kfree(hwgroup); @@ -784,20 +811,18 @@ static int hwif_init (ide_hwif_t *hwif) return (hwif->present = 0); } - if (init_irq (hwif)) { + if (init_irq(hwif)) { int i = hwif->irq; /* * It failed to initialise. Find the default IRQ for * this port and try that. */ - 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 unable to get IRQ %d.\n", hwif->name, i); (void) unregister_blkdev (hwif->major, hwif->name); return (hwif->present = 0); } - if(init_irq (hwif)) - { + if (init_irq(hwif)) { printk("%s: probed IRQ %d and default IRQ %d failed.\n", hwif->name, i, hwif->irq); (void) unregister_blkdev (hwif->major, hwif->name); @@ -863,7 +888,8 @@ int ideprobe_init (void) for (index = 0; index < MAX_HWIFS; ++index) if (probe[index]) hwif_init(&ide_hwifs[index]); - ide_register_module(&ideprobe_module); + if (!ide_probe) + ide_probe = &ideprobe_module; MOD_DEC_USE_COUNT; return 0; } @@ -882,6 +908,6 @@ int init_module (void) void cleanup_module (void) { - ide_unregister_module(&ideprobe_module); + ide_probe = NULL; } #endif /* MODULE */ diff --git a/drivers/block/ide-proc.c b/drivers/block/ide-proc.c index 66e45001c..90977c959 100644 --- a/drivers/block/ide-proc.c +++ b/drivers/block/ide-proc.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-proc.c Version 1.03 January 2, 1998 + * linux/drivers/block/ide-proc.c Version 1.03 January 2, 1998 * * Copyright (C) 1997-1998 Mark Lord */ @@ -73,21 +73,46 @@ #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif +#ifdef CONFIG_BLK_DEV_AEC6210 +extern byte aec6210_proc; +int (*aec6210_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_AEC6210 */ #ifdef CONFIG_BLK_DEV_ALI15X3 extern byte ali_proc; int (*ali_display_info)(char *, char **, off_t, int) = NULL; #endif /* CONFIG_BLK_DEV_ALI15X3 */ - +#ifdef CONFIG_BLK_DEV_AMD7409 +extern byte amd7409_proc; +int (*amd7409_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_AMD7409 */ +#ifdef CONFIG_BLK_DEV_CMD64X +extern byte cmd64x_proc; +int (*cmd64x_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_CMD64X */ +#ifdef CONFIG_BLK_DEV_CS5530 +extern byte cs5530_proc; +int (*cs5530_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_CS5530 */ +#ifdef CONFIG_BLK_DEV_HPT34X +extern byte hpt34x_proc; +int (*hpt34x_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_HPT34X */ +#ifdef CONFIG_BLK_DEV_HPT366 +extern byte hpt366_proc; +int (*hpt366_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_HPT366 */ +#ifdef CONFIG_BLK_DEV_PDC202XX +extern byte pdc202xx_proc; +int (*pdc202xx_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_PDC202XX */ #ifdef CONFIG_BLK_DEV_PIIX extern byte piix_proc; int (*piix_display_info)(char *, char **, off_t, int) = NULL; #endif /* CONFIG_BLK_DEV_PIIX */ - #ifdef CONFIG_BLK_DEV_SIS5513 extern byte sis_proc; int (*sis_display_info)(char *, char **, off_t, int) = NULL; #endif /* CONFIG_BLK_DEV_SIS5513 */ - #ifdef CONFIG_BLK_DEV_VIA82CXXX extern byte via_proc; int (*via_display_info)(char *, char **, off_t, int) = NULL; @@ -229,7 +254,7 @@ static int proc_ide_write_config #endif /* CONFIG_BLK_DEV_IDEPCI */ if (for_real) { #if 0 - printk("proc_ide_write_config: type=%c, reg=0x%x, val=0x%x, digits=%d\n", is_pci ? 'PCI' : 'non-PCI', reg, val, digits); + printk("proc_ide_write_config: type=%c, reg=0x%x, val=0x%x, digits=%d\n", is_pci ? "PCI" : "non-PCI", reg, val, digits); #endif if (is_pci) { #ifdef CONFIG_BLK_DEV_IDEPCI @@ -349,7 +374,7 @@ static int proc_ide_read_drivers while (p) { driver = (ide_driver_t *) p->info; - if (p->type == IDE_DRIVER_MODULE && driver) + if (driver) out += sprintf(out, "%s version %s\n", driver->name, driver->version); p = p->next; } @@ -775,10 +800,38 @@ void proc_ide_create(void) create_proc_read_entry("drivers",0,proc_ide_root, proc_ide_read_drivers, NULL); +#ifdef CONFIG_BLK_DEV_AEC6210 + if ((aec6210_display_info) && (aec6210_proc)) + create_proc_info_entry("aec6210", 0, proc_ide_root, aec6210_display_info); +#endif /* CONFIG_BLK_DEV_AEC6210 */ #ifdef CONFIG_BLK_DEV_ALI15X3 if ((ali_display_info) && (ali_proc)) create_proc_info_entry("ali", 0, proc_ide_root, ali_display_info); #endif /* CONFIG_BLK_DEV_ALI15X3 */ +#ifdef CONFIG_BLK_DEV_AMD7409 + if ((amd7409_display_info) && (amd7409_proc)) + create_proc_info_entry("amd7409", 0, proc_ide_root, amd7409_display_info); +#endif /* CONFIG_BLK_DEV_AMD7409 */ +#ifdef CONFIG_BLK_DEV_CMD64X + if ((cmd64x_display_info) && (cmd64x_proc)) + create_proc_info_entry("cmd64x", 0, proc_ide_root, cmd64x_display_info); +#endif /* CONFIG_BLK_DEV_CMD64X */ +#ifdef CONFIG_BLK_DEV_CS5530 + if ((cs5530_display_info) && (cs5530_proc)) + create_proc_info_entry("cs5530", 0, proc_ide_root, cs5530_display_info); +#endif /* CONFIG_BLK_DEV_CS5530 */ +#ifdef CONFIG_BLK_DEV_HPT34X + if ((hpt34x_display_info) && (hpt34x_proc)) + create_proc_info_entry("", 0, proc_ide_root, hpt34x_display_info); +#endif /* CONFIG_BLK_DEV_HPT34X */ +#ifdef CONFIG_BLK_DEV_HPT366 + if ((hpt366_display_info) && (hpt366_proc)) + create_proc_info_entry("", 0, proc_ide_root, hpt366_display_info); +#endif /* CONFIG_BLK_DEV_HPT366 */ +#ifdef CONFIG_BLK_DEV_PDC202XX + if ((pdc202xx_display_info) && (pdc202xx_proc)) + create_proc_info_entry("pdc202xx", 0, proc_ide_root, pdc202xx_display_info); +#endif /* CONFIG_BLK_DEV_PDC202XX */ #ifdef CONFIG_BLK_DEV_PIIX if ((piix_display_info) && (piix_proc)) create_proc_info_entry("piix", 0, proc_ide_root, piix_display_info); @@ -799,10 +852,38 @@ void proc_ide_destroy(void) * Mmmm.. does this free up all resources, * or do we need to do a more proper cleanup here ?? */ +#ifdef CONFIG_BLK_DEV_AEC6210 + if ((aec6210_display_info) && (aec6210_proc)) + remove_proc_entry("ide/aec6210",0); +#endif /* CONFIG_BLK_DEV_AEC6210 */ #ifdef CONFIG_BLK_DEV_ALI15X3 if ((ali_display_info) && (ali_proc)) remove_proc_entry("ide/ali",0); #endif /* CONFIG_BLK_DEV_ALI15X3 */ +#ifdef CONFIG_BLK_DEV_AMD7409 + if ((amd7409_display_info) && (amd7409_proc)) + remove_proc_entry("ide/amd7409",0); +#endif /* CONFIG_BLK_DEV_AMD7409 */ +#ifdef CONFIG_BLK_DEV_CMD64X + if ((cmd64x_display_info) && (cmd64x_proc)) + remove_proc_entry("ide/cmd64x",0); +#endif /* CONFIG_BLK_DEV_CMD64X */ +#ifdef CONFIG_BLK_DEV_CS5530 + if ((cs5530_display_info) && (cs5530_proc)) + remove_proc_entry("ide/cs5530",0); +#endif /* CONFIG_BLK_DEV_CS5530 */ +#ifdef CONFIG_BLK_DEV_HPT34X + if ((hpt34x_display_info) && (hpt34x_proc)) + remove_proc_entry("ide/hpt34x",0); +#endif /* CONFIG_BLK_DEV_HPT34X */ +#ifdef CONFIG_BLK_DEV_HPT366 + if ((hpt366_display_info) && (hpt366_proc)) + remove_proc_entry("ide/hpt366",0); +#endif /* CONFIG_BLK_DEV_HPT366 */ +#ifdef CONFIG_BLK_DEV_PDC202XX + if ((pdc202xx_display_info) && (pdc202xx_proc)) + remove_proc_entry("ide/pdc202xx",0); +#endif /* CONFIG_BLK_DEV_PDC202XX */ #ifdef CONFIG_BLK_DEV_PIIX if ((piix_display_info) && (piix_proc)) remove_proc_entry("ide/piix",0); diff --git a/drivers/block/ide-tape.c b/drivers/block/ide-tape.c index 1e1b6e44e..95e780abf 100644 --- a/drivers/block/ide-tape.c +++ b/drivers/block/ide-tape.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-tape.c Version 1.16f Dec 15, 1999 + * linux/drivers/block/ide-tape.c Version 1.16f Dec 15, 1999 * * Copyright (C) 1995 - 1999 Gadi Oxman <gadio@netvision.net.il> * @@ -411,12 +411,12 @@ #include <asm/bitops.h> -#define NO_LONGER_REQUIRE (1) +#define NO_LONGER_REQUIRED (1) /* * OnStream support */ -#define ONSTREAM_DEBUG (1) +#define ONSTREAM_DEBUG (0) #define OS_CONFIG_PARTITION (0xff) #define OS_DATA_PARTITION (0) #define OS_PARTITION_VERSION (1) @@ -543,6 +543,7 @@ typedef struct os_header_s { /* * The following are used to debug the driver: * + * Setting IDETAPE_DEBUG_INFO to 1 will report device capabilities. * 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. @@ -557,7 +558,9 @@ typedef struct os_header_s { * is verified to be stable enough. This will make it much more * esthetic. */ +#define IDETAPE_DEBUG_INFO 0 #define IDETAPE_DEBUG_LOG 1 +#define IDETAPE_DEBUG_LOG_VERBOSE 0 #define IDETAPE_DEBUG_BUGS 1 /* @@ -700,9 +703,10 @@ typedef struct idetape_packet_command_s { */ typedef struct { unsigned page_code :6; /* Page code - Should be 0x2a */ - unsigned reserved1_67 :2; - u8 page_length; /* Page Length - Should be 0x12 */ - u8 reserved2, reserved3; + __u8 reserved0_6 :1; + __u8 ps :1; /* parameters saveable */ + __u8 page_length; /* Page Length - Should be 0x12 */ + __u8 reserved2, reserved3; unsigned ro :1; /* Read Only Mode */ unsigned reserved4_1234 :4; unsigned sprev :1; /* Supports SPACE in the reverse direction */ @@ -716,7 +720,8 @@ typedef struct { unsigned locked :1; /* The volume is locked */ unsigned prevent :1; /* The device defaults in the prevent state after power up */ unsigned eject :1; /* The device can eject the volume */ - unsigned reserved6_45 :2; /* Reserved */ + __u8 disconnect :1; /* The device can break request > ctl */ + __u8 reserved6_5 :1; unsigned ecc :1; /* Supports error correction */ unsigned cmprs :1; /* Supports data compression */ unsigned reserved7_0 :1; @@ -726,12 +731,12 @@ typedef struct { unsigned blk32768 :1; /* slowb - the device restricts the byte count for PIO */ /* transfers for slow buffer memory ??? */ /* Also 32768 block size in some cases */ - u16 max_speed; /* Maximum speed supported in KBps */ - u8 reserved10, reserved11; - u16 ctl; /* Continuous Transfer Limit in blocks */ - u16 speed; /* Current Speed, in KBps */ - u16 buffer_size; /* Buffer Size, in 512 bytes */ - u8 reserved18, reserved19; + __u16 max_speed; /* Maximum speed supported in KBps */ + __u8 reserved10, reserved11; + __u16 ctl; /* Continuous Transfer Limit in blocks */ + __u16 speed; /* Current Speed, in KBps */ + __u16 buffer_size; /* Buffer Size, in 512 bytes */ + __u8 reserved18, reserved19; } idetape_capabilities_page_t; /* @@ -741,8 +746,8 @@ typedef struct { unsigned page_code :6; /* Page code - Should be 0x30 */ unsigned reserved1_6 :1; unsigned ps :1; - u8 page_length; /* Page Length - Should be 2 */ - u8 reserved2; + __u8 page_length; /* Page Length - Should be 2 */ + __u8 reserved2; unsigned play32 :1; unsigned play32_5 :1; unsigned reserved2_23 :2; @@ -768,23 +773,23 @@ typedef struct idetape_stage_s { typedef struct { unsigned error_code :7; /* Current of deferred errors */ unsigned valid :1; /* The information field conforms to QIC-157C */ - u8 reserved1 :8; /* Segment Number - Reserved */ + __u8 reserved1 :8; /* Segment Number - Reserved */ unsigned sense_key :4; /* Sense Key */ unsigned reserved2_4 :1; /* Reserved */ unsigned ili :1; /* Incorrect Length Indicator */ unsigned eom :1; /* End Of Medium */ unsigned filemark :1; /* Filemark */ - u32 information __attribute__ ((packed)); - u8 asl; /* Additional sense length (n-7) */ - u32 command_specific; /* Additional command specific information */ - u8 asc; /* Additional Sense Code */ - u8 ascq; /* Additional Sense Code Qualifier */ - u8 replaceable_unit_code; /* Field Replaceable Unit Code */ + __u32 information __attribute__ ((packed)); + __u8 asl; /* Additional sense length (n-7) */ + __u32 command_specific; /* Additional command specific information */ + __u8 asc; /* Additional Sense Code */ + __u8 ascq; /* Additional Sense Code Qualifier */ + __u8 replaceable_unit_code; /* Field Replaceable Unit Code */ unsigned sk_specific1 :7; /* Sense Key Specific */ unsigned sksv :1; /* Sense Key Specific information is valid */ - u8 sk_specific2; /* Sense Key Specific */ - u8 sk_specific3; /* Sense Key Specific */ - u8 pad[2]; /* Padding to 20 bytes */ + __u8 sk_specific2; /* Sense Key Specific */ + __u8 sk_specific3; /* Sense Key Specific */ + __u8 pad[2]; /* Padding to 20 bytes */ } idetape_request_sense_result_t; @@ -1247,13 +1252,13 @@ typedef struct { unsigned reserved3_45 :2; /* Reserved */ unsigned reserved3_6 :1; /* TrmIOP - Reserved */ unsigned reserved3_7 :1; /* AENC - Reserved */ - u8 additional_length; /* Additional Length (total_length-4) */ - u8 rsv5, rsv6, rsv7; /* Reserved */ - u8 vendor_id[8]; /* Vendor Identification */ - u8 product_id[16]; /* Product Identification */ - u8 revision_level[4]; /* Revision Level */ - u8 vendor_specific[20]; /* Vendor Specific - Optional */ - u8 reserved56t95[40]; /* Reserved - Optional */ + __u8 additional_length; /* Additional Length (total_length-4) */ + __u8 rsv5, rsv6, rsv7; /* Reserved */ + __u8 vendor_id[8]; /* Vendor Identification */ + __u8 product_id[16]; /* Product Identification */ + __u8 revision_level[4]; /* Revision Level */ + __u8 vendor_specific[20]; /* Vendor Specific - Optional */ + __u8 reserved56t95[40]; /* Reserved - Optional */ /* Additional information may be returned */ } idetape_inquiry_result_t; @@ -1287,10 +1292,25 @@ typedef struct { * Mode Parameter Header for the MODE SENSE packet command */ typedef struct { - u8 mode_data_length; /* Length of the following data transfer */ - u8 medium_type; /* Medium Type */ - u8 dsp; /* Device Specific Parameter */ - u8 bdl; /* Block Descriptor Length */ + __u8 mode_data_length; /* Length of the following data transfer */ + __u8 medium_type; /* Medium Type */ + __u8 dsp; /* Device Specific Parameter */ + __u8 bdl; /* Block Descriptor Length */ +#if 0 + /* data transfer page */ + __u8 page_code :6; + __u8 reserved0_6 :1; + __u8 ps :1; /* parameters saveable */ + __u8 page_length; /* page Length == 0x02 */ + __u8 reserved2; + __u8 read32k :1; /* 32k blk size (data only) */ + __u8 read32k5 :1; /* 32.5k blk size (data&AUX) */ + __u8 reserved3_23 :2; + __u8 write32k :1; /* 32k blk size (data only) */ + __u8 write32k5 :1; /* 32.5k blk size (data&AUX) */ + __u8 reserved3_6 :1; + __u8 streaming :1; /* streaming mode enable */ +#endif } idetape_mode_parameter_header_t; /* @@ -1299,10 +1319,10 @@ typedef struct { * Support for block descriptors is optional. */ typedef struct { - u8 density_code; /* Medium density code */ - u8 blocks[3]; /* Number of blocks */ - u8 reserved4; /* Reserved */ - u8 length[3]; /* Block Length */ + __u8 density_code; /* Medium density code */ + __u8 blocks[3]; /* Number of blocks */ + __u8 reserved4; /* Reserved */ + __u8 length[3]; /* Block Length */ } idetape_parameter_block_descriptor_t; /* @@ -1312,16 +1332,16 @@ typedef struct { unsigned page_code :6; /* Page Code - Should be 0xf */ unsigned reserved0 :1; /* Reserved */ unsigned ps :1; - u8 page_length; /* Page Length - Should be 14 */ + __u8 page_length; /* Page Length - Should be 14 */ unsigned reserved2 :6; /* Reserved */ unsigned dcc :1; /* Data Compression Capable */ unsigned dce :1; /* Data Compression Enable */ unsigned reserved3 :5; /* Reserved */ unsigned red :2; /* Report Exception on Decompression */ unsigned dde :1; /* Data Decompression Enable */ - u32 ca; /* Compression Algorithm */ - u32 da; /* Decompression Algorithm */ - u8 reserved[4]; /* Reserved */ + __u32 ca; /* Compression Algorithm */ + __u32 da; /* Decompression Algorithm */ + __u8 reserved[4]; /* Reserved */ } idetape_data_compression_page_t; /* @@ -1331,16 +1351,16 @@ typedef struct { unsigned page_code :6; /* Page Code - Should be 0x11 */ unsigned reserved1_6 :1; /* Reserved */ unsigned ps :1; - u8 page_length; /* Page Length - Should be 6 */ - u8 map; /* Maximum Additional Partitions - Should be 0 */ - u8 apd; /* Additional Partitions Defined - Should be 0 */ + __u8 page_length; /* Page Length - Should be 6 */ + __u8 map; /* Maximum Additional Partitions - Should be 0 */ + __u8 apd; /* Additional Partitions Defined - Should be 0 */ unsigned reserved4_012 :3; /* Reserved */ unsigned psum :2; /* Should be 0 */ unsigned idp :1; /* Should be 0 */ unsigned sdp :1; /* Should be 0 */ unsigned fdp :1; /* Fixed Data Partitions */ - u8 mfr; /* Medium Format Recognition */ - u8 reserved[2]; /* Reserved */ + __u8 mfr; /* Medium Format Recognition */ + __u8 reserved[2]; /* Reserved */ } idetape_medium_partition_page_t; /* @@ -1359,6 +1379,53 @@ typedef struct { static idetape_chrdev_t idetape_chrdevs[MAX_HWIFS * MAX_DRIVES]; static int idetape_chrdev_present = 0; +#if IDETAPE_DEBUG_LOG_VERBOSE + +/* + * DO NOT REMOVE, BUILDING A VERBOSE DEBUG SCHEME FOR ATAPI + */ + +char *idetape_sense_key_verbose (byte idetape_sense_key) +{ + switch (idetape_sense_key) { + default: { + char buf[22]; + sprintf(buf, "IDETAPE_SENSE (0x%02x)", idetape_sense_key); + return(buf); + } + + } +} + +char *idetape_command_key_verbose (byte idetape_command_key) +{ + switch (idetape_command_key) { + case IDETAPE_TEST_UNIT_READY_CMD: return("TEST_UNIT_READY_CMD"); + case IDETAPE_REWIND_CMD: return("REWIND_CMD"); + case IDETAPE_REQUEST_SENSE_CMD: return("REQUEST_SENSE_CMD"); + case IDETAPE_READ_CMD: return("READ_CMD"); + case IDETAPE_WRITE_CMD: return("WRITE_CMD"); + case IDETAPE_WRITE_FILEMARK_CMD: return("WRITE_FILEMARK_CMD"); + case IDETAPE_SPACE_CMD: return("SPACE_CMD"); + case IDETAPE_INQUIRY_CMD: return("INQUIRY_CMD"); + case IDETAPE_ERASE_CMD: return("ERASE_CMD") + case IDETAPE_MODE_SENSE_CMD: return("MODE_SENSE_CMD"); + case IDETAPE_MODE_SELECT_CMD: return("MODE_SELECT_CMD"); + case IDETAPE_LOAD_UNLOAD_CMD: return("LOAD_UNLOAD_CMD"); + case IDETAPE_PREVENT_CMD: return("PREVENT_CMD"); + case IDETAPE_LOCATE_CMD: return("LOCATE_CMD"); + case IDETAPE_READ_POSITION_CMD: return("READ_POSITION_CMD"); + case IDETAPE_READ_BUFFER_CMD: return("READ_BUFFER_CMD"); + case IDETAPE_SET_SPEED_CMD: return("SET_SPEED_CMD"); + default: { + char buf[20]; + sprintf(buf, "CMD (0x%02x)", idetape_command_key); + return(buf); + } + } +} +#endif /* IDETAPE_DEBUG_LOG_VERBOSE */ + /* * Too bad. The drive wants to send us data which we are not ready to accept. * Just throw it away. @@ -1523,6 +1590,14 @@ static void idetape_analyze_error (ide_drive_t *drive,idetape_request_sense_resu */ if (tape->debug_level >= 1) printk (KERN_INFO "ide-tape: pc = %x, sense key = %x, asc = %x, ascq = %x\n",pc->c[0],result->sense_key,result->asc,result->ascq); +#if IDETAPE_DEBUG_LOG_VERBOSE + if (tape->debug_level >= 1) + printk (KERN_INFO "ide-tape: pc = %s, sense key = %x, asc = %x, ascq = %x\n", + idetape_command_key_verbose((byte) pc->c[0]), + result->sense_key, + result->asc, + result->ascq); +#endif /* IDETAPE_DEBUG_LOG_VERBOSE */ #endif /* IDETAPE_DEBUG_LOG */ if (tape->onstream && result->sense_key == 2 && result->asc == 0x53 && result->ascq == 2) { @@ -3833,7 +3908,7 @@ static int idetape_get_logical_blk (ide_drive_t *drive, int logical_blk_num, int if (tape->onstream) { #if ONSTREAM_DEBUG if (tape->debug_level >= 1) - printk(KERN_INFO "ide-tape: %s: first_stage == NULL, pipeline error %d\n", tape->name, test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags)); + printk(KERN_INFO "ide-tape: %s: first_stage == NULL, pipeline error %ld\n", tape->name, (long)test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags)); #endif clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); position = idetape_read_position(drive); @@ -5280,16 +5355,16 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp) static int idetape_identify_device (ide_drive_t *drive,struct hd_driveid *id) { struct idetape_id_gcw gcw; -#if IDETAPE_DEBUG_LOG +#if IDETAPE_DEBUG_INFO unsigned short mask,i; -#endif /* IDETAPE_DEBUG_LOG */ +#endif /* IDETAPE_DEBUG_INFO */ if (!id) return 0; *((unsigned short *) &gcw) = id->config; -#if IDETAPE_DEBUG_LOG +#if IDETAPE_DEBUG_INFO printk (KERN_INFO "ide-tape: Dumping ATAPI Identify Device tape parameters\n"); printk (KERN_INFO "ide-tape: Protocol Type: "); switch (gcw.protocol) { @@ -5377,7 +5452,7 @@ static int idetape_identify_device (ide_drive_t *drive,struct hd_driveid *id) } else printk (KERN_INFO "ide-tape: According to the device, fields 64-70 are not valid.\n"); -#endif /* IDETAPE_DEBUG_LOG */ +#endif /* IDETAPE_DEBUG_INFO */ /* Check that we can support this device */ @@ -5462,12 +5537,12 @@ static void idetape_onstream_configure_block_size (ide_drive_t *drive) header = (idetape_mode_parameter_header_t *) pc.buffer; bs = (idetape_block_size_page_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t) + header->bdl); -#if IDETAPE_DEBUG_LOG +#if IDETAPE_DEBUG_INFO printk(KERN_INFO "ide-tape: 32KB play back: %s\n", bs->play32 ? "Yes" : "No"); printk(KERN_INFO "ide-tape: 32.5KB play back: %s\n", bs->play32_5 ? "Yes" : "No"); printk(KERN_INFO "ide-tape: 32KB record: %s\n", bs->record32 ? "Yes" : "No"); printk(KERN_INFO "ide-tape: 32.5KB record: %s\n", bs->record32_5 ? "Yes" : "No"); -#endif +#endif /* IDETAPE_DEBUG_INFO */ /* * Configure default auto columns mode, 32.5KB block size @@ -5587,7 +5662,7 @@ static void idetape_get_mode_sense_results (ide_drive_t *drive) else if (tape->onstream && capabilities->blk32768) tape->tape_block_size = 32768; -#if IDETAPE_DEBUG_LOG +#if IDETAPE_DEBUG_INFO printk (KERN_INFO "ide-tape: Dumping the results of the MODE SENSE packet command\n"); printk (KERN_INFO "ide-tape: Mode Parameter Header:\n"); printk (KERN_INFO "ide-tape: Mode Data Length - %d\n",header->mode_data_length); @@ -5615,7 +5690,7 @@ static void idetape_get_mode_sense_results (ide_drive_t *drive) printk (KERN_INFO "ide-tape: Continuous transfer limits in blocks - %d\n",capabilities->ctl); printk (KERN_INFO "ide-tape: Current speed in KBps - %d\n",capabilities->speed); printk (KERN_INFO "ide-tape: Buffer size - %d\n",capabilities->buffer_size*512); -#endif /* IDETAPE_DEBUG_LOG */ +#endif /* IDETAPE_DEBUG_INFO */ } static void idetape_add_settings (ide_drive_t *drive) diff --git a/drivers/block/ide.c b/drivers/block/ide.c index 93da9bea2..b82092452 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -186,6 +186,7 @@ static int ide_lock = 0; * ide_modules keeps track of the available IDE chipset/probe/driver modules. */ ide_module_t *ide_modules = NULL; +ide_module_t *ide_probe = NULL; /* * This is declared extern in ide.h, for access by other IDE modules: @@ -281,7 +282,7 @@ static void init_hwif_data (unsigned int index) * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them. */ #define MAGIC_COOKIE 0x12345678 -static void init_ide_data (void) +static void __init init_ide_data (void) { unsigned int index; static unsigned long magic_cookie = MAGIC_COOKIE; @@ -1093,13 +1094,18 @@ static ide_startstop_t start_request (ide_drive_t *drive) #endif block = rq->sector; blockend = block + rq->nr_sectors; - if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK].nr_sects)) { - printk("%s%c: bad access: block=%ld, count=%ld\n", drive->name, - (minor&PARTN_MASK)?'0'+(minor&PARTN_MASK):' ', block, rq->nr_sectors); - goto kill_rq; +#if 0 + if ((rq->cmd == READ || rq->cmd == WRITE) && + (drive->media == ide_disk || drive->media == ide_floppy)) +#endif + { + if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK].nr_sects)) { + printk("%s%c: bad access: block=%ld, count=%ld\n", drive->name, + (minor&PARTN_MASK)?'0'+(minor&PARTN_MASK):' ', block, rq->nr_sectors); + goto kill_rq; + } + block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0; } - block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0; - /* Yecch - this will shift the entire interval, possibly killing some innocent following sector */ if (block == 0 && drive->remap_0_to_1 == 1) @@ -1409,9 +1415,9 @@ void ide_timer_expiry (unsigned long data) } } else { ide_drive_t *drive = hwgroup->drive; - hwgroup->handler = NULL; if (!drive) { printk("ide_timer_expiry: hwgroup->drive was NULL\n"); + hwgroup->handler = NULL; } else { ide_hwif_t *hwif; ide_startstop_t startstop; @@ -1429,6 +1435,7 @@ void ide_timer_expiry (unsigned long data) return; } } + hwgroup->handler = NULL; /* * We need to simulate a real interrupt when invoking * the handler() function, which means we need to globally @@ -1436,7 +1443,7 @@ void ide_timer_expiry (unsigned long data) */ spin_unlock(&io_request_lock); hwif = HWIF(drive); - disable_irq(hwif->irq); + disable_irq(hwif->irq); /* disable_irq_nosync ?? */ __cli(); /* local CPU only, as if we were handling an interrupt */ if (hwgroup->poll_timeout != 0) { startstop = handler(drive); @@ -1802,23 +1809,33 @@ static void revalidate_drives (void) } } -static void ide_init_module (int type) +static void ide_probe_module (void) +{ + if (!ide_probe) { +#ifdef CONFIG_KMOD + (void) request_module("ide-probe-mod"); +#endif /* CONFIG_KMOD */ + } else { + (void) ide_probe->init(); + } + revalidate_drives(); +} + +static void ide_driver_module (void) { - int found = 0; + int index; ide_module_t *module = ide_modules; - + + for (index = 0; index < MAX_HWIFS; ++index) + if (ide_hwifs[index].present) + goto search; + ide_probe_module(); +search: while (module) { - if (module->type == type) { - found = 1; - (void) module->init(); - } + (void) module->init(); module = module->next; } revalidate_drives(); -#ifdef CONFIG_KMOD - if (!found && type == IDE_PROBE_MODULE) - (void) request_module("ide-probe-mod"); -#endif /* CONFIG_KMOD */ } static int ide_open (struct inode * inode, struct file * filp) @@ -1830,7 +1847,7 @@ static int ide_open (struct inode * inode, struct file * filp) return -ENXIO; MOD_INC_USE_COUNT; if (drive->driver == NULL) - ide_init_module(IDE_DRIVER_MODULE); + ide_driver_module(); #ifdef CONFIG_KMOD if (drive->driver == NULL) { if (drive->media == ide_disk) @@ -1881,9 +1898,9 @@ int ide_replace_subdriver (ide_drive_t *drive, const char *driver) if (drive->driver != NULL && DRIVER(drive)->cleanup(drive)) goto abort; strncpy(drive->driver_req, driver, 9); - ide_init_module(IDE_DRIVER_MODULE); + ide_driver_module(); drive->driver_req[0] = 0; - ide_init_module(IDE_DRIVER_MODULE); + ide_driver_module(); if (DRIVER(drive) && !strcmp(DRIVER(drive)->name, driver)) return 0; abort: @@ -1897,6 +1914,35 @@ ide_proc_entry_t generic_subdriver_entries[] = { }; #endif +/* + * Note that we only release the standard ports, + * and do not even try to handle any extra ports + * allocated for weird IDE interface chipsets. + */ +void hwif_unregister (ide_hwif_t *hwif) +{ + if (hwif->io_ports[IDE_DATA_OFFSET]) + ide_release_region(hwif->io_ports[IDE_DATA_OFFSET], 1); + if (hwif->io_ports[IDE_ERROR_OFFSET]) + ide_release_region(hwif->io_ports[IDE_ERROR_OFFSET], 1); + if (hwif->io_ports[IDE_NSECTOR_OFFSET]) + ide_release_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1); + if (hwif->io_ports[IDE_SECTOR_OFFSET]) + ide_release_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1); + if (hwif->io_ports[IDE_LCYL_OFFSET]) + ide_release_region(hwif->io_ports[IDE_LCYL_OFFSET], 1); + if (hwif->io_ports[IDE_HCYL_OFFSET]) + ide_release_region(hwif->io_ports[IDE_HCYL_OFFSET], 1); + if (hwif->io_ports[IDE_SELECT_OFFSET]) + ide_release_region(hwif->io_ports[IDE_SELECT_OFFSET], 1); + if (hwif->io_ports[IDE_STATUS_OFFSET]) + ide_release_region(hwif->io_ports[IDE_STATUS_OFFSET], 1); + if (hwif->io_ports[IDE_CONTROL_OFFSET]) + ide_release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1); + if (hwif->io_ports[IDE_IRQ_OFFSET]) + ide_release_region(hwif->io_ports[IDE_IRQ_OFFSET], 1); +} + void ide_unregister (unsigned int index) { struct gendisk *gd, **gdp; @@ -1967,9 +2013,7 @@ void ide_unregister (unsigned int index) * and do not even try to handle any extra ports * allocated for weird IDE interface chipsets. */ - ide_release_region(hwif->io_ports[IDE_DATA_OFFSET], 8); - if (hwif->io_ports[IDE_CONTROL_OFFSET]) - ide_release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1); + hwif_unregister(hwif); /* * Remove us from the hwgroup, and free @@ -2036,23 +2080,28 @@ void ide_unregister (unsigned int index) kfree (gd->flags); kfree(gd); } - old_hwif = *hwif; + old_hwif = *hwif; init_hwif_data (index); /* restore hwif data to pristine status */ - hwif->hwgroup = old_hwif.hwgroup; - hwif->tuneproc = old_hwif.tuneproc; - hwif->resetproc = old_hwif.resetproc; - hwif->dmaproc = old_hwif.dmaproc; - hwif->dma_base = old_hwif.dma_base; - hwif->dma_extra = old_hwif.dma_extra; - hwif->config_data = old_hwif.config_data; - hwif->select_data = old_hwif.select_data; - hwif->irq = old_hwif.irq; - hwif->major = old_hwif.major; - hwif->proc = old_hwif.proc; - hwif->udma_four = old_hwif.udma_four; - hwif->chipset = old_hwif.chipset; - hwif->pci_dev = old_hwif.pci_dev; - hwif->pci_devid = old_hwif.pci_devid; + hwif->hwgroup = old_hwif.hwgroup; + hwif->tuneproc = old_hwif.tuneproc; + hwif->selectproc = old_hwif.selectproc; + hwif->resetproc = old_hwif.resetproc; + hwif->dmaproc = old_hwif.dmaproc; + hwif->dma_base = old_hwif.dma_base; + hwif->dma_extra = old_hwif.dma_extra; + hwif->config_data = old_hwif.config_data; + hwif->select_data = old_hwif.select_data; + hwif->proc = old_hwif.proc; + hwif->irq = old_hwif.irq; + hwif->major = old_hwif.major; + hwif->chipset = old_hwif.chipset; + hwif->autodma = old_hwif.autodma; + hwif->udma_four = old_hwif.udma_four; +#ifdef CONFIG_BLK_DEV_IDEPCI + hwif->pci_dev = old_hwif.pci_dev; + hwif->pci_devid = old_hwif.pci_devid; +#endif /* CONFIG_BLK_DEV_IDEPCI */ + abort: restore_flags(flags); /* all CPUs */ } @@ -2087,6 +2136,7 @@ void ide_setup_ports ( hw_regs_t *hw, } } hw->irq = irq; + hw->dma = NO_DMA; hw->ack_intr = ack_intr; } @@ -2126,11 +2176,11 @@ found: hwif->noprobe = 0; if (!initializing) { - ide_init_module(IDE_PROBE_MODULE); + ide_probe_module(); #ifdef CONFIG_PROC_FS create_proc_ide_interfaces(); #endif - ide_init_module(IDE_DRIVER_MODULE); + ide_driver_module(); } if (hwifp) @@ -2750,7 +2800,7 @@ int __init ide_setup (char *s) if (!strcmp(s, "ide=doubler")) { extern int ide_doubler; - printk("ide: Enabled support for IDE doublers\n"); + printk(" : Enabled support for IDE doublers\n"); ide_doubler = 1; return 0; } @@ -2759,12 +2809,14 @@ int __init ide_setup (char *s) #ifdef CONFIG_BLK_DEV_IDEPCI if (!strcmp(s, "ide=reverse")) { ide_scan_direction = 1; - printk("ide: Enabled support for IDE inverse scan order.\n"); + printk(" : Enabled support for IDE inverse scan order.\n"); return 0; } #endif /* CONFIG_BLK_DEV_IDEPCI */ +#ifndef CONFIG_BLK_DEV_IDEPCI init_ide_data (); +#endif /* CONFIG_BLK_DEV_IDEPCI */ /* * Look for drive options: "hdx=" @@ -3176,7 +3228,7 @@ void __init ide_init_builtin_drivers (void) #if defined(__mc68000__) || defined(CONFIG_APUS) if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) { ide_get_lock(&ide_lock, NULL, NULL); /* for atari only */ - disable_irq(ide_hwifs[0].irq); + disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */ } #endif /* __mc68000__ || CONFIG_APUS */ @@ -3293,10 +3345,6 @@ ide_drive_t *ide_scan_devices (byte media, const char *name, ide_driver_t *drive { unsigned int unit, index, i; - for (index = 0; index < MAX_HWIFS; ++index) - if (ide_hwifs[index].present) goto search; - ide_init_module(IDE_PROBE_MODULE); -search: for (index = 0, i = 0; index < MAX_HWIFS; ++index) { ide_hwif_t *hwif = &ide_hwifs[index]; if (!hwif->present) @@ -3327,8 +3375,16 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio setup_driver_defaults(drive); restore_flags(flags); /* all CPUs */ if (drive->autotune != 2) { - if (driver->supports_dma && HWIF(drive)->dmaproc != NULL) + if (driver->supports_dma && HWIF(drive)->dmaproc != NULL) { + /* + * Force DMAing for the beginning of the check. + * Some chipsets appear to do interesting things, + * if not checked and cleared. + * PARANOIA!!! + */ + (void) (HWIF(drive)->dmaproc(ide_dma_off_quietly, drive)); (void) (HWIF(drive)->dmaproc(ide_dma_check, drive)); + } drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap); drive->nice1 = 1; } @@ -3400,6 +3456,7 @@ EXPORT_SYMBOL(ide_spin_wait_hwgroup); /* * Probe module */ +EXPORT_SYMBOL(ide_probe); EXPORT_SYMBOL(drive_is_flashcard); EXPORT_SYMBOL(ide_timer_expiry); EXPORT_SYMBOL(ide_intr); @@ -3474,7 +3531,7 @@ EXPORT_SYMBOL(ide_register_hw); EXPORT_SYMBOL(ide_register); EXPORT_SYMBOL(ide_unregister); EXPORT_SYMBOL(ide_setup_ports); - +EXPORT_SYMBOL(hwif_unregister); EXPORT_SYMBOL(get_info_ptr); EXPORT_SYMBOL(current_capacity); @@ -3539,13 +3596,9 @@ void cleanup_module (void) { int index; - for (index = 0; index < MAX_HWIFS; ++index) { + for (index = 0; index < MAX_HWIFS; ++index) ide_unregister(index); -#ifdef CONFIG_BLK_DEV_IDEDMA - if (ide_hwifs[index].dma_base) - (void) ide_release_dma(&ide_hwifs[index]); -#endif /* CONFIG_BLK_DEV_IDEDMA */ - } + #ifdef CONFIG_PROC_FS proc_ide_destroy(); #endif diff --git a/drivers/block/ide_modes.h b/drivers/block/ide_modes.h index d8c8a7144..b6c28e6ab 100644 --- a/drivers/block/ide_modes.h +++ b/drivers/block/ide_modes.h @@ -1,11 +1,12 @@ -#ifndef _IDE_MODES_H -#define _IDE_MODES_H /* * linux/drivers/block/ide_modes.h * * Copyright (C) 1996 Linus Torvalds, Igor Abramov, and Mark Lord */ +#ifndef _IDE_MODES_H +#define _IDE_MODES_H + #include <linux/config.h> /* diff --git a/drivers/block/linear.c b/drivers/block/linear.c index 1c3305bae..978d75b80 100644 --- a/drivers/block/linear.c +++ b/drivers/block/linear.c @@ -121,14 +121,15 @@ static int linear_stop (mddev_t *mddev) return 0; } -static int linear_make_request (mddev_t *mddev, int rw, struct buffer_head * bh) +static int linear_make_request (request_queue_t *q, mddev_t *mddev, + int rw, struct buffer_head * bh) { linear_conf_t *conf = mddev_to_conf(mddev); struct linear_hash *hash; dev_info_t *tmp_dev; long block; - block = bh->b_blocknr * (bh->b_size >> 10); + block = bh->b_rsector >> 1; hash = conf->hash_table + (block / conf->smallest->size); if (block >= (hash->dev0->size + hash->dev0->offset)) { @@ -149,8 +150,7 @@ static int linear_make_request (mddev_t *mddev, int rw, struct buffer_head * bh) bh->b_rdev = tmp_dev->dev; bh->b_rsector = (block - tmp_dev->offset) << 1; - generic_make_request(rw, bh); - return 0; + return 1; } static int linear_status (char *page, mddev_t *mddev) diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 808878b3e..a0ac26a49 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -952,96 +952,122 @@ end_io: bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state)); } -void generic_make_request(int rw, struct buffer_head * bh) +static inline void buffer_IO_error(struct buffer_head * bh) +{ + mark_buffer_clean(bh); + /* + * b_end_io has to clear the BH_Uptodate bitflag in the error case! + */ + bh->b_end_io(bh, 0); +} + +int generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh) { - request_queue_t * q; unsigned long flags; + int ret; - q = blk_get_queue(bh->b_rdev); + /* + * Resolve the mapping until finished. (drivers are + * still free to implement/resolve their own stacking + * by explicitly returning 0) + */ + while (q->make_request_fn) { + ret = q->make_request_fn(q, rw, bh); + if (ret > 0) { + q = blk_get_queue(bh->b_rdev); + continue; + } + return ret; + } + /* + * Does the block device want us to queue + * the IO request? (normal case) + */ __make_request(q, rw, bh); - spin_lock_irqsave(&io_request_lock,flags); if (q && !q->plugged) (q->request_fn)(q); spin_unlock_irqrestore(&io_request_lock,flags); -} + return 0; +} /* This function can be used to request a number of buffers from a block device. Currently the only restriction is that all buffers must belong to the same device */ -static void __ll_rw_block(int rw, int nr, struct buffer_head * bh[],int haslock) +static void __ll_rw_block(int rw, int nr, struct buffer_head * bhs[], + int haslock) { + struct buffer_head *bh; + request_queue_t *q; unsigned int major; int correct_size; - request_queue_t *q; int i; - major = MAJOR(bh[0]->b_dev); - q = blk_get_queue(bh[0]->b_dev); + major = MAJOR(bhs[0]->b_dev); + q = blk_get_queue(bhs[0]->b_dev); if (!q) { printk(KERN_ERR "ll_rw_block: Trying to read nonexistent block-device %s (%ld)\n", - kdevname(bh[0]->b_dev), bh[0]->b_blocknr); + kdevname(bhs[0]->b_dev), bhs[0]->b_blocknr); goto sorry; } /* Determine correct block size for this device. */ correct_size = BLOCK_SIZE; if (blksize_size[major]) { - i = blksize_size[major][MINOR(bh[0]->b_dev)]; + i = blksize_size[major][MINOR(bhs[0]->b_dev)]; if (i) correct_size = i; } /* Verify requested block sizes. */ for (i = 0; i < nr; i++) { - if (bh[i]->b_size != correct_size) { + bh = bhs[i]; + if (bh->b_size != correct_size) { printk(KERN_NOTICE "ll_rw_block: device %s: " "only %d-char blocks implemented (%u)\n", - kdevname(bh[0]->b_dev), - correct_size, bh[i]->b_size); + kdevname(bhs[0]->b_dev), + correct_size, bh->b_size); goto sorry; } } - if ((rw & WRITE) && is_read_only(bh[0]->b_dev)) { + if ((rw & WRITE) && is_read_only(bhs[0]->b_dev)) { printk(KERN_NOTICE "Can't write to read-only device %s\n", - kdevname(bh[0]->b_dev)); + kdevname(bhs[0]->b_dev)); goto sorry; } for (i = 0; i < nr; i++) { + bh = bhs[i]; + /* Only one thread can actually submit the I/O. */ if (haslock) { - if (!buffer_locked(bh[i])) + if (!buffer_locked(bh)) BUG(); } else { - if (test_and_set_bit(BH_Lock, &bh[i]->b_state)) + if (test_and_set_bit(BH_Lock, &bh->b_state)) continue; } - set_bit(BH_Req, &bh[i]->b_state); + set_bit(BH_Req, &bh->b_state); - if (q->make_request_fn) - q->make_request_fn(rw, bh[i]); - else { - bh[i]->b_rdev = bh[i]->b_dev; - bh[i]->b_rsector = bh[i]->b_blocknr*(bh[i]->b_size>>9); + /* + * First step, 'identity mapping' - RAID or LVM might + * further remap this. + */ + bh->b_rdev = bh->b_dev; + bh->b_rsector = bh->b_blocknr * (bh->b_size>>9); - generic_make_request(rw, bh[i]); - } + generic_make_request(q, rw, bh); } - return; sorry: - for (i = 0; i < nr; i++) { - mark_buffer_clean(bh[i]); /* remeber to refile it */ - clear_bit(BH_Uptodate, &bh[i]->b_state); - bh[i]->b_end_io(bh[i], 0); - } + for (i = 0; i < nr; i++) + buffer_IO_error(bhs[i]); return; } @@ -1176,10 +1202,7 @@ int __init blk_dev_init(void) #ifdef CONFIG_BLK_DEV_FD floppy_init(); #else -#if !defined(CONFIG_SGI_IP22) && !defined(CONFIG_SGI_IP27) && \ - !defined (__mc68000__) && !defined(CONFIG_PPC) && !defined(__sparc__) && \ - !defined(CONFIG_APUS) && !defined(CONFIG_DECSTATION) && \ - !defined(CONFIG_BAGET_MIPS) && !defined(__sh__) && !defined(__ia64__) +#if defined(__i386__) /* Do we even need this? */ outb_p(0xc, 0x3f2); #endif #endif diff --git a/drivers/block/lvm.c b/drivers/block/lvm.c index 6d2f2743e..9f58a48d5 100644 --- a/drivers/block/lvm.c +++ b/drivers/block/lvm.c @@ -192,7 +192,7 @@ extern int lvm_init(void); static void lvm_dummy_device_request(request_queue_t *); #define DEVICE_REQUEST lvm_dummy_device_request -static void lvm_make_request_fn(int, struct buffer_head*); +static int lvm_make_request_fn(request_queue_t *, int, struct buffer_head*); static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong); static int lvm_blk_open(struct inode *, struct file *); @@ -1292,14 +1292,14 @@ static int lvm_proc_get_info(char *page, char **start, off_t pos, int count) */ static int lvm_map(struct buffer_head *bh, int rw) { - int minor = MINOR(bh->b_dev); + int minor = MINOR(bh->b_rdev); int ret = 0; ulong index; ulong pe_start; ulong size = bh->b_size >> 9; - ulong rsector_tmp = bh->b_blocknr * size; + ulong rsector_tmp = bh->b_rsector; ulong rsector_sav; - kdev_t rdev_tmp = bh->b_dev; + kdev_t rdev_tmp = bh->b_rdev; kdev_t rdev_sav; lv_t *lv = vg[VG_BLK(minor)]->lv[LV_BLK(minor)]; @@ -1513,11 +1513,10 @@ static void lvm_dummy_device_request(request_queue_t * t) /* * make request function */ -static void lvm_make_request_fn(int rw, struct buffer_head *bh) +static int lvm_make_request_fn(request_queue_t *q, int rw, struct buffer_head *bh) { lvm_map(bh, rw); - if (bh->b_rdev != MD_MAJOR) generic_make_request(rw, bh); - return; + return 1; } diff --git a/drivers/block/macide.c b/drivers/block/macide.c index 4f6febd28..46a14ba19 100644 --- a/drivers/block/macide.c +++ b/drivers/block/macide.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/macide.c -- Macintosh IDE Driver + * linux/drivers/ide/macide.c -- Macintosh IDE Driver * * Copyright (C) 1998 by Michael Schmitz * @@ -43,7 +43,7 @@ #define MAC_HD_STATUS 0x1c /* see status-bits */ #define MAC_HD_CONTROL 0x38 /* control/altstatus */ -static int macide_offsets[IDE_NR_PORTS] = { +static int __init 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 }; @@ -84,7 +84,7 @@ static int mac_ack_intr(ide_hwif_t* hwif) * Probe for a Macintosh IDE interface */ -void macide_init(void) +void __init macide_init(void) { hw_regs_t hw; int index = -1; diff --git a/drivers/block/md.c b/drivers/block/md.c index b258fc6c5..171b3b659 100644 --- a/drivers/block/md.c +++ b/drivers/block/md.c @@ -75,16 +75,16 @@ static devfs_handle_t devfs_handle = NULL; static struct gendisk md_gendisk= { - MD_MAJOR, - "md", - 0, - 1, - md_hd_struct, - md_size, - MAX_MD_DEVS, - NULL, - NULL, - &md_fops, + major: MD_MAJOR, + major_name: "md", + minor_shift: 0, + max_p: 1, + part: md_hd_struct, + sizes: md_size, + nr_real: MAX_MD_DEVS, + real_devices: NULL, + next: NULL, + fops: &md_fops, }; void md_plug_device (request_queue_t *mdqueue, kdev_t dev) @@ -178,17 +178,16 @@ static void do_md_request (request_queue_t * q) return; } -void md_make_request (int rw, struct buffer_head * bh) +static int md_make_request (request_queue_t *q, int rw, struct buffer_head * bh) { - mddev_t *mddev = kdev_to_mddev(bh->b_dev); + mddev_t *mddev = kdev_to_mddev(bh->b_rdev); - if (!mddev || !mddev->pers) - bh->b_end_io(bh, 0); + if (mddev && mddev->pers) + return mddev->pers->make_request(q, mddev, rw, bh); else { - if ((rw == READ || rw == READA) && buffer_uptodate(bh)) - bh->b_end_io(bh, 1); - else - mddev->pers->make_request(mddev, rw, bh); + mark_buffer_clean(bh); + bh->b_end_io(bh, 0); + return -1; } } @@ -234,28 +233,6 @@ static mddev_t * alloc_mddev (kdev_t dev) return mddev; } -static void free_mddev (mddev_t *mddev) -{ - if (!mddev) { - MD_BUG(); - return; - } - - /* - * Make sure nobody else is using this mddev - * (careful, we rely on the global kernel lock here) - */ - while (md_atomic_read(&mddev->resync_sem.count) != 1) - schedule(); - while (md_atomic_read(&mddev->recovery_sem.count) != 1) - schedule(); - - del_mddev_mapping(mddev, MKDEV(MD_MAJOR, mdidx(mddev))); - md_list_del(&mddev->all_mddevs); - MD_INIT_LIST_HEAD(&mddev->all_mddevs); - kfree(mddev); -} - struct gendisk * find_gendisk (kdev_t dev) { struct gendisk *tmp = gendisk_head; @@ -757,6 +734,32 @@ static void export_array (mddev_t *mddev) MD_BUG(); } +static void free_mddev (mddev_t *mddev) +{ + if (!mddev) { + MD_BUG(); + return; + } + + export_array(mddev); + md_size[mdidx(mddev)] = 0; + md_hd_struct[mdidx(mddev)].nr_sects = 0; + + /* + * Make sure nobody else is using this mddev + * (careful, we rely on the global kernel lock here) + */ + while (md_atomic_read(&mddev->resync_sem.count) != 1) + schedule(); + while (md_atomic_read(&mddev->recovery_sem.count) != 1) + schedule(); + + del_mddev_mapping(mddev, MKDEV(MD_MAJOR, mdidx(mddev))); + md_list_del(&mddev->all_mddevs); + MD_INIT_LIST_HEAD(&mddev->all_mddevs); + kfree(mddev); +} + #undef BAD_CSUM #undef BAD_MAGIC #undef OUT_OF_MEM @@ -1723,13 +1726,7 @@ static int do_md_stop (mddev_t * mddev, int ro) printk (STILL_MOUNTED, mdidx(mddev)); OUT(-EBUSY); } - - /* - * complain if it's already stopped - */ - if (!mddev->nb_dev) - OUT(-ENXIO); - + if (mddev->pers) { /* * It is safe to call stop here, it only frees private @@ -1796,9 +1793,6 @@ static int do_md_stop (mddev_t * mddev, int ro) * Free resources if final stop */ if (!ro) { - export_array(mddev); - md_size[mdidx(mddev)] = 0; - md_hd_struct[mdidx(mddev)].nr_sects = 0; free_mddev(mddev); printk (KERN_INFO "md%d stopped.\n", mdidx(mddev)); @@ -3279,15 +3273,15 @@ static void md_geninit (void) { int i; - blksize_size[MD_MAJOR] = md_blocksizes; - max_readahead[MD_MAJOR] = md_maxreadahead; - for(i = 0; i < MAX_MD_DEVS; i++) { md_blocksizes[i] = 1024; + md_size[i] = 0; md_maxreadahead[i] = MD_READAHEAD; register_disk(&md_gendisk, MKDEV(MAJOR_NR,i), 1, &md_fops, 0); - } + blksize_size[MD_MAJOR] = md_blocksizes; + blk_size[MAJOR_NR] = md_size; + max_readahead[MD_MAJOR] = md_maxreadahead; printk("md.c: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t)); diff --git a/drivers/block/ns87415.c b/drivers/block/ns87415.c index 8b8bb3f60..0e5675fde 100644 --- a/drivers/block/ns87415.c +++ b/drivers/block/ns87415.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ns87415.c Version 1.00 December 7, 1997 + * linux/drivers/block/ns87415.c Version 1.00 December 7, 1997 * * Copyright (C) 1997-1998 Mark Lord * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) diff --git a/drivers/block/opti621.c b/drivers/block/opti621.c index 0885ed49e..cc2aa567c 100644 --- a/drivers/block/opti621.c +++ b/drivers/block/opti621.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/opti621.c Version 0.6 Jan 02, 1999 + * linux/drivers/block/opti621.c Version 0.6 Jan 02, 1999 * * Copyright (C) 1996-1998 Linus Torvalds & authors (see below) */ diff --git a/drivers/block/pdc202xx.c b/drivers/block/pdc202xx.c index c5a0c4924..bce80650c 100644 --- a/drivers/block/pdc202xx.c +++ b/drivers/block/pdc202xx.c @@ -1,7 +1,7 @@ /* - * linux/drivers/block/pdc202xx.c Version 0.28 Dec. 13, 1999 + * linux/drivers/block/pdc202xx.c Version 0.29 Feb. 10, 2000 * - * Copyright (C) 1998-99 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) * May be copied or modified under the terms of the GNU General Public License * * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this @@ -14,7 +14,7 @@ * 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 "CONFIG_PDC202XX_FORCE_BURST_BIT" + * UNLESS you enable "CONFIG_PDC202XX_BURST" * * There is only one BIOS in the three contollers. * @@ -100,6 +100,61 @@ #define PDC202XX_DEBUG_DRIVE_INFO 0 #define PDC202XX_DECODE_REGISTER_INFO 0 +#define DISPLAY_PDC202XX_TIMINGS +#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static int pdc202xx_get_info(char *, char **, off_t, int); +extern int (*pdc202xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static struct pci_dev *bmide_dev; + +static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count) +{ + char *p = buffer; + + u32 bibma = bmide_dev->resource[4].start; + u8 c0 = 0, c1 = 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + + switch(bmide_dev->device) { + case PCI_DEVICE_ID_PROMISE_20262: + p += sprintf(p, "\n PDC20262 Chipset.\n"); + break; + case PCI_DEVICE_ID_PROMISE_20246: + p += sprintf(p, "\n PDC20246 Chipset.\n"); + break; + default: + p += sprintf(p, "\n PDC202XX Chipset.\n"); + break; + } + + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\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 " ); + + p += sprintf(p, "UDMA\n"); + p += sprintf(p, "DMA\n"); + p += sprintf(p, "PIO\n"); + + return p-buffer; /* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */ + +byte pdc202xx_proc = 0; + extern char *ide_xfer_verbose (byte xfer_rate); /* A Register */ @@ -620,15 +675,15 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) (primary_mode & 1) ? "MASTER" : "PCI", (secondary_mode & 1) ? "MASTER" : "PCI" ); -#ifdef CONFIG_PDC202XX_FORCE_BURST_BIT +#ifdef CONFIG_PDC202XX_BURST 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 /* CONFIG_PDC202XX_FORCE_BURST_BIT */ +#endif /* CONFIG_PDC202XX_BURST */ -#ifdef CONFIG_PDC202XX_FORCE_MASTER_MODE +#ifdef CONFIG_PDC202XX_MASTER if (!(primary_mode & 1)) { printk("%s: FORCING PRIMARY MODE BIT 0x%02x -> 0x%02x ", name, primary_mode, (primary_mode|1)); @@ -642,7 +697,14 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) outb(secondary_mode|1, high_16 + 0x001b); printk("%s\n", (inb(high_16 + 0x001b) & 1) ? "MASTER" : "PCI"); } -#endif /* CONFIG_PDC202XX_FORCE_MASTER_MODE */ +#endif /* CONFIG_PDC202XX_MASTER */ + +#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) + pdc202xx_proc = 1; + bmide_dev = dev; + pdc202xx_display_info = &pdc202xx_get_info; +#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */ + return dev->irq; } diff --git a/drivers/block/pdc4030.c b/drivers/block/pdc4030.c index 0b682645c..f42c4946f 100644 --- a/drivers/block/pdc4030.c +++ b/drivers/block/pdc4030.c @@ -1,5 +1,5 @@ /* -*- linux-c -*- - * linux/drivers/block/pdc4030.c Version 0.90 May 27, 1999 + * linux/drivers/ide/pdc4030.c Version 0.90 May 27, 1999 * * Copyright (C) 1995-1999 Linus Torvalds & authors (see below) */ diff --git a/drivers/block/pdc4030.h b/drivers/block/pdc4030.h index 9f08da5aa..551785c36 100644 --- a/drivers/block/pdc4030.h +++ b/drivers/block/pdc4030.h @@ -1,5 +1,5 @@ /* - * linux/drivers/block/pdc4030.h + * linux/drivers/ide/pdc4030.h * * Copyright (C) 1995-1998 Linus Torvalds & authors */ diff --git a/drivers/block/piix.c b/drivers/block/piix.c index 64cf45853..4c2d94c99 100644 --- a/drivers/block/piix.c +++ b/drivers/block/piix.c @@ -1,8 +1,8 @@ /* - * linux/drivers/block/piix.c Version 0.28 Dec. 13, 1999 + * linux/drivers/block/piix.c Version 0.30 Feb. 26, 2000 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer - * Copyright (C) 1998-1999 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) * May be copied or modified under the terms of the GNU General Public License * * PIO mode setting function for Intel chipsets. @@ -49,13 +49,33 @@ * 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); + * pci_read_config_word(HWIF(drive)->pci_dev, 0x54, ®54); + * + * 00:1f.1 IDE interface: Intel Corporation: + * Unknown device 2411 (rev 01) (prog-if 80 [Master]) + * Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- + * ParErr- Stepping- SERR- FastB2B- + * Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- + * <TAbort- <MAbort- >SERR- <PERR- + * Latency: 0 set + * Region 4: I/O ports at ffa0 + * 00: 86 80 11 24 05 00 80 02 01 80 01 01 00 00 00 00 + * 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 20: a1 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 40: 07 a3 03 a3 00 00 00 00 05 00 02 02 00 00 00 00 + * 50: 00 00 00 00 11 04 00 00 00 00 00 00 00 00 00 00 + * 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * f0: 00 00 00 00 00 00 00 00 3a 0f 00 00 00 00 00 00 * - * #if 0 - * int err; - * err = ide_config_drive_speed(drive, speed); - * (void) ide_config_drive_speed(drive, speed); - * #else - * #endif */ #include <linux/config.h> @@ -86,16 +106,88 @@ static struct pci_dev *bmide_dev; static int piix_get_info (char *buffer, char **addr, off_t offset, int count) { - /* int rc; */ - int piix_who = ((bmide_dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) || - (bmide_dev->device == PCI_DEVICE_ID_INTEL_82801AB_1) || - (bmide_dev->device == PCI_DEVICE_ID_INTEL_82371AB)) ? 4 : 3; char *p = buffer; - p += sprintf(p, "\n Intel PIIX%d Chipset.\n", piix_who); - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n\n"); + u32 bibma = bmide_dev->resource[4].start; + u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0; + u8 c0 = 0, c1 = 0; + u8 reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0; + + pci_read_config_word(bmide_dev, 0x40, ®40); + pci_read_config_word(bmide_dev, 0x42, ®42); + pci_read_config_byte(bmide_dev, 0x44, ®44); + pci_read_config_byte(bmide_dev, 0x48, ®48); + pci_read_config_byte(bmide_dev, 0x4a, ®4a); + pci_read_config_byte(bmide_dev, 0x4b, ®4b); + pci_read_config_byte(bmide_dev, 0x54, ®54); + + psitre = (reg40 & 0x4000) ? 1 : 0; + ssitre = (reg42 & 0x4000) ? 1 : 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + + switch(bmide_dev->device) { + case PCI_DEVICE_ID_INTEL_82372FB_1: + case PCI_DEVICE_ID_INTEL_82801AA_1: + p += sprintf(p, "\n Intel PIIX4 Ultra 66 Chipset.\n"); + break; + case PCI_DEVICE_ID_INTEL_82801AB_1: + case PCI_DEVICE_ID_INTEL_82371AB: + p += sprintf(p, "\n Intel PIIX4 Ultra 33 Chipset.\n"); + break; + case PCI_DEVICE_ID_INTEL_82371SB_1: + p += sprintf(p, "\n Intel PIIX3 Chipset.\n"); + break; + case PCI_DEVICE_ID_INTEL_82371FB_1: + case PCI_DEVICE_ID_INTEL_82371FB_0: + default: + p += sprintf(p, "\n Intel PIIX Chipset.\n"); + break; + } + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); - p += sprintf(p, "\n"); - p += sprintf(p, "\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 " ); + p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + (reg48&0x01) ? "yes" : "no ", + (reg48&0x02) ? "yes" : "no ", + (reg48&0x04) ? "yes" : "no ", + (reg48&0x08) ? "yes" : "no " ); + p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + ((reg54&0x11) && (reg4a&0x02)) ? "4" : + ((reg54&0x11) && (reg4a&0x01)) ? "3" : + (reg4a&0x02) ? "2" : + (reg4a&0x01) ? "1" : + (reg4a&0x00) ? "0" : "X", + ((reg54&0x22) && (reg4a&0x20)) ? "4" : + ((reg54&0x22) && (reg4a&0x10)) ? "3" : + (reg4a&0x20) ? "2" : + (reg4a&0x10) ? "1" : + (reg4a&0x00) ? "0" : "X", + ((reg54&0x44) && (reg4b&0x02)) ? "4" : + ((reg54&0x44) && (reg4b&0x01)) ? "3" : + (reg4b&0x02) ? "2" : + (reg4b&0x01) ? "1" : + (reg4b&0x00) ? "0" : "X", + ((reg54&0x88) && (reg4b&0x20)) ? "4" : + ((reg54&0x88) && (reg4b&0x10)) ? "3" : + (reg4b&0x20) ? "2" : + (reg4b&0x10) ? "1" : + (reg4b&0x00) ? "0" : "X"); + + p += sprintf(p, "UDMA\n"); + p += sprintf(p, "DMA\n"); + p += sprintf(p, "PIO\n"); /* * FIXME.... Add configuration junk data....blah blah...... @@ -113,7 +205,6 @@ byte piix_proc = 0; extern char *ide_xfer_verbose (byte xfer_rate); -#ifdef CONFIG_BLK_DEV_PIIX_TUNING /* * */ @@ -143,7 +234,6 @@ static byte piix_dma_2_pio (byte xfer_rate) { return 0; } } -#endif /* CONFIG_BLK_DEV_PIIX_TUNING */ /* * Based on settings done by AMI BIOS @@ -191,8 +281,6 @@ static void piix_tune_drive (ide_drive_t *drive, byte pio) restore_flags(flags); } -#ifdef CONFIG_BLK_DEV_PIIX_TUNING - static int piix_config_drive_for_dma (ide_drive_t *drive) { struct hd_driveid *id = drive->id; @@ -205,12 +293,15 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) byte maslave = hwif->channel ? 0x42 : 0x40; byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; - int ultra = ((dev->device == PCI_DEVICE_ID_INTEL_82371AB) || + int ultra66 = ((dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) || + (dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0; + int ultra = ((ultra66) || + (dev->device == PCI_DEVICE_ID_INTEL_82371AB) || (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0; - int ultra66 = (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ? 1 : 0; 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; + int v_flag = 0x10 << drive_number; int u_speed = 0; pci_read_config_word(dev, maslave, ®4042); @@ -245,10 +336,6 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); } - /* - * This is !@#$% ugly and stupid............. - * But ugly harware generates ugly code......... - */ if (speed >= XFER_UDMA_0) { if (!(reg48 & u_flag)) pci_write_config_word(dev, 0x48, reg48|u_flag); @@ -256,10 +343,12 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); pci_write_config_word(dev, 0x4a, reg4a|u_speed); } - if ((speed > XFER_UDMA_2) && (!(reg54 & u_flag))) { - pci_write_config_word(dev, 0x54, reg54|u_flag); + if (speed > XFER_UDMA_2) { + if (!(reg54 & v_flag)) { + pci_write_config_word(dev, 0x54, reg54|v_flag); + } } else { - pci_write_config_word(dev, 0x54, reg54 & ~u_flag); + pci_write_config_word(dev, 0x54, reg54 & ~v_flag); } } @@ -268,8 +357,8 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) pci_write_config_word(dev, 0x48, reg48 & ~u_flag); if (reg4a & a_speed) pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); - if (reg54 & u_flag) - pci_write_config_word(dev, 0x54, reg54 & ~u_flag); + if (reg54 & v_flag) + pci_write_config_word(dev, 0x54, reg54 & ~v_flag); } piix_tune_drive(drive, piix_dma_2_pio(speed)); @@ -277,8 +366,7 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) (void) ide_config_drive_speed(drive, speed); #if PIIX_DEBUG_DRIVE_INFO - printk("%s: %s drive%d ", drive->name, ide_xfer_verbose(speed), drive_number); - printk("\n"); + printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive_number); #endif /* PIIX_DEBUG_DRIVE_INFO */ return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on : @@ -299,16 +387,13 @@ static int piix_dmaproc(ide_dma_action_t func, ide_drive_t *drive) /* Other cases are done by generic IDE-DMA code. */ return ide_dmaproc(func, drive); } -#endif /* CONFIG_BLK_DEV_PIIX_TUNING */ unsigned int __init pci_init_piix (struct pci_dev *dev, const char *name) { #if defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS) - if (!piix_proc) { - piix_proc = 1; - bmide_dev = dev; - piix_display_info = &piix_get_info; - } + piix_proc = 1; + bmide_dev = dev; + piix_display_info = &piix_get_info; #endif /* DISPLAY_PIIX_TIMINGS && CONFIG_PROC_FS */ return 0; } @@ -325,7 +410,7 @@ unsigned int __init ata66_piix (ide_hwif_t *hwif) pci_read_config_byte(hwif->pci_dev, 0x54, ®54h); pci_read_config_byte(hwif->pci_dev, 0x55, ®55h); - ata66 = (reg54h & mask) ? 0 : 1; + ata66 = (reg54h & mask) ? 1 : 0; return ata66; } @@ -335,9 +420,9 @@ void __init ide_init_piix (ide_hwif_t *hwif) hwif->tuneproc = &piix_tune_drive; if (hwif->dma_base) { -#ifdef CONFIG_BLK_DEV_PIIX_TUNING +#ifdef CONFIG_PIIX_TUNING hwif->dmaproc = &piix_dmaproc; -#endif /* CONFIG_BLK_DEV_PIIX_TUNING */ +#endif /* CONFIG_PIIX_TUNING */ hwif->drives[0].autotune = 0; hwif->drives[1].autotune = 0; } else { diff --git a/drivers/block/qd6580.c b/drivers/block/qd6580.c index d7b2784d1..31781a9f0 100644 --- a/drivers/block/qd6580.c +++ b/drivers/block/qd6580.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/qd6580.c Version 0.02 Feb 09, 1996 + * linux/drivers/block/qd6580.c Version 0.02 Feb 09, 1996 * * Copyright (C) 1996 Linus Torvalds & author (see below) */ @@ -60,7 +60,7 @@ static void tune_qd6580 (ide_drive_t *drive, byte pio) restore_flags(flags); /* all CPUs */ } -void init_qd6580 (void) +void __init init_qd6580 (void) { ide_hwifs[0].chipset = ide_qd6580; ide_hwifs[1].chipset = ide_qd6580; diff --git a/drivers/block/raid0.c b/drivers/block/raid0.c index 661855a18..0e075277a 100644 --- a/drivers/block/raid0.c +++ b/drivers/block/raid0.c @@ -223,23 +223,23 @@ static int raid0_stop (mddev_t *mddev) * Of course, those facts may not be valid anymore (and surely won't...) * Hey guys, there's some work out there ;-) */ -static int raid0_make_request (mddev_t *mddev, int rw, struct buffer_head * bh) +static int raid0_make_request (request_queue_t *q, mddev_t *mddev, + int rw, struct buffer_head * bh) { - unsigned long size = bh->b_size >> 10; + int blk_in_chunk, chunksize_bits, chunk, chunk_size; raid0_conf_t *conf = mddev_to_conf(mddev); struct raid0_hash *hash; struct strip_zone *zone; mdk_rdev_t *tmp_dev; - int blk_in_chunk, chunksize_bits, chunk, chunk_size; long block, rblock; chunk_size = mddev->param.chunk_size >> 10; chunksize_bits = ffz(~chunk_size); - block = bh->b_blocknr * size; + block = bh->b_rsector >> 1; hash = conf->hash_table + block / conf->smallest->size; /* Sanity check */ - if (chunk_size < (block % chunk_size) + size) + if (chunk_size < (block % chunk_size) + (bh->b_size >> 10)) goto bad_map; if (!hash) @@ -261,20 +261,19 @@ static int raid0_make_request (mddev_t *mddev, int rw, struct buffer_head * bh) rblock = (chunk << chunksize_bits) + blk_in_chunk + zone->dev_offset; /* - * Important, at this point we are not guaranteed to be the only - * CPU modifying b_rdev and b_rsector! Only __make_request() later - * on serializes the IO. So in 2.4 we must never write temporary - * values to bh->b_rdev, like 2.2 and 2.0 did. + * The new BH_Lock semantics in ll_rw_blk.c guarantee that this + * is the only IO operation happening on this bh. */ bh->b_rdev = tmp_dev->dev; bh->b_rsector = rblock << 1; - generic_make_request(rw, bh); - - return 0; + /* + * Let the main block layer submit the IO and resolve recursion: + */ + return 1; bad_map: - printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %ld %ld\n", chunk_size, bh->b_rsector, size); + printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %ld %d\n", chunk_size, bh->b_rsector, bh->b_size >> 10); return -1; bad_hash: printk("raid0_make_request bug: hash==NULL for block %ld\n", block); diff --git a/drivers/block/rapide.c b/drivers/block/rapide.c index 468f2e3b1..5905aca41 100644 --- a/drivers/block/rapide.c +++ b/drivers/block/rapide.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/drivers/block/ide-rapide.c + * linux/drivers/block/rapide.c * * Copyright (c) 1996-1998 Russell King. * @@ -16,7 +16,7 @@ #include <asm/ecard.h> -static const card_ids rapide_cids[] = { +static const card_ids __init rapide_cids[] = { { MANU_YELLOWSTONE, PROD_YELLOWSTONE_RAPIDE32 }, { 0xffff, 0xffff } }; @@ -43,7 +43,7 @@ static inline int rapide_register(struct expansion_card *ec) return ide_register_hw(&hw, NULL); } -int rapide_init(void) +int __init rapide_init(void) { int i; diff --git a/drivers/block/rz1000.c b/drivers/block/rz1000.c index 811e1665f..455641c1d 100644 --- a/drivers/block/rz1000.c +++ b/drivers/block/rz1000.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/rz1000.c Version 0.05 December 8, 1997 + * linux/drivers/block/rz1000.c Version 0.05 December 8, 1997 * * Copyright (C) 1995-1998 Linus Torvalds & author (see below) */ diff --git a/drivers/block/sis5513.c b/drivers/block/sis5513.c index d255bbdf8..942187900 100644 --- a/drivers/block/sis5513.c +++ b/drivers/block/sis5513.c @@ -1,7 +1,7 @@ /* - * linux/drivers/block/sis5513.c Version 0.08 Dec. 13, 1999 + * linux/drivers/block/sis5513.c Version 0.09 Feb. 10, 2000 * - * Copyright (C) 1999 Andre Hedrick (andre@suse.com) + * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com) * May be copied or modified under the terms of the GNU General Public License * * Thanks to SIS Taiwan for direct support and hardware. @@ -50,6 +50,7 @@ static const struct { { "SiS540", PCI_DEVICE_ID_SI_540, SIS5513_FLAG_ATA_66, }, { "SiS620", PCI_DEVICE_ID_SI_620, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, { "SiS630", PCI_DEVICE_ID_SI_630, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, + { "SiS5591", PCI_DEVICE_ID_SI_5591, SIS5513_FLAG_ATA_33, }, { "SiS5597", PCI_DEVICE_ID_SI_5597, SIS5513_FLAG_ATA_33, }, { "SiS5600", PCI_DEVICE_ID_SI_5600, SIS5513_FLAG_ATA_33, }, { "SiS5511", PCI_DEVICE_ID_SI_5511, SIS5513_FLAG_ATA_16, }, @@ -233,8 +234,10 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) byte drive_pci, test1, test2, mask; int err; + unsigned long dma_base = hwif->dma_base; + byte unit = (drive->select.b.unit & 0x01); byte speed = 0x00, unmask = 0xE0, four_two = 0x00; - int drive_number = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); + int drive_number = ((hwif->channel ? 2 : 0) + unit); byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; if (host_dev) { @@ -314,6 +317,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) return ((int) ide_dma_off_quietly); } + outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); err = ide_config_drive_speed(drive, speed); #if SIS5513_DEBUG_DRIVE_INFO @@ -532,6 +536,7 @@ void __init ide_init_sis5513 (ide_hwif_t *hwif) case PCI_DEVICE_ID_SI_630: case PCI_DEVICE_ID_SI_5600: case PCI_DEVICE_ID_SI_5597: + case PCI_DEVICE_ID_SI_5591: hwif->autodma = 1; hwif->dmaproc = &sis5513_dmaproc; break; diff --git a/drivers/block/sl82c105.c b/drivers/block/sl82c105.c index 9ab90f0df..29f006682 100644 --- a/drivers/block/sl82c105.c +++ b/drivers/block/sl82c105.c @@ -1,5 +1,5 @@ /* - * drivers/block/sl82c105.c + * linux/drivers/block/sl82c105.c * * SL82C105/Winbond 553 IDE driver * diff --git a/drivers/block/trm290.c b/drivers/block/trm290.c index 4ec1d09c6..fb5e8d1af 100644 --- a/drivers/block/trm290.c +++ b/drivers/block/trm290.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/trm290.c Version 1.01 December 5, 1997 + * linux/drivers/block/trm290.c Version 1.01 December 5, 1997 * * Copyright (c) 1997-1998 Mark Lord * May be copied or modified under the terms of the GNU General Public License diff --git a/drivers/block/umc8672.c b/drivers/block/umc8672.c index 13f5f39a7..02b581a28 100644 --- a/drivers/block/umc8672.c +++ b/drivers/block/umc8672.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/umc8672.c Version 0.05 Jul 31, 1996 + * linux/drivers/block/umc8672.c Version 0.05 Jul 31, 1996 * * Copyright (C) 1995-1996 Linus Torvalds & author (see below) */ @@ -76,7 +76,7 @@ static void out_umc (char port,char wert) outb_p (wert,0x109); } -static byte in_umc (char port) +static inline byte in_umc (char port) { outb_p (port,0x108); return inb_p (0x109); @@ -125,7 +125,7 @@ static void tune_umc (ide_drive_t *drive, byte pio) restore_flags(flags); /* all CPUs */ } -void init_umc8672 (void) /* called from ide.c */ +void __init init_umc8672 (void) /* called from ide.c */ { unsigned long flags; diff --git a/drivers/block/via82cxxx.c b/drivers/block/via82cxxx.c index 09c4a86a7..54681f38c 100644 --- a/drivers/block/via82cxxx.c +++ b/drivers/block/via82cxxx.c @@ -1,9 +1,10 @@ /* - * linux/drivers/block/via82cxxx.c Version 0.06 Dec. 13, 1999 + * linux/drivers/block/via82cxxx.c Version 0.07 Feb. 10, 2000 * - * Copyright (C) 1998-99 Michel Aubry, Maintainer - * Copyright (C) 1999 Jeff Garzik, MVP4 Support (jgarzik@mandrakesoft.com) - * Copyright (C) 1998-99 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-99 Michel Aubry, Maintainer + * Copyright (C) 1999 Jeff Garzik, MVP4 Support + * (jgarzik@mandrakesoft.com) + * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) * May be copied or modified under the terms of the GNU General Public License * * The VIA MVP-4 is reported OK with UDMA. @@ -473,12 +474,6 @@ static int via_set_fifoconfig(ide_hwif_t *hwif) !(newfifo & 0x03) ? "1" : (!(newfifo & 0x02) ? "3/4" : (newfifo & 0x01) ? "1/4" : "1/2")); - -#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) - via_proc = 1; - bmide_dev = hwif->pci_dev; - via_display_info = &via_get_info; -#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS*/ return 0; } @@ -530,6 +525,12 @@ unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name) printk("\n"); } +#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) + via_proc = 1; + bmide_dev = dev; + via_display_info = &via_get_info; +#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS*/ + return 0; } @@ -555,7 +556,7 @@ void __init ide_init_via82cxxx (ide_hwif_t *hwif) } /* - * ide_dmacapable_via82c568(ide_hwif_t *, unsigned long) + * ide_dmacapable_via82cxxx(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. |