diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/Kconfig | 128 | ||||
-rw-r--r-- | drivers/ide/Makefile | 106 | ||||
-rw-r--r-- | drivers/ide/aec62xx.c (renamed from drivers/ide/pci/aec62xx.c) | 8 | ||||
-rw-r--r-- | drivers/ide/ali14xx.c (renamed from drivers/ide/legacy/ali14xx.c) | 2 | ||||
-rw-r--r-- | drivers/ide/alim15x3.c (renamed from drivers/ide/pci/alim15x3.c) | 15 | ||||
-rw-r--r-- | drivers/ide/amd74xx.c (renamed from drivers/ide/pci/amd74xx.c) | 8 | ||||
-rw-r--r-- | drivers/ide/arm/Makefile | 10 | ||||
-rw-r--r-- | drivers/ide/atiixp.c (renamed from drivers/ide/pci/atiixp.c) | 6 | ||||
-rw-r--r-- | drivers/ide/au1xxx-ide.c (renamed from drivers/ide/mips/au1xxx-ide.c) | 34 | ||||
-rw-r--r-- | drivers/ide/buddha.c (renamed from drivers/ide/legacy/buddha.c) | 0 | ||||
-rw-r--r-- | drivers/ide/cmd640.c (renamed from drivers/ide/pci/cmd640.c) | 18 | ||||
-rw-r--r-- | drivers/ide/cmd64x.c (renamed from drivers/ide/pci/cmd64x.c) | 10 | ||||
-rw-r--r-- | drivers/ide/cs5520.c (renamed from drivers/ide/pci/cs5520.c) | 4 | ||||
-rw-r--r-- | drivers/ide/cs5530.c (renamed from drivers/ide/pci/cs5530.c) | 6 | ||||
-rw-r--r-- | drivers/ide/cs5535.c (renamed from drivers/ide/pci/cs5535.c) | 8 | ||||
-rw-r--r-- | drivers/ide/cy82c693.c (renamed from drivers/ide/pci/cy82c693.c) | 124 | ||||
-rw-r--r-- | drivers/ide/delkin_cb.c (renamed from drivers/ide/pci/delkin_cb.c) | 69 | ||||
-rw-r--r-- | drivers/ide/dtc2278.c (renamed from drivers/ide/legacy/dtc2278.c) | 0 | ||||
-rw-r--r-- | drivers/ide/falconide.c (renamed from drivers/ide/legacy/falconide.c) | 0 | ||||
-rw-r--r-- | drivers/ide/gayle.c (renamed from drivers/ide/legacy/gayle.c) | 0 | ||||
-rw-r--r-- | drivers/ide/generic.c (renamed from drivers/ide/pci/generic.c) | 6 | ||||
-rw-r--r-- | drivers/ide/h8300/Makefile | 2 | ||||
-rw-r--r-- | drivers/ide/hpt366.c (renamed from drivers/ide/pci/hpt366.c) | 50 | ||||
-rw-r--r-- | drivers/ide/ht6560b.c (renamed from drivers/ide/legacy/ht6560b.c) | 9 | ||||
-rw-r--r-- | drivers/ide/icside.c (renamed from drivers/ide/arm/icside.c) | 23 | ||||
-rw-r--r-- | drivers/ide/ide-4drives.c (renamed from drivers/ide/legacy/ide-4drives.c) | 2 | ||||
-rw-r--r-- | drivers/ide/ide-acpi.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide-atapi.c | 185 | ||||
-rw-r--r-- | drivers/ide/ide-cd.c | 302 | ||||
-rw-r--r-- | drivers/ide/ide-cd.h | 1 | ||||
-rw-r--r-- | drivers/ide/ide-cd_ioctl.c | 8 | ||||
-rw-r--r-- | drivers/ide/ide-cs.c (renamed from drivers/ide/legacy/ide-cs.c) | 158 | ||||
-rw-r--r-- | drivers/ide/ide-disk.c | 671 | ||||
-rw-r--r-- | drivers/ide/ide-disk.h | 29 | ||||
-rw-r--r-- | drivers/ide/ide-disk_ioctl.c | 27 | ||||
-rw-r--r-- | drivers/ide/ide-disk_proc.c | 129 | ||||
-rw-r--r-- | drivers/ide/ide-dma-sff.c | 356 | ||||
-rw-r--r-- | drivers/ide/ide-dma.c | 481 | ||||
-rw-r--r-- | drivers/ide/ide-floppy.c | 675 | ||||
-rw-r--r-- | drivers/ide/ide-floppy.h | 54 | ||||
-rw-r--r-- | drivers/ide/ide-floppy_ioctl.c | 67 | ||||
-rw-r--r-- | drivers/ide/ide-floppy_proc.c | 33 | ||||
-rw-r--r-- | drivers/ide/ide-gd.c | 398 | ||||
-rw-r--r-- | drivers/ide/ide-gd.h | 44 | ||||
-rw-r--r-- | drivers/ide/ide-generic.c | 51 | ||||
-rw-r--r-- | drivers/ide/ide-h8300.c (renamed from drivers/ide/h8300/ide-h8300.c) | 2 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 241 | ||||
-rw-r--r-- | drivers/ide/ide-ioctls.c | 21 | ||||
-rw-r--r-- | drivers/ide/ide-iops.c | 97 | ||||
-rw-r--r-- | drivers/ide/ide-lib.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-park.c | 121 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 220 | ||||
-rw-r--r-- | drivers/ide/ide-proc.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 182 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 128 | ||||
-rw-r--r-- | drivers/ide/ide.c | 135 | ||||
-rw-r--r-- | drivers/ide/ide_arm.c (renamed from drivers/ide/arm/ide_arm.c) | 0 | ||||
-rw-r--r-- | drivers/ide/ide_platform.c (renamed from drivers/ide/legacy/ide_platform.c) | 0 | ||||
-rw-r--r-- | drivers/ide/it8213.c (renamed from drivers/ide/pci/it8213.c) | 6 | ||||
-rw-r--r-- | drivers/ide/it821x.c (renamed from drivers/ide/pci/it821x.c) | 46 | ||||
-rw-r--r-- | drivers/ide/jmicron.c (renamed from drivers/ide/pci/jmicron.c) | 6 | ||||
-rw-r--r-- | drivers/ide/legacy/Makefile | 25 | ||||
-rw-r--r-- | drivers/ide/macide.c (renamed from drivers/ide/legacy/macide.c) | 0 | ||||
-rw-r--r-- | drivers/ide/mips/Makefile | 3 | ||||
-rw-r--r-- | drivers/ide/ns87415.c (renamed from drivers/ide/pci/ns87415.c) | 21 | ||||
-rw-r--r-- | drivers/ide/opti621.c (renamed from drivers/ide/pci/opti621.c) | 8 | ||||
-rw-r--r-- | drivers/ide/palm_bk3710.c (renamed from drivers/ide/arm/palm_bk3710.c) | 0 | ||||
-rw-r--r-- | drivers/ide/pci/Makefile | 44 | ||||
-rw-r--r-- | drivers/ide/pci/hpt34x.c | 193 | ||||
-rw-r--r-- | drivers/ide/pdc202xx_new.c (renamed from drivers/ide/pci/pdc202xx_new.c) | 6 | ||||
-rw-r--r-- | drivers/ide/pdc202xx_old.c (renamed from drivers/ide/pci/pdc202xx_old.c) | 14 | ||||
-rw-r--r-- | drivers/ide/piix.c (renamed from drivers/ide/pci/piix.c) | 46 | ||||
-rw-r--r-- | drivers/ide/pmac.c (renamed from drivers/ide/ppc/pmac.c) | 71 | ||||
-rw-r--r-- | drivers/ide/ppc/Makefile | 2 | ||||
-rw-r--r-- | drivers/ide/q40ide.c (renamed from drivers/ide/legacy/q40ide.c) | 0 | ||||
-rw-r--r-- | drivers/ide/qd65xx.c (renamed from drivers/ide/legacy/qd65xx.c) | 2 | ||||
-rw-r--r-- | drivers/ide/qd65xx.h (renamed from drivers/ide/legacy/qd65xx.h) | 0 | ||||
-rw-r--r-- | drivers/ide/rapide.c (renamed from drivers/ide/arm/rapide.c) | 0 | ||||
-rw-r--r-- | drivers/ide/rz1000.c (renamed from drivers/ide/pci/rz1000.c) | 6 | ||||
-rw-r--r-- | drivers/ide/sc1200.c (renamed from drivers/ide/pci/sc1200.c) | 12 | ||||
-rw-r--r-- | drivers/ide/scc_pata.c (renamed from drivers/ide/pci/scc_pata.c) | 33 | ||||
-rw-r--r-- | drivers/ide/serverworks.c (renamed from drivers/ide/pci/serverworks.c) | 8 | ||||
-rw-r--r-- | drivers/ide/sgiioc4.c (renamed from drivers/ide/pci/sgiioc4.c) | 100 | ||||
-rw-r--r-- | drivers/ide/siimage.c (renamed from drivers/ide/pci/siimage.c) | 17 | ||||
-rw-r--r-- | drivers/ide/sis5513.c (renamed from drivers/ide/pci/sis5513.c) | 6 | ||||
-rw-r--r-- | drivers/ide/sl82c105.c (renamed from drivers/ide/pci/sl82c105.c) | 8 | ||||
-rw-r--r-- | drivers/ide/slc90e66.c (renamed from drivers/ide/pci/slc90e66.c) | 6 | ||||
-rw-r--r-- | drivers/ide/tc86c001.c (renamed from drivers/ide/pci/tc86c001.c) | 8 | ||||
-rw-r--r-- | drivers/ide/triflex.c (renamed from drivers/ide/pci/triflex.c) | 15 | ||||
-rw-r--r-- | drivers/ide/trm290.c (renamed from drivers/ide/pci/trm290.c) | 10 | ||||
-rw-r--r-- | drivers/ide/umc8672.c (renamed from drivers/ide/legacy/umc8672.c) | 0 | ||||
-rw-r--r-- | drivers/ide/via82cxxx.c (renamed from drivers/ide/pci/via82cxxx.c) | 6 |
92 files changed, 2907 insertions, 3311 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index b50b5dac95b..a820ca6fc32 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -4,7 +4,7 @@ # Select HAVE_IDE if IDE is supported config HAVE_IDE - def_bool n + bool menuconfig IDE tristate "ATA/ATAPI/MFM/RLL support" @@ -54,38 +54,6 @@ menuconfig IDE if IDE -config BLK_DEV_IDE - tristate "Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support" - ---help--- - If you say Y here, you will use the full-featured IDE driver to - control up to ten ATA/IDE interfaces, each being able to serve a - "master" and a "slave" device, for a total of up to twenty ATA/IDE - disk/cdrom/tape/floppy drives. - - Useful information about large (>540 MB) IDE disks, multiple - interfaces, what to do if ATA/IDE devices are not automatically - detected, sound card ATA/IDE ports, module support, and other - topics, is contained in <file:Documentation/ide/ide.txt>. For detailed - information about hard drives, consult the Disk-HOWTO and the - Multi-Disk-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - To fine-tune ATA/IDE drive/interface parameters for improved - performance, look for the hdparm package at - <ftp://ibiblio.org/pub/Linux/system/hardware/>. - - To compile this driver as a module, choose M here and read - <file:Documentation/ide/ide.txt>. The module will be called ide-mod. - Do not compile this driver as a module if your root file system (the - one containing the directory /) is located on an IDE device. - - If you have one or more IDE drives, say Y or M here. If your system - has no IDE drives, or if memory requirements are really tight, you - could say N here, and select the "Old hard disk driver" below - instead to save about 13 KB of memory in the kernel. - -if BLK_DEV_IDE - comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" config IDE_TIMINGS @@ -116,21 +84,40 @@ config BLK_DEV_IDE_SATA If unsure, say N. -config BLK_DEV_IDEDISK - tristate "Include IDE/ATA-2 DISK support" - ---help--- - This will include enhanced support for MFM/RLL/IDE hard disks. If - you have a MFM/RLL/IDE disk, and there is no special reason to use - the old hard disk driver instead, say Y. If you have an SCSI-only - system, you can say N here. +config IDE_GD + tristate "generic ATA/ATAPI disk support" + default y + help + Support for ATA/ATAPI disks (including ATAPI floppy drives). - To compile this driver as a module, choose M here: the - module will be called ide-disk. - Do not compile this driver as a module if your root file system - (the one containing the directory /) is located on the IDE disk. + To compile this driver as a module, choose M here. + The module will be called ide-gd_mod. + + If unsure, say Y. + +config IDE_GD_ATA + bool "ATA disk support" + depends on IDE_GD + default y + help + This will include support for ATA hard disks. If unsure, say Y. +config IDE_GD_ATAPI + bool "ATAPI floppy support" + depends on IDE_GD + select IDE_ATAPI + help + This will include support for ATAPI floppy drives + (i.e. Iomega ZIP or MKE LS-120). + + For information about jumper settings and the question + of when a ZIP drive uses a partition table, see + <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>. + + If unsure, say N. + config BLK_DEV_IDECS tristate "PCMCIA IDE support" depends on PCMCIA @@ -195,29 +182,6 @@ config BLK_DEV_IDETAPE To compile this driver as a module, choose M here: the module will be called ide-tape. -config BLK_DEV_IDEFLOPPY - tristate "Include IDE/ATAPI FLOPPY support" - select IDE_ATAPI - ---help--- - If you have an IDE floppy drive which uses the ATAPI protocol, - answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy - drives, similar to the SCSI protocol. - - The LS-120 and the IDE/ATAPI Iomega ZIP drive are also supported by - this driver. For information about jumper settings and the question - of when a ZIP drive uses a partition table, see - <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>. - (ATAPI PD-CD/CDR drives are not supported by this driver; support - for PD-CD/CDR drives is available if you answer Y to - "SCSI emulation support", below). - - If you say Y here, the FLOPPY drive will be identified along with - other IDE devices, as "hdb" or "hdc", or something similar (check - the boot messages with dmesg). - - To compile this driver as a module, choose M here: the - module will be called ide-floppy. - config BLK_DEV_IDESCSI tristate "SCSI emulation support (DEPRECATED)" depends on SCSI @@ -348,7 +312,7 @@ config BLK_DEV_IDEPCI config IDEPCI_PCIBUS_ORDER bool "Probe IDE PCI devices in the PCI bus order (DEPRECATED)" - depends on BLK_DEV_IDE=y && BLK_DEV_IDEPCI + depends on IDE=y && BLK_DEV_IDEPCI default y help Probe IDE PCI devices in the order in which they appear on the @@ -364,7 +328,7 @@ config IDEPCI_PCIBUS_ORDER # TODO: split it on per host driver config options (or module parameters) config BLK_DEV_OFFBOARD bool "Boot off-board chipsets first support (DEPRECATED)" - depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT34X || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001) + depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001) help Normally, IDE controllers built into the motherboard (on-board controllers) are assigned to ide0 and ide1 while those on add-in PCI @@ -514,28 +478,6 @@ config BLK_DEV_CS5535 It is safe to say Y to this question. -config BLK_DEV_HPT34X - tristate "HPT34X chipset support" - depends on BROKEN - select BLK_DEV_IDEDMA_PCI - help - This driver adds up to 4 more EIDE devices sharing a single - interrupt. The HPT343 chipset in its current form is a non-bootable - controller; the HPT345/HPT363 chipset is a bootable (needs BIOS FIX) - PCI UDMA controllers. This driver requires dynamic tuning of the - chipset during the ide-probe at boot time. It is reported to support - DVD II drives, by the manufacturer. - -config HPT34X_AUTODMA - bool "HPT34X AUTODMA support (EXPERIMENTAL)" - depends on BLK_DEV_HPT34X && EXPERIMENTAL - help - This is a dangerous thing to attempt currently! Please read the - comments at the top of <file:drivers/ide/pci/hpt34x.c>. If you say Y - here, then say Y to "Use DMA by default when available" as well. - - If unsure, say N. - config BLK_DEV_HPT366 tristate "HPT36X/37X chipset support" select BLK_DEV_IDEDMA_PCI @@ -729,7 +671,7 @@ endif config BLK_DEV_IDE_PMAC tristate "PowerMac on-board IDE support" - depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y + depends on PPC_PMAC && IDE=y select IDE_TIMINGS help This driver provides support for the on-board IDE controller on @@ -963,6 +905,4 @@ config BLK_DEV_IDEDMA def_bool BLK_DEV_IDEDMA_SFF || BLK_DEV_IDEDMA_PMAC || \ BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA -endif - endif # IDE diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 308b8a12f31..9cf92ac939d 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -5,53 +5,109 @@ EXTRA_CFLAGS += -Idrivers/ide ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ - ide-taskfile.o ide-pio-blacklist.o + ide-taskfile.o ide-park.o ide-pio-blacklist.o # core IDE code ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o +ide-core-$(CONFIG_BLK_DEV_IDEDMA_SFF) += ide-dma-sff.o ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o -obj-$(CONFIG_BLK_DEV_IDE) += ide-core.o +obj-$(CONFIG_IDE) += ide-core.o -ifeq ($(CONFIG_IDE_ARM), y) - ide-arm-core-y += arm/ide_arm.o - obj-y += ide-arm-core.o -endif +obj-$(CONFIG_IDE_ARM) += ide_arm.o + +obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o +obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o +obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o +obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o +obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o +obj-$(CONFIG_BLK_DEV_4DRIVES) += ide-4drives.o + +obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o +obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o +obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o +obj-$(CONFIG_BLK_DEV_Q40IDE) += q40ide.o +obj-$(CONFIG_BLK_DEV_BUDDHA) += buddha.o + +obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o +obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o +obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o +obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o +obj-$(CONFIG_BLK_DEV_CELLEB) += scc_pata.o +obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o +obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o +obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o +obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o +obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o +obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o +obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o +obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o +obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o +obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o +obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o +obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o +obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o +obj-$(CONFIG_BLK_DEV_PDC202XX_OLD) += pdc202xx_old.o +obj-$(CONFIG_BLK_DEV_PDC202XX_NEW) += pdc202xx_new.o +obj-$(CONFIG_BLK_DEV_PIIX) += piix.o +obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o +obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o +obj-$(CONFIG_BLK_DEV_SGIIOC4) += sgiioc4.o +obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o +obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o +obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o +obj-$(CONFIG_BLK_DEV_SLC90E66) += slc90e66.o +obj-$(CONFIG_BLK_DEV_TC86C001) += tc86c001.o +obj-$(CONFIG_BLK_DEV_TRIFLEX) += triflex.o +obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o +obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o -obj-$(CONFIG_BLK_DEV_IDE) += legacy/ pci/ +# Must appear at the end of the block +obj-$(CONFIG_BLK_DEV_GENERIC) += ide-pci-generic.o +ide-pci-generic-y += generic.o obj-$(CONFIG_IDEPCI_PCIBUS_ORDER) += ide-scan-pci.o -ifeq ($(CONFIG_BLK_DEV_CMD640), y) - cmd640-core-y += pci/cmd640.o - obj-y += cmd640-core.o -endif +obj-$(CONFIG_BLK_DEV_CMD640) += cmd640.o + +obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o + +obj-$(CONFIG_IDE_H8300) += ide-h8300.o -obj-$(CONFIG_BLK_DEV_IDE) += ppc/ -obj-$(CONFIG_IDE_H8300) += h8300/ obj-$(CONFIG_IDE_GENERIC) += ide-generic.o obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o +ide-gd_mod-y += ide-gd.o ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o -ide-floppy_mod-y += ide-floppy.o ide-floppy_ioctl.o -obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o +ifeq ($(CONFIG_IDE_GD_ATA), y) + ide-gd_mod-y += ide-disk.o ide-disk_ioctl.o +ifeq ($(CONFIG_IDE_PROC_FS), y) + ide-gd_mod-y += ide-disk_proc.o +endif +endif + +ifeq ($(CONFIG_IDE_GD_ATAPI), y) + ide-gd_mod-y += ide-floppy.o ide-floppy_ioctl.o +ifeq ($(CONFIG_IDE_PROC_FS), y) + ide-gd_mod-y += ide-floppy_proc.o +endif +endif + +obj-$(CONFIG_IDE_GD) += ide-gd_mod.o obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o -obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy_mod.o obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o -ifeq ($(CONFIG_BLK_DEV_IDECS), y) - ide-cs-core-y += legacy/ide-cs.o - obj-y += ide-cs-core.o -endif +obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o -ifeq ($(CONFIG_BLK_DEV_PLATFORM), y) - ide-platform-core-y += legacy/ide_platform.o - obj-y += ide-platform-core.o -endif +obj-$(CONFIG_BLK_DEV_PLATFORM) += ide_platform.o + +obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o +obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o +obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o -obj-$(CONFIG_BLK_DEV_IDE) += arm/ mips/ +obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/aec62xx.c index e7475ba559c..4142c698e0d 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/aec62xx.c @@ -115,7 +115,7 @@ static void aec6260_set_mode(ide_drive_t *drive, const u8 speed) struct pci_dev *dev = to_pci_dev(hwif->dev); struct ide_host *host = pci_get_drvdata(dev); struct chipset_bus_clock_list_entry *bus_clock = host->host_priv; - u8 unit = (drive->select.b.unit & 0x01); + u8 unit = drive->dn & 1; u8 tmp1 = 0, tmp2 = 0; u8 ultra = 0, drive_conf = 0, ultra_conf = 0; unsigned long flags; @@ -302,7 +302,7 @@ static const struct pci_device_id aec62xx_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver aec62xx_pci_driver = { .name = "AEC62xx_IDE", .id_table = aec62xx_pci_tbl, .probe = aec62xx_init_one, @@ -313,12 +313,12 @@ static struct pci_driver driver = { static int __init aec62xx_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&aec62xx_pci_driver); } static void __exit aec62xx_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&aec62xx_pci_driver); } module_init(aec62xx_ide_init); diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/ali14xx.c index 7276c96aaa2..90da1f953ed 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/ali14xx.c @@ -131,7 +131,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) drive->name, pio, time1, time2, param1, param2, param3, param4); /* stuff timing parameters into controller registers */ - driveNum = (HWIF(drive)->index << 1) + drive->select.b.unit; + driveNum = (drive->hwif->index << 1) + (drive->dn & 1); spin_lock_irqsave(&ali14xx_lock, flags); outb_p(regOn, basePort); outReg(param1, regTab[driveNum].reg1); diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/alim15x3.c index 053c7526391..daf9dce39e5 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -77,8 +77,7 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) int bus_speed = ide_pci_clk ? ide_pci_clk : 33; int port = hwif->channel ? 0x5c : 0x58; int portFIFO = hwif->channel ? 0x55 : 0x54; - u8 cd_dma_fifo = 0; - int unit = drive->select.b.unit & 1; + u8 cd_dma_fifo = 0, unit = drive->dn & 1; if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8) s_clc = 0; @@ -112,7 +111,7 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) } pci_write_config_byte(dev, port, s_clc); - pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc); + pci_write_config_byte(dev, port + unit + 2, (a_clc << 4) | r_clc); local_irq_restore(flags); } @@ -154,7 +153,7 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); u8 speed1 = speed; - u8 unit = (drive->select.b.unit & 0x01); + u8 unit = drive->dn & 1; u8 tmpbyte = 0x00; int m5229_udma = (hwif->channel) ? 0x57 : 0x56; @@ -508,7 +507,7 @@ static const struct ide_dma_ops ali_dma_ops = { .dma_setup = ali15x3_dma_setup, .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, - .dma_end = __ide_dma_end, + .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, .dma_timeout = ide_dma_timeout, @@ -576,7 +575,7 @@ static const struct pci_device_id alim15x3_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver alim15x3_pci_driver = { .name = "ALI15x3_IDE", .id_table = alim15x3_pci_tbl, .probe = alim15x3_init_one, @@ -587,12 +586,12 @@ static struct pci_driver driver = { static int __init ali15x3_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&alim15x3_pci_driver); } static void __exit ali15x3_ide_exit(void) { - return pci_unregister_driver(&driver); + return pci_unregister_driver(&alim15x3_pci_driver); } module_init(ali15x3_ide_init); diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/amd74xx.c index 824471f91bf..81ec73134ed 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/amd74xx.c @@ -92,7 +92,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed) ide_timing_compute(drive, speed, &t, T, UT); - if (peer->present) { + if (peer->dev_flags & IDE_DFLAG_PRESENT) { ide_timing_compute(peer, peer->current_speed, &p, T, UT); ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); } @@ -319,7 +319,7 @@ static const struct pci_device_id amd74xx_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver amd74xx_pci_driver = { .name = "AMD_IDE", .id_table = amd74xx_pci_tbl, .probe = amd74xx_probe, @@ -330,12 +330,12 @@ static struct pci_driver driver = { static int __init amd74xx_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&amd74xx_pci_driver); } static void __exit amd74xx_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&amd74xx_pci_driver); } module_init(amd74xx_ide_init); diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile deleted file mode 100644 index 5bc26053afa..00000000000 --- a/drivers/ide/arm/Makefile +++ /dev/null @@ -1,10 +0,0 @@ - -obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o -obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o -obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o - -ifeq ($(CONFIG_IDE_ARM), m) - obj-m += ide_arm.o -endif - -EXTRA_CFLAGS := -Idrivers/ide diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/atiixp.c index e4437034dd0..b2735d28f5c 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/atiixp.c @@ -182,7 +182,7 @@ static const struct pci_device_id atiixp_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver atiixp_pci_driver = { .name = "ATIIXP_IDE", .id_table = atiixp_pci_tbl, .probe = atiixp_init_one, @@ -193,12 +193,12 @@ static struct pci_driver driver = { static int __init atiixp_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&atiixp_pci_driver); } static void __exit atiixp_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&atiixp_pci_driver); } module_init(atiixp_ide_init); diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c index 11b7f61aae4..0ec8fd1e4dc 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/au1xxx-ide.c @@ -322,11 +322,7 @@ static int auide_dma_setup(ide_drive_t *drive) } static int auide_dma_test_irq(ide_drive_t *drive) -{ - if (drive->waiting_for_dma == 0) - printk(KERN_WARNING "%s: ide_dma_test_irq \ - called while not waiting\n", drive->name); - +{ /* If dbdma didn't execute the STOP command yet, the * active bit is still set */ @@ -344,11 +340,6 @@ static void auide_dma_host_set(ide_drive_t *drive, int on) { } -static void auide_dma_lost_irq(ide_drive_t *drive) -{ - printk(KERN_ERR "%s: IRQ lost\n", drive->name); -} - static void auide_ddma_tx_callback(int irq, void *param) { _auide_hwif *ahwif = (_auide_hwif*)param; @@ -375,18 +366,6 @@ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 de } #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA -static void auide_dma_timeout(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - - printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); - - if (auide_dma_test_irq(drive)) - return; - - auide_dma_end(drive); -} - static const struct ide_dma_ops au1xxx_dma_ops = { .dma_host_set = auide_dma_host_set, .dma_setup = auide_dma_setup, @@ -394,8 +373,8 @@ static const struct ide_dma_ops au1xxx_dma_ops = { .dma_start = auide_dma_start, .dma_end = auide_dma_end, .dma_test_irq = auide_dma_test_irq, - .dma_lost_irq = auide_dma_lost_irq, - .dma_timeout = auide_dma_timeout, + .dma_lost_irq = ide_dma_lost_irq, + .dma_timeout = ide_dma_timeout, }; static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d) @@ -448,10 +427,9 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d) NUM_DESCRIPTORS); auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan, NUM_DESCRIPTORS); - - hwif->dmatable_cpu = dma_alloc_coherent(hwif->dev, - PRD_ENTRIES * PRD_BYTES, /* 1 Page */ - &hwif->dmatable_dma, GFP_KERNEL); + + /* FIXME: check return value */ + (void)ide_allocate_dma_engine(hwif); au1xxx_dbdma_start( auide->tx_chan ); au1xxx_dbdma_start( auide->rx_chan ); diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/buddha.c index c5a3c9ef6a5..c5a3c9ef6a5 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/buddha.c diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/cmd640.c index 7f39cdb4141..e4306647d00 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/cmd640.c @@ -378,13 +378,13 @@ static void __set_prefetch_mode(ide_drive_t *drive, int mode) { if (mode) { /* want prefetch on? */ #if CMD640_PREFETCH_MASKS - drive->no_unmask = 1; - drive->unmask = 0; + drive->dev_flags |= IDE_DFLAG_NO_UNMASK; + drive->dev_flags &= ~IDE_DFLAG_UNMASK; #endif - drive->no_io_32bit = 0; + drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT; } else { - drive->no_unmask = 0; - drive->no_io_32bit = 1; + drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK; + drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT; drive->io_32bit = 0; } } @@ -468,10 +468,10 @@ static void program_drive_counts(ide_drive_t *drive, unsigned int index) */ if (index > 1) { ide_hwif_t *hwif = drive->hwif; - ide_drive_t *peer = &hwif->drives[!drive->select.b.unit]; + ide_drive_t *peer = &hwif->drives[!(drive->dn & 1)]; unsigned int mate = index ^ 1; - if (peer->present) { + if (peer->dev_flags & IDE_DFLAG_PRESENT) { if (setup_count < setup_counts[mate]) setup_count = setup_counts[mate]; if (active_count < active_counts[mate]) @@ -607,7 +607,7 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) static void cmd640_init_dev(ide_drive_t *drive) { - unsigned int i = drive->hwif->channel * 2 + drive->select.b.unit; + unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1); #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED /* @@ -626,7 +626,7 @@ static void cmd640_init_dev(ide_drive_t *drive) */ check_prefetch(drive, i); printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n", - i, drive->no_io_32bit ? "off" : "on"); + i, (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) ? "off" : "on"); #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ } diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/cmd64x.c index 456dee18b66..935385c77e0 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -228,7 +228,7 @@ static int cmd648_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); unsigned long base = hwif->dma_base - (hwif->channel * 8); - int err = __ide_dma_end(drive); + int err = ide_dma_end(drive); u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0; u8 mrdmode = inb(base + 1); @@ -248,7 +248,7 @@ static int cmd64x_dma_end(ide_drive_t *drive) u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; u8 irq_stat = 0; - int err = __ide_dma_end(drive); + int err = ide_dma_end(drive); (void) pci_read_config_byte(dev, irq_reg, &irq_stat); /* clear the interrupt bit */ @@ -505,7 +505,7 @@ static const struct pci_device_id cmd64x_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cmd64x_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver cmd64x_pci_driver = { .name = "CMD64x_IDE", .id_table = cmd64x_pci_tbl, .probe = cmd64x_init_one, @@ -516,12 +516,12 @@ static struct pci_driver driver = { static int __init cmd64x_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&cmd64x_pci_driver); } static void __exit cmd64x_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&cmd64x_pci_driver); } module_init(cmd64x_ide_init); diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/cs5520.c index d6341f7c414..5efb467f8fa 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/cs5520.c @@ -145,7 +145,7 @@ static const struct pci_device_id cs5520_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cs5520_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver cs5520_pci_driver = { .name = "Cyrix_IDE", .id_table = cs5520_pci_tbl, .probe = cs5520_init_one, @@ -155,7 +155,7 @@ static struct pci_driver driver = { static int __init cs5520_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&cs5520_pci_driver); } module_init(cs5520_ide_init); diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/cs5530.c index da42fa7e9f9..53f079cc00a 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/cs5530.c @@ -267,7 +267,7 @@ static const struct pci_device_id cs5530_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cs5530_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver cs5530_pci_driver = { .name = "CS5530 IDE", .id_table = cs5530_pci_tbl, .probe = cs5530_init_one, @@ -278,12 +278,12 @@ static struct pci_driver driver = { static int __init cs5530_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&cs5530_pci_driver); } static void __exit cs5530_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&cs5530_pci_driver); } module_init(cs5530_ide_init); diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/cs5535.c index 1e5bc59ea2f..983d957a018 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/cs5535.c @@ -76,7 +76,7 @@ static unsigned int cs5535_udma_timings[5] = static void cs5535_set_speed(ide_drive_t *drive, const u8 speed) { u32 reg = 0, dummy; - int unit = drive->select.b.unit; + u8 unit = drive->dn & 1; /* Set the PIO timings */ if (speed < XFER_SW_DMA_0) { @@ -192,7 +192,7 @@ static const struct pci_device_id cs5535_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver cs5535_pci_driver = { .name = "CS5535_IDE", .id_table = cs5535_pci_tbl, .probe = cs5535_init_one, @@ -203,12 +203,12 @@ static struct pci_driver driver = { static int __init cs5535_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&cs5535_pci_driver); } static void __exit cs5535_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&cs5535_pci_driver); } module_init(cs5535_ide_init); diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/cy82c693.c index 69820e9224d..5297f07d293 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/cy82c693.c @@ -50,18 +50,11 @@ #define DRV_NAME "cy82c693" -/* the current version */ -#define CY82_VERSION "CY82C693U driver v0.34 99-13-12 Andreas S. Krebs (akrebs@altavista.net)" - /* * The following are used to debug the driver. */ -#define CY82C693_DEBUG_LOGS 0 #define CY82C693_DEBUG_INFO 0 -/* define CY82C693_SETDMA_CLOCK to set DMA Controller Clock Speed to ATCLK */ -#undef CY82C693_SETDMA_CLOCK - /* * NOTE: the value for busmaster timeout is tricky and I got it by * trial and error! By using a to low value will cause DMA timeouts @@ -89,7 +82,6 @@ #define CY82_INDEX_PORT 0x22 #define CY82_DATA_PORT 0x23 -#define CY82_INDEX_CTRLREG1 0x01 #define CY82_INDEX_CHANNEL0 0x30 #define CY82_INDEX_CHANNEL1 0x31 #define CY82_INDEX_TIMEOUT 0x32 @@ -179,17 +171,6 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode) index = hwif->channel ? CY82_INDEX_CHANNEL1 : CY82_INDEX_CHANNEL0; -#if CY82C693_DEBUG_LOGS - /* for debug let's show the previous values */ - - outb(index, CY82_INDEX_PORT); - data = inb(CY82_DATA_PORT); - - printk(KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", - drive->name, HWIF(drive)->channel, drive->select.b.unit, - (data&0x3), ((data>>2)&1)); -#endif /* CY82C693_DEBUG_LOGS */ - data = (mode & 3) | (single << 2); outb(index, CY82_INDEX_PORT); @@ -197,8 +178,7 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode) #if CY82C693_DEBUG_INFO printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", - drive->name, HWIF(drive)->channel, drive->select.b.unit, - mode & 3, single); + drive->name, hwif->channel, drive->dn & 1, mode & 3, single); #endif /* CY82C693_DEBUG_INFO */ /* @@ -239,50 +219,11 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) } } -#if CY82C693_DEBUG_LOGS - /* for debug let's show the register values */ - - if (drive->select.b.unit == 0) { - /* - * get master drive registers - * address setup control register - * is 32 bit !!! - */ - pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); - addrCtrl &= 0x0F; - - /* now let's get the remaining registers */ - pci_read_config_byte(dev, CY82_IDE_MASTER_IOR, &pclk.time_16r); - pci_read_config_byte(dev, CY82_IDE_MASTER_IOW, &pclk.time_16w); - pci_read_config_byte(dev, CY82_IDE_MASTER_8BIT, &pclk.time_8); - } else { - /* - * set slave drive registers - * address setup control register - * is 32 bit !!! - */ - pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); - - addrCtrl &= 0xF0; - addrCtrl >>= 4; - - /* now let's get the remaining registers */ - pci_read_config_byte(dev, CY82_IDE_SLAVE_IOR, &pclk.time_16r); - pci_read_config_byte(dev, CY82_IDE_SLAVE_IOW, &pclk.time_16w); - pci_read_config_byte(dev, CY82_IDE_SLAVE_8BIT, &pclk.time_8); - } - - printk(KERN_INFO "%s (ch=%d, dev=%d): PIO timing is " - "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", - drive->name, hwif->channel, drive->select.b.unit, - addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); -#endif /* CY82C693_DEBUG_LOGS */ - /* let's calc the values for this PIO mode */ compute_clocks(pio, &pclk); /* now let's write the clocks registers */ - if (drive->select.b.unit == 0) { + if ((drive->dn & 1) == 0) { /* * set master drive * address setup control register @@ -324,63 +265,11 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) #if CY82C693_DEBUG_INFO printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to " "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", - drive->name, hwif->channel, drive->select.b.unit, + drive->name, hwif->channel, drive->dn & 1, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); #endif /* CY82C693_DEBUG_INFO */ } -/* - * this function is called during init and is used to setup the cy82c693 chip - */ -static unsigned int init_chipset_cy82c693(struct pci_dev *dev) -{ - if (PCI_FUNC(dev->devfn) != 1) - return 0; - -#ifdef CY82C693_SETDMA_CLOCK - u8 data = 0; -#endif /* CY82C693_SETDMA_CLOCK */ - - /* write info about this verion of the driver */ - printk(KERN_INFO CY82_VERSION "\n"); - -#ifdef CY82C693_SETDMA_CLOCK - /* okay let's set the DMA clock speed */ - - outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); - data = inb(CY82_DATA_PORT); - -#if CY82C693_DEBUG_INFO - printk(KERN_INFO DRV_NAME ": Peripheral Configuration Register: 0x%X\n", - data); -#endif /* CY82C693_DEBUG_INFO */ - - /* - * for some reason sometimes the DMA controller - * speed is set to ATCLK/2 ???? - we fix this here - * - * note: i don't know what causes this strange behaviour, - * but even changing the dma speed doesn't solve it :-( - * the ide performance is still only half the normal speed - * - * if anybody knows what goes wrong with my machine, please - * let me know - ASK - */ - - data |= 0x03; - - outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); - outb(data, CY82_DATA_PORT); - -#if CY82C693_DEBUG_INFO - printk(KERN_INFO ": New Peripheral Configuration Register: 0x%X\n", - data); -#endif /* CY82C693_DEBUG_INFO */ - -#endif /* CY82C693_SETDMA_CLOCK */ - return 0; -} - static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) { static ide_hwif_t *primary; @@ -401,7 +290,6 @@ static const struct ide_port_ops cy82c693_port_ops = { static const struct ide_port_info cy82c693_chipset __devinitdata = { .name = DRV_NAME, - .init_chipset = init_chipset_cy82c693, .init_iops = init_iops_cy82c693, .port_ops = &cy82c693_port_ops, .chipset = ide_cy82c693, @@ -443,7 +331,7 @@ static const struct pci_device_id cy82c693_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cy82c693_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver cy82c693_pci_driver = { .name = "Cypress_IDE", .id_table = cy82c693_pci_tbl, .probe = cy82c693_init_one, @@ -454,12 +342,12 @@ static struct pci_driver driver = { static int __init cy82c693_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&cy82c693_pci_driver); } static void __exit cy82c693_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&cy82c693_pci_driver); } module_init(cy82c693_ide_init); diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/delkin_cb.c index 83b63b365e5..8f1b2d9f051 100644 --- a/drivers/ide/pci/delkin_cb.c +++ b/drivers/ide/delkin_cb.c @@ -46,10 +46,27 @@ static const struct ide_port_ops delkin_cb_port_ops = { .quirkproc = ide_undecoded_slave, }; +static unsigned int delkin_cb_init_chipset(struct pci_dev *dev) +{ + unsigned long base = pci_resource_start(dev, 0); + int i; + + outb(0x02, base + 0x1e); /* set nIEN to block interrupts */ + inb(base + 0x17); /* read status to clear interrupts */ + + for (i = 0; i < sizeof(setup); ++i) { + if (setup[i]) + outb(setup[i], base + i); + } + + return 0; +} + static const struct ide_port_info delkin_cb_port_info = { .port_ops = &delkin_cb_port_ops, .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | IDE_HFLAG_NO_DMA, + .init_chipset = delkin_cb_init_chipset, }; static int __devinit @@ -57,7 +74,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) { struct ide_host *host; unsigned long base; - int i, rc; + int rc; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; rc = pci_enable_device(dev); @@ -72,12 +89,8 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) return rc; } base = pci_resource_start(dev, 0); - outb(0x02, base + 0x1e); /* set nIEN to block interrupts */ - inb(base + 0x17); /* read status to clear interrupts */ - for (i = 0; i < sizeof(setup); ++i) { - if (setup[i]) - outb(setup[i], base + i); - } + + delkin_cb_init_chipset(dev); memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base + 0x10, base + 0x1e); @@ -110,6 +123,40 @@ delkin_cb_remove (struct pci_dev *dev) pci_disable_device(dev); } +#ifdef CONFIG_PM +static int delkin_cb_suspend(struct pci_dev *dev, pm_message_t state) +{ + pci_save_state(dev); + pci_disable_device(dev); + pci_set_power_state(dev, pci_choose_state(dev, state)); + + return 0; +} + +static int delkin_cb_resume(struct pci_dev *dev) +{ + struct ide_host *host = pci_get_drvdata(dev); + int rc; + + pci_set_power_state(dev, PCI_D0); + + rc = pci_enable_device(dev); + if (rc) + return rc; + + pci_restore_state(dev); + pci_set_master(dev); + + if (host->init_chipset) + host->init_chipset(dev); + + return 0; +} +#else +#define delkin_cb_suspend NULL +#define delkin_cb_resume NULL +#endif + static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -117,21 +164,23 @@ static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { }; MODULE_DEVICE_TABLE(pci, delkin_cb_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver delkin_cb_pci_driver = { .name = "Delkin-ASKA-Workbit Cardbus IDE", .id_table = delkin_cb_pci_tbl, .probe = delkin_cb_probe, .remove = delkin_cb_remove, + .suspend = delkin_cb_suspend, + .resume = delkin_cb_resume, }; static int __init delkin_cb_init(void) { - return pci_register_driver(&driver); + return pci_register_driver(&delkin_cb_pci_driver); } static void __exit delkin_cb_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&delkin_cb_pci_driver); } module_init(delkin_cb_init); diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/dtc2278.c index 689b2e49341..689b2e49341 100644 --- a/drivers/ide/legacy/dtc2278.c +++ b/drivers/ide/dtc2278.c diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/falconide.c index 39d500d84b0..39d500d84b0 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/falconide.c diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/gayle.c index 69150688656..69150688656 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/gayle.c diff --git a/drivers/ide/pci/generic.c b/drivers/ide/generic.c index 092b238cb25..474f96a7c07 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/generic.c @@ -166,7 +166,7 @@ static const struct pci_device_id generic_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, generic_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver generic_pci_driver = { .name = "PCI_IDE", .id_table = generic_pci_tbl, .probe = generic_init_one, @@ -177,12 +177,12 @@ static struct pci_driver driver = { static int __init generic_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&generic_pci_driver); } static void __exit generic_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&generic_pci_driver); } module_init(generic_ide_init); diff --git a/drivers/ide/h8300/Makefile b/drivers/ide/h8300/Makefile deleted file mode 100644 index 5eba16f423f..00000000000 --- a/drivers/ide/h8300/Makefile +++ /dev/null @@ -1,2 +0,0 @@ - -obj-$(CONFIG_IDE_H8300) += ide-h8300.o diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/hpt366.c index a194022b6a6..a7909e9c720 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/hpt366.c @@ -3,7 +3,7 @@ * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc * Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz - * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. + * Portions Copyright (C) 2005-2008 MontaVista Software, Inc. * * Thanks to HighPoint Technologies for their assistance, and hardware. * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his @@ -748,26 +748,24 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask) struct pci_dev *dev = to_pci_dev(hwif->dev); struct hpt_info *info = hpt3xx_get_info(hwif->dev); - if (drive->quirk_list) { - if (info->chip_type >= HPT370) { - u8 scr1 = 0; - - pci_read_config_byte(dev, 0x5a, &scr1); - if (((scr1 & 0x10) >> 4) != mask) { - if (mask) - scr1 |= 0x10; - else - scr1 &= ~0x10; - pci_write_config_byte(dev, 0x5a, scr1); - } - } else { + if (drive->quirk_list == 0) + return; + + if (info->chip_type >= HPT370) { + u8 scr1 = 0; + + pci_read_config_byte(dev, 0x5a, &scr1); + if (((scr1 & 0x10) >> 4) != mask) { if (mask) - disable_irq(hwif->irq); + scr1 |= 0x10; else - enable_irq (hwif->irq); + scr1 &= ~0x10; + pci_write_config_byte(dev, 0x5a, scr1); } - } else - outb(ATA_DEVCTL_OBS | (mask ? 2 : 0), hwif->io_ports.ctl_addr); + } else if (mask) + disable_irq(hwif->irq); + else + enable_irq(hwif->irq); } /* @@ -835,7 +833,7 @@ static int hpt370_dma_end(ide_drive_t *drive) if (dma_stat & 0x01) hpt370_irq_timeout(drive); } - return __ide_dma_end(drive); + return ide_dma_end(drive); } static void hpt370_dma_timeout(ide_drive_t *drive) @@ -863,9 +861,6 @@ static int hpt374_dma_test_irq(ide_drive_t *drive) if (dma_stat & 4) return 1; - if (!drive->waiting_for_dma) - printk(KERN_WARNING "%s: (%s) called while not waiting\n", - drive->name, __func__); return 0; } @@ -880,7 +875,7 @@ static int hpt374_dma_end(ide_drive_t *drive) pci_read_config_byte(dev, mcr_addr, &mcr); if (bwsr & mask) pci_write_config_byte(dev, mcr_addr, mcr | 0x30); - return __ide_dma_end(drive); + return ide_dma_end(drive); } /** @@ -1292,7 +1287,6 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) { - struct pci_dev *dev = to_pci_dev(hwif->dev); struct hpt_info *info = hpt3xx_get_info(hwif->dev); int serialize = HPT_SERIALIZE_IO; u8 chip_type = info->chip_type; @@ -1456,7 +1450,7 @@ static const struct ide_dma_ops hpt36x_dma_ops = { .dma_setup = ide_dma_setup, .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, - .dma_end = __ide_dma_end, + .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = hpt366_dma_lost_irq, .dma_timeout = ide_dma_timeout, @@ -1622,7 +1616,7 @@ static const struct pci_device_id hpt366_pci_tbl[] __devinitconst = { }; MODULE_DEVICE_TABLE(pci, hpt366_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver hpt366_pci_driver = { .name = "HPT366_IDE", .id_table = hpt366_pci_tbl, .probe = hpt366_init_one, @@ -1633,12 +1627,12 @@ static struct pci_driver driver = { static int __init hpt366_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&hpt366_pci_driver); } static void __exit hpt366_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&hpt366_pci_driver); } module_init(hpt366_ide_init); diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/ht6560b.c index 5123ea291d0..c7e5c2246b7 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/ht6560b.c @@ -120,7 +120,8 @@ static void ht6560b_selectproc (ide_drive_t *drive) * Need to enforce prefetch sometimes because otherwise * it'll hang (hard). */ - if (drive->media != ide_disk || !drive->present) + if (drive->media != ide_disk || + (drive->dev_flags & IDE_DFLAG_PRESENT) == 0) select |= HT_PREFETCH_MODE; if (select != current_select || timing != current_timing) { @@ -249,11 +250,11 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state) */ if (state) { drive->drive_data |= t; /* enable prefetch mode */ - drive->no_unmask = 1; - drive->unmask = 0; + drive->dev_flags |= IDE_DFLAG_NO_UNMASK; + drive->dev_flags &= ~IDE_DFLAG_UNMASK; } else { drive->drive_data &= ~t; /* disable prefetch mode */ - drive->no_unmask = 0; + drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK; } spin_unlock_irqrestore(&ht6560b_lock, flags); diff --git a/drivers/ide/arm/icside.c b/drivers/ide/icside.c index 70f5b164828..76bdc9a27f6 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/icside.c @@ -372,25 +372,6 @@ static int icside_dma_test_irq(ide_drive_t *drive) ICS_ARCIN_V6_INTRSTAT_1)) & 1; } -static void icside_dma_timeout(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - - printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); - - if (icside_dma_test_irq(drive)) - return; - - ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif)); - - icside_dma_end(drive); -} - -static void icside_dma_lost_irq(ide_drive_t *drive) -{ - printk(KERN_ERR "%s: IRQ lost\n", drive->name); -} - static int icside_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d) { hwif->dmatable_cpu = NULL; @@ -406,8 +387,8 @@ static const struct ide_dma_ops icside_v6_dma_ops = { .dma_start = icside_dma_start, .dma_end = icside_dma_end, .dma_test_irq = icside_dma_test_irq, - .dma_timeout = icside_dma_timeout, - .dma_lost_irq = icside_dma_lost_irq, + .dma_timeout = ide_dma_timeout, + .dma_lost_irq = ide_dma_lost_irq, }; #else #define icside_v6_dma_ops NULL diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/ide-4drives.c index c76d55de699..9e85b1ec960 100644 --- a/drivers/ide/legacy/ide-4drives.c +++ b/drivers/ide/ide-4drives.c @@ -14,7 +14,7 @@ MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); static void ide_4drives_init_dev(ide_drive_t *drive) { if (drive->hwif->channel) - drive->select.all ^= 0x20; + drive->select ^= 0x20; } static const struct ide_port_ops ide_4drives_port_ops = { diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 2427c380b3d..244a8a052ce 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -290,7 +290,7 @@ static int do_drive_get_GTF(ide_drive_t *drive, DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n", hwif->name, dev->bus_id, port, hwif->channel); - if (!drive->present) { + if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) { DEBPRINT("%s drive %d:%d not present\n", hwif->name, hwif->channel, port); goto out; @@ -420,8 +420,9 @@ static int do_drive_set_taskfiles(ide_drive_t *drive, DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn); - if (!drive->present) + if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) goto out; + if (!gtf_count) /* shouldn't be here */ goto out; @@ -660,7 +661,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) if (!drive->acpidata->obj_handle) drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive); - if (drive->acpidata->obj_handle && drive->present) { + if (drive->acpidata->obj_handle && + (drive->dev_flags & IDE_DFLAG_PRESENT)) { acpi_bus_set_power(drive->acpidata->obj_handle, on? ACPI_STATE_D0: ACPI_STATE_D3); } @@ -720,7 +722,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) memset(drive->acpidata, 0, sizeof(*drive->acpidata)); - if (!drive->present) + if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) continue; err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff); @@ -745,7 +747,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) for (i = 0; i < MAX_DRIVES; i++) { drive = &hwif->drives[i]; - if (drive->present) + if (drive->dev_flags & IDE_DFLAG_PRESENT) /* Execute ACPI startup code */ ide_acpi_exec_tfs(drive); } diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 608c5bade92..4e58b9e7a58 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -124,8 +124,8 @@ EXPORT_SYMBOL_GPL(ide_init_pc); * the current request, so that it will be processed immediately, on the next * pass through the driver. */ -void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, - struct ide_atapi_pc *pc, struct request *rq) +static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, + struct ide_atapi_pc *pc, struct request *rq) { blk_rq_init(NULL, rq); rq->cmd_type = REQ_TYPE_SPECIAL; @@ -137,7 +137,6 @@ void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, rq->cmd[13] = REQ_IDETAPE_PC1; ide_do_drive_cmd(drive, rq); } -EXPORT_SYMBOL_GPL(ide_queue_pc_head); /* * Add a special packet command request to the tail of the request queue, @@ -192,7 +191,7 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on) { struct ide_atapi_pc pc; - if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK) + if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) return 0; ide_init_pc(&pc); @@ -203,25 +202,80 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on) } EXPORT_SYMBOL_GPL(ide_set_media_lock); -/* TODO: unify the code thus making some arguments go away */ -ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, - ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, - void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), - void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *), - int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int)) +void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc) { + ide_init_pc(pc); + pc->c[0] = REQUEST_SENSE; + if (drive->media == ide_floppy) { + pc->c[4] = 255; + pc->req_xfer = 18; + } else { + pc->c[4] = 20; + pc->req_xfer = 20; + } +} +EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd); + +/* + * Called when an error was detected during the last packet command. + * We queue a request sense packet command in the head of the request list. + */ +void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk) +{ + struct request *rq = &drive->request_sense_rq; + struct ide_atapi_pc *pc = &drive->request_sense_pc; + + (void)ide_read_error(drive); + ide_create_request_sense_cmd(drive, pc); + if (drive->media == ide_tape) + set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); + ide_queue_pc_head(drive, disk, pc, rq); +} +EXPORT_SYMBOL_GPL(ide_retry_pc); + +int ide_scsi_expiry(ide_drive_t *drive) +{ + struct ide_atapi_pc *pc = drive->pc; + + debug_log("%s called for %lu at %lu\n", __func__, + pc->scsi_cmd->serial_number, jiffies); + + pc->flags |= PC_FLAG_TIMEDOUT; + + return 0; /* we do not want the IDE subsystem to retry */ +} +EXPORT_SYMBOL_GPL(ide_scsi_expiry); + +/* + * This is the usual interrupt handler which will be called during a packet + * command. We will transfer some of the data (as requested by the drive) + * and will re-point interrupt handler to us. + */ +static ide_startstop_t ide_pc_intr(ide_drive_t *drive) +{ + struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->hwgroup->rq; const struct ide_tp_ops *tp_ops = hwif->tp_ops; xfer_func_t *xferfunc; - unsigned int temp; + ide_expiry_t *expiry; + unsigned int timeout, temp; u16 bcount; - u8 stat, ireason, scsi = drive->scsi; + u8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0; debug_log("Enter %s - interrupt handler\n", __func__); + if (scsi) { + timeout = ide_scsi_get_timeout(pc); + expiry = ide_scsi_expiry; + } else { + timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD + : WAIT_TAPE_CMD; + expiry = NULL; + } + if (pc->flags & PC_FLAG_TIMEDOUT) { - drive->pc_callback(drive); + drive->pc_callback(drive, 0); return ide_stopped; } @@ -238,8 +292,8 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, pc->flags |= PC_FLAG_DMA_ERROR; } else { pc->xferred = pc->req_xfer; - if (update_buffers) - update_buffers(drive, pc); + if (drive->pc_update_buffers) + drive->pc_update_buffers(drive, pc); } debug_log("%s: DMA finished\n", drive->name); } @@ -276,21 +330,19 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, debug_log("[cmd %x]: check condition\n", rq->cmd[0]); /* Retry operation */ - retry_pc(drive); + ide_retry_pc(drive, rq->rq_disk); /* queued, but not started */ return ide_stopped; } cmd_finished: pc->error = 0; - if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && - (stat & ATA_DSC) == 0) { - dsc_handle(drive); - return ide_stopped; - } + + if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) + dsc = 1; /* Command finished - Call the callback function */ - drive->pc_callback(drive); + drive->pc_callback(drive, dsc); return ide_stopped; } @@ -336,7 +388,8 @@ cmd_finished: temp = 0; if (temp) { if (pc->sg) - io_buffers(drive, pc, temp, 0); + drive->pc_io_buffers(drive, pc, + temp, 0); else tp_ops->input_data(drive, NULL, pc->cur_pos, temp); @@ -348,9 +401,7 @@ cmd_finished: pc->xferred += temp; pc->cur_pos += temp; ide_pad_transfer(drive, 0, bcount - temp); - ide_set_handler(drive, handler, timeout, - expiry); - return ide_started; + goto next_irq; } debug_log("The device wants to send us more data than " "expected - allowing transfer\n"); @@ -362,7 +413,7 @@ cmd_finished: if ((drive->media == ide_floppy && !scsi && !pc->buf) || (drive->media == ide_tape && !scsi && pc->bh) || (scsi && pc->sg)) { - int done = io_buffers(drive, pc, bcount, + int done = drive->pc_io_buffers(drive, pc, bcount, !!(pc->flags & PC_FLAG_WRITING)); /* FIXME: don't do partial completions */ @@ -377,12 +428,11 @@ cmd_finished: debug_log("[cmd %x] transferred %d bytes on that intr.\n", rq->cmd[0], bcount); - +next_irq: /* And set the interrupt handler again */ - ide_set_handler(drive, handler, timeout, expiry); + ide_set_handler(drive, ide_pc_intr, timeout, expiry); return ide_started; } -EXPORT_SYMBOL_GPL(ide_pc_intr); static u8 ide_read_ireason(ide_drive_t *drive) { @@ -418,12 +468,22 @@ static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) return ireason; } -ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, - ide_handler_t *handler, unsigned int timeout, - ide_expiry_t *expiry) +static int ide_delayed_transfer_pc(ide_drive_t *drive) { + /* Send the actual packet */ + drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12); + + /* Timeout for the packet command */ + return WAIT_FLOPPY_CMD; +} + +static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) +{ + struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->hwgroup->rq; + ide_expiry_t *expiry; + unsigned int timeout; ide_startstop_t startstop; u8 ireason; @@ -434,7 +494,8 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, } ireason = ide_read_ireason(drive); - if (drive->media == ide_tape && !drive->scsi) + if (drive->media == ide_tape && + (drive->dev_flags & IDE_DFLAG_SCSI) == 0) ireason = ide_wait_ireason(drive, ireason); if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { @@ -443,8 +504,27 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, return ide_do_reset(drive); } + /* + * If necessary schedule the packet transfer to occur 'timeout' + * miliseconds later in ide_delayed_transfer_pc() after the device + * says it's ready for a packet. + */ + if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { + timeout = drive->pc_delay; + expiry = &ide_delayed_transfer_pc; + } else { + if (drive->dev_flags & IDE_DFLAG_SCSI) { + timeout = ide_scsi_get_timeout(pc); + expiry = ide_scsi_expiry; + } else { + timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD + : WAIT_TAPE_CMD; + expiry = NULL; + } + } + /* Set the interrupt routine */ - ide_set_handler(drive, handler, timeout, expiry); + ide_set_handler(drive, ide_pc_intr, timeout, expiry); /* Begin DMA, if necessary */ if (pc->flags & PC_FLAG_DMA_OK) { @@ -458,22 +538,22 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, return ide_started; } -EXPORT_SYMBOL_GPL(ide_transfer_pc); -ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, - ide_handler_t *handler, unsigned int timeout, +ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, ide_expiry_t *expiry) { + struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; + u32 tf_flags; u16 bcount; - u8 dma = 0; + u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI); /* We haven't transferred any data yet */ pc->xferred = 0; pc->cur_pos = pc->buf; /* Request to transfer the entire buffer at once */ - if (drive->media == ide_tape && !drive->scsi) + if (drive->media == ide_tape && scsi == 0) bcount = pc->req_xfer; else bcount = min(pc->req_xfer, 63 * 1024); @@ -483,28 +563,35 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, ide_dma_off(drive); } - if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) { - if (drive->scsi) + if ((pc->flags & PC_FLAG_DMA_OK) && + (drive->dev_flags & IDE_DFLAG_USING_DMA)) { + if (scsi) hwif->sg_mapped = 1; - dma = !hwif->dma_ops->dma_setup(drive); - if (drive->scsi) + drive->dma = !hwif->dma_ops->dma_setup(drive); + if (scsi) hwif->sg_mapped = 0; } - if (!dma) + if (!drive->dma) pc->flags &= ~PC_FLAG_DMA_OK; - ide_pktcmd_tf_load(drive, drive->scsi ? 0 : IDE_TFLAG_OUT_DEVICE, - bcount, dma); + if (scsi) + tf_flags = 0; + else if (drive->media == ide_cdrom || drive->media == ide_optical) + tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; + else + tf_flags = IDE_TFLAG_OUT_DEVICE; + + ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); /* Issue the packet command */ if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { - ide_execute_command(drive, ATA_CMD_PACKET, handler, + ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, timeout, NULL); return ide_started; } else { ide_execute_pkt_cmd(drive); - return (*handler)(drive); + return ide_transfer_pc(drive); } } EXPORT_SYMBOL_GPL(ide_issue_pc); diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 465a92ca017..13265a8827d 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -23,6 +23,9 @@ * Documentation/ide/ChangeLog.ide-cd.1994-2004 */ +#define DRV_NAME "ide-cd" +#define PFX DRV_NAME ": " + #define IDECD_VERSION "5.00" #include <linux/module.h> @@ -50,12 +53,15 @@ #include "ide-cd.h" -static DEFINE_MUTEX(idecd_ref_mutex); +#define IDECD_DEBUG_LOG 1 -#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref) +#if IDECD_DEBUG_LOG +#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) +#else +#define ide_debug_log(lvl, fmt, args...) do {} while (0) +#endif -#define ide_cd_g(disk) \ - container_of((disk)->private_data, struct cdrom_info, driver) +static DEFINE_MUTEX(idecd_ref_mutex); static void ide_cd_release(struct kref *); @@ -64,7 +70,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk) struct cdrom_info *cd = NULL; mutex_lock(&idecd_ref_mutex); - cd = ide_cd_g(disk); + cd = ide_drv_g(disk, cdrom_info); if (cd) { if (ide_device_get(cd->drive)) cd = NULL; @@ -93,7 +99,7 @@ static void ide_cd_put(struct cdrom_info *cd) /* Mark that we've seen a media change and invalidate our internal buffers. */ static void cdrom_saw_media_change(ide_drive_t *drive) { - drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED; + drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; } @@ -102,6 +108,9 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, { int log = 0; + ide_debug_log(IDE_DBG_SENSE, "Call %s, sense_key: 0x%x\n", __func__, + sense->sense_key); + if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) return 0; @@ -150,6 +159,14 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, unsigned long bio_sectors; struct cdrom_info *info = drive->driver_data; + ide_debug_log(IDE_DBG_SENSE, "Call %s, error_code: 0x%x, " + "sense_key: 0x%x\n", __func__, sense->error_code, + sense->sense_key); + + if (failed_command) + ide_debug_log(IDE_DBG_SENSE, "%s: failed cmd: 0x%x\n", + __func__, failed_command->cmd[0]); + if (!cdrom_log_sense(drive, failed_command, sense)) return; @@ -200,6 +217,8 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, struct cdrom_info *info = drive->driver_data; struct request *rq = &info->request_sense_request; + ide_debug_log(IDE_DBG_SENSE, "Call %s\n", __func__); + if (sense == NULL) sense = &info->sense_data; @@ -219,6 +238,10 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, /* NOTE! Save the failed command in "rq->buffer" */ rq->buffer = (void *) failed_command; + if (failed_command) + ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n", + failed_command->cmd[0]); + ide_do_drive_cmd(drive, rq); } @@ -227,6 +250,10 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) struct request *rq = HWGROUP(drive)->rq; int nsectors = rq->hard_cur_sectors; + ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, " + "nsectors: %d\n", __func__, rq->cmd[0], uptodate, + nsectors); + if (blk_sense_request(rq) && uptodate) { /* * For REQ_TYPE_SENSE, "rq->buffer" points to the original @@ -269,6 +296,9 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) if (!nsectors) nsectors = 1; + ide_debug_log(IDE_DBG_FUNC, "Exit %s, uptodate: 0x%x, nsectors: %d\n", + __func__, uptodate, nsectors); + ide_end_request(drive, uptodate, nsectors); } @@ -304,11 +334,15 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) sense_key = err >> 4; if (rq == NULL) { - printk(KERN_ERR "%s: missing rq in %s\n", + printk(KERN_ERR PFX "%s: missing rq in %s\n", drive->name, __func__); return 1; } + ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " + "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n", + __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err); + if (blk_sense_request(rq)) { /* * We got an error trying to get sense info from the drive @@ -374,7 +408,8 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) cdrom_saw_media_change(drive); /* fail the request */ - printk(KERN_ERR "%s: tray open\n", drive->name); + printk(KERN_ERR PFX "%s: tray open\n", + drive->name); do_end_request = 1; } else { struct cdrom_info *info = drive->driver_data; @@ -460,7 +495,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) if (stat & ATA_ERR) cdrom_queue_request_sense(drive, NULL, NULL); } else { - blk_dump_rq_flags(rq, "ide-cd: bad rq"); + blk_dump_rq_flags(rq, PFX "bad rq"); cdrom_end_request(drive, 0); } @@ -488,6 +523,9 @@ static int cdrom_timer_expiry(ide_drive_t *drive) struct request *rq = HWGROUP(drive)->rq; unsigned long wait = 0; + ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd[0]: 0x%x\n", __func__, + rq->cmd[0]); + /* * Some commands are *slow* and normally take a long time to complete. * Usually we can use the ATAPI "disconnect" to bypass this, but not all @@ -504,7 +542,7 @@ static int cdrom_timer_expiry(ide_drive_t *drive) break; default: if (!(rq->cmd_flags & REQ_QUIET)) - printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", + printk(KERN_INFO PFX "cmd 0x%x timed out\n", rq->cmd[0]); wait = 0; break; @@ -524,20 +562,21 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, int xferlen, ide_handler_t *handler) { - struct cdrom_info *info = drive->driver_data; ide_hwif_t *hwif = drive->hwif; + ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen); + /* FIXME: for Virtual DMA we must check harder */ - if (info->dma) - info->dma = !hwif->dma_ops->dma_setup(drive); + if (drive->dma) + drive->dma = !hwif->dma_ops->dma_setup(drive); /* set up the controller registers */ ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL, - xferlen, info->dma); + xferlen, drive->dma); if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { /* waiting for CDB interrupt, not DMA yet. */ - if (info->dma) + if (drive->dma) drive->waiting_for_dma = 0; /* packet command */ @@ -564,9 +603,10 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, { ide_hwif_t *hwif = drive->hwif; int cmd_len; - struct cdrom_info *info = drive->driver_data; ide_startstop_t startstop; + ide_debug_log(IDE_DBG_PC, "Call %s\n", __func__); + if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { /* * Here we should have been called after receiving an interrupt @@ -578,7 +618,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, return ide_stopped; /* ok, next interrupt will be DMA interrupt */ - if (info->dma) + if (drive->dma) drive->waiting_for_dma = 1; } else { /* otherwise, we must wait for DRQ to get set */ @@ -599,7 +639,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); /* start the DMA if need be */ - if (info->dma) + if (drive->dma) hwif->dma_ops->dma_start(drive); return ide_started; @@ -615,6 +655,9 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, { ide_hwif_t *hwif = drive->hwif; + ide_debug_log(IDE_DBG_FUNC, "Call %s, ireason: 0x%x, rw: 0x%x\n", + __func__, ireason, rw); + /* * ireason == 0: the drive wants to receive data from us * ireason == 2: the drive is expecting to transfer data to us @@ -624,7 +667,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, else if (ireason == (rw << 1)) { /* whoops... */ - printk(KERN_ERR "%s: %s: wrong transfer direction!\n", + printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n", drive->name, __func__); ide_pad_transfer(drive, rw, len); @@ -637,7 +680,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, return 0; } else { /* drive wants a command packet, or invalid ireason... */ - printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n", + printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n", drive->name, __func__, ireason); } @@ -654,17 +697,19 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, */ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) { + ide_debug_log(IDE_DBG_FUNC, "Call %s, len: %d\n", __func__, len); + if ((len % SECTOR_SIZE) == 0) return 0; - printk(KERN_ERR "%s: %s: Bad transfer size %d\n", - drive->name, __func__, len); + printk(KERN_ERR PFX "%s: %s: Bad transfer size %d\n", drive->name, + __func__, len); if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES) - printk(KERN_ERR " This drive is not supported by " - "this version of the driver\n"); + printk(KERN_ERR PFX "This drive is not supported by this " + "version of the driver\n"); else { - printk(KERN_ERR " Trying to limit transfer sizes\n"); + printk(KERN_ERR PFX "Trying to limit transfer sizes\n"); drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES; } @@ -676,6 +721,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, struct request *rq) { + ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd_flags: 0x%x\n", __func__, + rq->cmd_flags); + if (rq_data_dir(rq) == READ) { unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; @@ -695,7 +743,7 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, /* sanity check... */ if (rq->current_nr_sectors != bio_cur_sectors(rq->bio)) { - printk(KERN_ERR "%s: %s: buffer botch (%u)\n", + printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n", drive->name, __func__, rq->current_nr_sectors); cdrom_end_request(drive, 0); @@ -704,11 +752,7 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, rq->current_nr_sectors += nskip; } } -#if 0 - else - /* the immediate bit */ - rq->cmd[1] = 1 << 3; -#endif + /* set up the command */ rq->timeout = ATAPI_WAIT_PC; @@ -739,6 +783,8 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive) int stat; static int retry = 10; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + if (cdrom_decode_status(drive, 0, &stat)) return ide_stopped; @@ -746,7 +792,7 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive) if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) { if (--retry == 0) - drive->dsc_overlap = 0; + drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; } return ide_stopped; } @@ -755,6 +801,8 @@ static void ide_cd_prepare_seek_request(ide_drive_t *drive, struct request *rq) { sector_t frame = rq->sector; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS); memset(rq->cmd, 0, BLK_MAX_CDB); @@ -775,8 +823,11 @@ static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) * Fix up a possibly partially-processed request so that we can start it over * entirely, or even put it back on the request queue. */ -static void restore_request(struct request *rq) +static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) { + + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + if (rq->buffer != bio_data(rq->bio)) { sector_t n = (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE; @@ -792,11 +843,11 @@ static void restore_request(struct request *rq) rq->q->prep_rq_fn(rq->q, rq); } -/* - * All other packet commands. - */ -static void ide_cd_request_sense_fixup(struct request *rq) +static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) { + ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n", + __func__, rq->cmd[0]); + /* * Some of the trailing request sense fields are optional, * and some drives don't send them. Sigh. @@ -822,6 +873,10 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, if (!sense) sense = &local_sense; + ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, " + "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write, + timeout, cmd_flags); + /* start of retry loop */ do { struct request *rq; @@ -895,7 +950,6 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq) static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - struct cdrom_info *info = drive->driver_data; struct request *rq = HWGROUP(drive)->rq; xfer_func_t *xferfunc; ide_expiry_t *expiry = NULL; @@ -905,13 +959,16 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) u16 len; u8 ireason; + ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x\n", + __func__, rq->cmd[0], write); + /* check for errors */ - dma = info->dma; + dma = drive->dma; if (dma) { - info->dma = 0; + drive->dma = 0; dma_error = hwif->dma_ops->dma_end(drive); if (dma_error) { - printk(KERN_ERR "%s: DMA %s error\n", drive->name, + printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name, write ? "write" : "read"); ide_dma_off(drive); } @@ -937,6 +994,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (thislen > len) thislen = len; + ide_debug_log(IDE_DBG_PC, "%s: DRQ: stat: 0x%x, thislen: %d\n", + __func__, stat, thislen); + /* If DRQ is clear, the command has completed. */ if ((stat & ATA_DRQ) == 0) { if (blk_fs_request(rq)) { @@ -946,7 +1006,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) */ uptodate = 1; if (rq->current_nr_sectors > 0) { - printk(KERN_ERR "%s: %s: data underrun " + printk(KERN_ERR PFX "%s: %s: data underrun " "(%d blocks)\n", drive->name, __func__, rq->current_nr_sectors); @@ -957,7 +1017,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) cdrom_end_request(drive, uptodate); return ide_stopped; } else if (!blk_pc_request(rq)) { - ide_cd_request_sense_fixup(rq); + ide_cd_request_sense_fixup(drive, rq); /* complain if we still have data left to transfer */ uptodate = rq->data_len ? 0 : 1; } @@ -1000,6 +1060,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) xferfunc = hwif->tp_ops->input_data; } + ide_debug_log(IDE_DBG_PC, "%s: data transfer, rq->cmd_type: 0x%x, " + "ireason: 0x%x\n", __func__, rq->cmd_type, ireason); + /* transfer data */ while (thislen > 0) { u8 *ptr = blk_fs_request(rq) ? NULL : rq->data; @@ -1024,7 +1087,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) */ ide_pad_transfer(drive, 0, thislen); else { - printk(KERN_ERR "%s: confused, missing data\n", + printk(KERN_ERR PFX "%s: confused, missing data\n", drive->name); blk_dump_rq_flags(rq, rq_data_dir(rq) ? "cdrom_newpc_intr, write" @@ -1111,6 +1174,10 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; + ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, " + "secs_per_frame: %u\n", + __func__, rq->cmd[0], write, sectors_per_frame); + if (write) { /* disk has become write protected */ if (get_disk_ro(cd->disk)) { @@ -1122,7 +1189,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) * We may be retrying this request after an error. Fix up any * weirdness which might be present in the request packet. */ - restore_request(rq); + ide_cd_restore_request(drive, rq); } /* use DMA, if possible / writes *must* be hardware frame aligned */ @@ -1132,9 +1199,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) cdrom_end_request(drive, 0); return ide_stopped; } - cd->dma = 0; + drive->dma = 0; } else - cd->dma = drive->using_dma; + drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); if (write) cd->devinfo.media_written = 1; @@ -1151,14 +1218,17 @@ static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive) static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { - struct cdrom_info *info = drive->driver_data; + + ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, " + "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0], + rq->cmd_type); if (blk_pc_request(rq)) rq->cmd_flags |= REQ_QUIET; else rq->cmd_flags &= ~REQ_FAILED; - info->dma = 0; + drive->dma = 0; /* sg request */ if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) { @@ -1171,7 +1241,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) else buf = rq->data; - info->dma = drive->using_dma; + drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); /* * check if dma is safe @@ -1182,13 +1252,10 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) alignment = queue_dma_alignment(q) | q->dma_pad_mask; if ((unsigned long)buf & alignment || rq->data_len & alignment || object_is_on_stack(buf)) - info->dma = 0; + drive->dma = 0; } } -/* - * cdrom driver request routine. - */ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, sector_t block) { @@ -1196,6 +1263,11 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, ide_handler_t *fn; int xferlen; + ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " + "rq->cmd_type: 0x%x, block: %llu\n", + __func__, rq->cmd[0], rq->cmd_type, + (unsigned long long)block); + if (blk_fs_request(rq)) { if (drive->atapi_flags & IDE_AFLAG_SEEKING) { ide_hwif_t *hwif = drive->hwif; @@ -1208,7 +1280,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, IDECD_SEEK_TIMER); return ide_stopped; } - printk(KERN_ERR "%s: DSC timeout\n", + printk(KERN_ERR PFX "%s: DSC timeout\n", drive->name); } drive->atapi_flags &= ~IDE_AFLAG_SEEKING; @@ -1216,11 +1288,11 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, if (rq_data_dir(rq) == READ && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && - drive->dsc_overlap) { + (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP)) { xferlen = 0; fn = cdrom_start_seek_continuation; - info->dma = 0; + drive->dma = 0; info->start_seek = jiffies; ide_cd_prepare_seek_request(drive, rq); @@ -1249,7 +1321,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, cdrom_end_request(drive, 1); return ide_stopped; } else { - blk_dump_rq_flags(rq, "ide-cd bad flags"); + blk_dump_rq_flags(rq, DRV_NAME " bad flags"); cdrom_end_request(drive, 0); return ide_stopped; } @@ -1279,6 +1351,8 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) struct cdrom_device_info *cdi = &info->devinfo; unsigned char cmd[BLK_MAX_CDB]; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_TEST_UNIT_READY; @@ -1305,6 +1379,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, unsigned len = sizeof(capbuf); u32 blocklen; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_READ_CDVD_CAPACITY; @@ -1324,16 +1400,20 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, case 4096: break; default: - printk(KERN_ERR "%s: weird block size %u\n", - drive->name, blocklen); - printk(KERN_ERR "%s: default to 2kb block size\n", - drive->name); + printk(KERN_ERR PFX "%s: weird block size %u\n", + drive->name, blocklen); + printk(KERN_ERR PFX "%s: default to 2kb block size\n", + drive->name); blocklen = 2048; break; } *capacity = 1 + be32_to_cpu(capbuf.lba); *sectors_per_frame = blocklen >> SECTOR_BITS; + + ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n", + __func__, *capacity, *sectors_per_frame); + return 0; } @@ -1343,6 +1423,8 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, { unsigned char cmd[BLK_MAX_CDB]; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_READ_TOC_PMA_ATIP; @@ -1371,11 +1453,13 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) long last_written; unsigned long sectors_per_frame = SECTORS_PER_FRAME; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + if (toc == NULL) { /* try to allocate space */ toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL); if (toc == NULL) { - printk(KERN_ERR "%s: No cdrom TOC buffer!\n", + printk(KERN_ERR PFX "%s: No cdrom TOC buffer!\n", drive->name); return -ENOMEM; } @@ -1531,6 +1615,8 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) struct packet_command cgc; int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0) size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; @@ -1549,6 +1635,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) struct cdrom_info *cd = drive->driver_data; u16 curspeed, maxspeed; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) { curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]); maxspeed = le16_to_cpup((__le16 *)&buf[8 + 8]); @@ -1557,6 +1645,9 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]); } + ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n", + __func__, curspeed, maxspeed); + cd->current_speed = (curspeed + (176/2)) / 176; cd->max_speed = (maxspeed + (176/2)) / 176; } @@ -1589,6 +1680,8 @@ static int ide_cdrom_register(ide_drive_t *drive, int nslots) struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *devinfo = &info->devinfo; + ide_debug_log(IDE_DBG_PROBE, "Call %s, nslots: %d\n", __func__, nslots); + devinfo->ops = &ide_cdrom_dops; devinfo->speed = info->current_speed; devinfo->capacity = nslots; @@ -1610,13 +1703,17 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) mechtype_t mechtype; int nslots = 1; + ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->media: 0x%x, " + "drive->atapi_flags: 0x%lx\n", __func__, drive->media, + drive->atapi_flags); + cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO | CDC_MO_DRIVE | CDC_RAM); if (drive->media == ide_optical) { cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM); - printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", + printk(KERN_ERR PFX "%s: ATAPI magneto-optical drive\n", drive->name); return nslots; } @@ -1640,7 +1737,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) return 0; if ((buf[8 + 6] & 0x01) == 0) - drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; + drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; if (buf[8 + 6] & 0x08) drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT; if (buf[8 + 3] & 0x01) @@ -1674,7 +1771,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) ide_cdrom_update_speed(drive, buf); - printk(KERN_INFO "%s: ATAPI", drive->name); + printk(KERN_INFO PFX "%s: ATAPI", drive->name); /* don't print speed if the drive reported 0 */ if (cd->max_speed) @@ -1685,7 +1782,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0) printk(KERN_CONT " DVD%s%s", (cdi->mask & CDC_DVD_R) ? "" : "-R", - (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM"); + (cdi->mask & CDC_DVD_RAM) ? "" : "/RAM"); if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0) printk(KERN_CONT " CD%s%s", @@ -1697,7 +1794,8 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) else printk(KERN_CONT " drive"); - printk(KERN_CONT ", %dkB Cache\n", be16_to_cpup((__be16 *)&buf[8 + 12])); + printk(KERN_CONT ", %dkB Cache\n", + be16_to_cpup((__be16 *)&buf[8 + 12])); return nslots; } @@ -1809,12 +1907,22 @@ static ide_proc_entry_t idecd_proc[] = { { NULL, 0, NULL, NULL } }; -ide_devset_rw_field(dsc_overlap, dsc_overlap); +ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP); static const struct ide_proc_devset idecd_settings[] = { IDE_PROC_DEVSET(dsc_overlap, 0, 1), { 0 }, }; + +static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive) +{ + return idecd_proc; +} + +static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive) +{ + return idecd_settings; +} #endif static const struct cd_list_entry ide_cd_quirks_list[] = { @@ -1884,6 +1992,8 @@ static int ide_cdrom_setup(ide_drive_t *drive) char *fw_rev = (char *)&id[ATA_ID_FW_REV]; int nslots; + ide_debug_log(IDE_DBG_PROBE, "Call %s\n", __func__); + blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); blk_queue_dma_alignment(drive->queue, 31); blk_queue_update_dma_pad(drive->queue, 15); @@ -1891,13 +2001,8 @@ static int ide_cdrom_setup(ide_drive_t *drive) if (!drive->queue->unplug_delay) drive->queue->unplug_delay = 1; - drive->special.all = 0; - - drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT | - ide_cd_flags(id); - - if ((id[ATA_ID_CONFIG] & 0x0060) == 0x20) - drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; + drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; + drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id); if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) && fw_rev[4] == '1' && fw_rev[6] <= '2') @@ -1915,10 +2020,13 @@ static int ide_cdrom_setup(ide_drive_t *drive) /* set correct block size */ blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); - drive->dsc_overlap = (drive->next != drive); + if (drive->next != drive) + drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; + else + drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; if (ide_cdrom_register(drive, nslots)) { - printk(KERN_ERR "%s: %s failed to register device with the" + printk(KERN_ERR PFX "%s: %s failed to register device with the" " cdrom driver.\n", drive->name, __func__); cd->devinfo.handle = NULL; return 1; @@ -1932,6 +2040,8 @@ static void ide_cd_remove(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + ide_proc_unregister_driver(drive, info->driver); del_gendisk(info->disk); @@ -1941,15 +2051,17 @@ static void ide_cd_remove(ide_drive_t *drive) static void ide_cd_release(struct kref *kref) { - struct cdrom_info *info = to_ide_cd(kref); + struct cdrom_info *info = to_ide_drv(kref, cdrom_info); struct cdrom_device_info *devinfo = &info->devinfo; ide_drive_t *drive = info->drive; struct gendisk *g = info->disk; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + kfree(info->toc); if (devinfo->handle == drive) unregister_cdrom(devinfo); - drive->dsc_overlap = 0; + drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; drive->driver_data = NULL; blk_queue_prep_rq(drive->queue, NULL); g->private_data = NULL; @@ -1968,13 +2080,12 @@ static ide_driver_t ide_cdrom_driver = { .probe = ide_cd_probe, .remove = ide_cd_remove, .version = IDECD_VERSION, - .media = ide_cdrom, .do_request = ide_cd_do_request, .end_request = ide_end_request, .error = __ide_error, #ifdef CONFIG_IDE_PROC_FS - .proc = idecd_proc, - .settings = idecd_settings, + .proc_entries = ide_cd_proc_entries, + .proc_devsets = ide_cd_proc_devsets, #endif }; @@ -1999,7 +2110,7 @@ static int idecd_open(struct inode *inode, struct file *file) static int idecd_release(struct inode *inode, struct file *file) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct cdrom_info *info = ide_cd_g(disk); + struct cdrom_info *info = ide_drv_g(disk, cdrom_info); cdrom_release(&info->devinfo, file); @@ -2051,7 +2162,7 @@ static int idecd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct block_device *bdev = inode->i_bdev; - struct cdrom_info *info = ide_cd_g(bdev->bd_disk); + struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); int err; switch (cmd) { @@ -2072,13 +2183,13 @@ static int idecd_ioctl(struct inode *inode, struct file *file, static int idecd_media_changed(struct gendisk *disk) { - struct cdrom_info *info = ide_cd_g(disk); + struct cdrom_info *info = ide_drv_g(disk, cdrom_info); return cdrom_media_changed(&info->devinfo); } static int idecd_revalidate_disk(struct gendisk *disk) { - struct cdrom_info *info = ide_cd_g(disk); + struct cdrom_info *info = ide_drv_g(disk, cdrom_info); struct request_sense sense; ide_cd_read_toc(info->drive, &sense); @@ -2097,8 +2208,11 @@ static struct block_device_operations idecd_ops = { /* module options */ static char *ignore; - module_param(ignore, charp, 0400); + +static unsigned long debug_mask; +module_param(debug_mask, ulong, 0644); + MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); static int ide_cd_probe(ide_drive_t *drive) @@ -2107,6 +2221,10 @@ static int ide_cd_probe(ide_drive_t *drive) struct gendisk *g; struct request_sense sense; + ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->driver_req: %s, " + "drive->media: 0x%x\n", __func__, drive->driver_req, + drive->media); + if (!strstr("ide-cdrom", drive->driver_req)) goto failed; @@ -2116,14 +2234,17 @@ static int ide_cd_probe(ide_drive_t *drive) /* skip drives that we were told to ignore */ if (ignore != NULL) { if (strstr(ignore, drive->name)) { - printk(KERN_INFO "ide-cd: ignoring drive %s\n", + printk(KERN_INFO PFX "ignoring drive %s\n", drive->name); goto failed; } } + + drive->debug_mask = debug_mask; + info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); if (info == NULL) { - printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", + printk(KERN_ERR PFX "%s: Can't allocate a cdrom structure\n", drive->name); goto failed; } @@ -2171,6 +2292,7 @@ static void __exit ide_cdrom_exit(void) static int __init ide_cdrom_init(void) { + printk(KERN_INFO DRV_NAME " driver " IDECD_VERSION "\n"); return driver_register(&ide_cdrom_driver.gen_driver); } diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 61a4599b77d..5882b9a9ea8 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -88,7 +88,6 @@ struct cdrom_info { struct request_sense sense_data; struct request request_sense_request; - int dma; unsigned long last_block; unsigned long start_seek; diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index 74231b41f61..df3df0041eb 100644 --- a/drivers/ide/ide-cd_ioctl.c +++ b/drivers/ide/ide-cd_ioctl.c @@ -86,8 +86,8 @@ int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi, if (slot_nr == CDSL_CURRENT) { (void) cdrom_check_status(drive, NULL); - retval = (drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED) ? 1 : 0; - drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED; + retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0; + drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; return retval; } else { return -EINVAL; @@ -136,7 +136,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, sense = &my_sense; /* If the drive cannot lock the door, just pretend. */ - if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK) { + if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) { stat = 0; } else { unsigned char cmd[BLK_MAX_CDB]; @@ -157,7 +157,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, (sense->asc == 0x24 || sense->asc == 0x20)) { printk(KERN_ERR "%s: door locking not supported\n", drive->name); - drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; + drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; stat = 0; } diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/ide-cs.c index ee6fc30d5e2..cb199c815b5 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/ide-cs.c @@ -219,103 +219,91 @@ out_release: #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) +struct pcmcia_config_check { + unsigned long ctl_base; + int skip_vcc; + int is_kme; +}; + +static int pcmcia_check_one_config(struct pcmcia_device *pdev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + struct pcmcia_config_check *stk = priv_data; + + /* Check for matching Vcc, unless we're desperate */ + if (!stk->skip_vcc) { + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) + return -ENODEV; + } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) + return -ENODEV; + } + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) + pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; + + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + pdev->conf.ConfigIndex = cfg->index; + pdev->io.BasePort1 = io->win[0].base; + pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (!(io->flags & CISTPL_IO_16BIT)) + pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + if (io->nwin == 2) { + pdev->io.NumPorts1 = 8; + pdev->io.BasePort2 = io->win[1].base; + pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; + if (pcmcia_request_io(pdev, &pdev->io) != 0) + return -ENODEV; + stk->ctl_base = pdev->io.BasePort2; + } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { + pdev->io.NumPorts1 = io->win[0].len; + pdev->io.NumPorts2 = 0; + if (pcmcia_request_io(pdev, &pdev->io) != 0) + return -ENODEV; + stk->ctl_base = pdev->io.BasePort1 + 0x0e; + } else + return -ENODEV; + /* If we've got this far, we're done */ + return 0; + } + return -ENODEV; +} + static int ide_config(struct pcmcia_device *link) { ide_info_t *info = link->priv; - tuple_t tuple; - struct { - u_short buf[128]; - cisparse_t parse; - config_info_t conf; - cistpl_cftable_entry_t dflt; - } *stk = NULL; - cistpl_cftable_entry_t *cfg; - int pass, last_ret = 0, last_fn = 0, is_kme = 0; + struct pcmcia_config_check *stk = NULL; + int last_ret = 0, last_fn = 0, is_kme = 0; unsigned long io_base, ctl_base; struct ide_host *host; DEBUG(0, "ide_config(0x%p)\n", link); - stk = kzalloc(sizeof(*stk), GFP_KERNEL); - if (!stk) goto err_mem; - cfg = &stk->parse.cftable_entry; - - tuple.TupleData = (cisdata_t *)&stk->buf; - tuple.TupleOffset = 0; - tuple.TupleDataMax = 255; - tuple.Attributes = 0; - is_kme = ((link->manf_id == MANFID_KME) && ((link->card_id == PRODID_KME_KXLC005_A) || (link->card_id == PRODID_KME_KXLC005_B))); - /* Not sure if this is right... look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); - - pass = io_base = ctl_base = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry; - if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry; - - /* Check for matching Vcc, unless we're desperate */ - if (!pass) { - if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) - goto next_entry; - } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) - goto next_entry; - } - } - - if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = - cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = - stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; - - if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io; - link->conf.ConfigIndex = cfg->index; - link->io.BasePort1 = io->win[0].base; - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (!(io->flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - if (io->nwin == 2) { - link->io.NumPorts1 = 8; - link->io.BasePort2 = io->win[1].base; - link->io.NumPorts2 = (is_kme) ? 2 : 1; - if (pcmcia_request_io(link, &link->io) != 0) - goto next_entry; - io_base = link->io.BasePort1; - ctl_base = link->io.BasePort2; - } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { - link->io.NumPorts1 = io->win[0].len; - link->io.NumPorts2 = 0; - if (pcmcia_request_io(link, &link->io) != 0) - goto next_entry; - io_base = link->io.BasePort1; - ctl_base = link->io.BasePort1 + 0x0e; - } else goto next_entry; - /* If we've got this far, we're done */ - break; - } - - next_entry: - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) - memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); - if (pass) { - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); - } else if (pcmcia_get_next_tuple(link, &tuple) != 0) { - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - memset(&stk->dflt, 0, sizeof(stk->dflt)); - pass++; - } + stk = kzalloc(sizeof(*stk), GFP_KERNEL); + if (!stk) + goto err_mem; + stk->is_kme = is_kme; + stk->skip_vcc = io_base = ctl_base = 0; + + if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) { + stk->skip_vcc = 1; + if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) + goto failed; /* No suitable config found */ } + io_base = link->io.BasePort1; + ctl_base = stk->ctl_base; CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); @@ -403,8 +391,10 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */ PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */ PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), + PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904), PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */ + PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */ PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 01846f244b4..223750c1b5a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -14,9 +14,6 @@ * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c. */ -#define IDEDISK_VERSION "1.18" - -#include <linux/module.h> #include <linux/types.h> #include <linux/string.h> #include <linux/kernel.h> @@ -39,54 +36,7 @@ #include <asm/io.h> #include <asm/div64.h> -#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) -#define IDE_DISK_MINORS (1 << PARTN_BITS) -#else -#define IDE_DISK_MINORS 0 -#endif - -struct ide_disk_obj { - ide_drive_t *drive; - ide_driver_t *driver; - struct gendisk *disk; - struct kref kref; - unsigned int openers; /* protected by BKL for now */ -}; - -static DEFINE_MUTEX(idedisk_ref_mutex); - -#define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref) - -#define ide_disk_g(disk) \ - container_of((disk)->private_data, struct ide_disk_obj, driver) - -static void ide_disk_release(struct kref *); - -static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) -{ - struct ide_disk_obj *idkp = NULL; - - mutex_lock(&idedisk_ref_mutex); - idkp = ide_disk_g(disk); - if (idkp) { - if (ide_device_get(idkp->drive)) - idkp = NULL; - else - kref_get(&idkp->kref); - } - mutex_unlock(&idedisk_ref_mutex); - return idkp; -} - -static void ide_disk_put(struct ide_disk_obj *idkp) -{ - ide_drive_t *drive = idkp->drive; - - mutex_lock(&idedisk_ref_mutex); - kref_put(&idkp->kref, ide_disk_release); - ide_device_put(drive); - mutex_unlock(&idedisk_ref_mutex); -} +#include "ide-disk.h" static const u8 ide_rw_cmds[] = { ATA_CMD_READ_MULTI, @@ -140,9 +90,9 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block) { ide_hwif_t *hwif = HWIF(drive); - unsigned int dma = drive->using_dma; u16 nsectors = (u16)rq->nr_sectors; - u8 lba48 = (drive->addressing == 1) ? 1 : 0; + u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); + u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); ide_task_t task; struct ide_taskfile *tf = &task.tf; ide_startstop_t rc; @@ -162,7 +112,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, memset(&task, 0, sizeof(task)); task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - if (drive->select.b.lba) { + if (drive->dev_flags & IDE_DFLAG_LBA) { if (lba48) { pr_debug("%s: LBA=0x%012llx\n", drive->name, (unsigned long long)block); @@ -187,6 +137,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, tf->lbah = block >>= 8; tf->device = (block >> 8) & 0xf; } + + tf->device |= ATA_LBA; } else { unsigned int sect, head, cyl, track; @@ -237,7 +189,7 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, { ide_hwif_t *hwif = HWIF(drive); - BUG_ON(drive->blocked); + BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED); if (!blk_fs_request(rq)) { blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command"); @@ -381,142 +333,59 @@ static void idedisk_check_hpa(ide_drive_t *drive) } } -static void init_idedisk_capacity(ide_drive_t *drive) +static int ide_disk_get_capacity(ide_drive_t *drive) { u16 *id = drive->id; - /* - * If this drive supports the Host Protected Area feature set, - * then we may need to change our opinion about the drive's capacity. - */ - int hpa = ata_id_hpa_enabled(id); + int lba; if (ata_id_lba48_enabled(id)) { /* drive speaks 48-bit LBA */ - drive->select.b.lba = 1; + lba = 1; drive->capacity64 = ata_id_u64(id, ATA_ID_LBA_CAPACITY_2); - if (hpa) - idedisk_check_hpa(drive); } else if (ata_id_has_lba(id) && ata_id_is_lba_capacity_ok(id)) { /* drive speaks 28-bit LBA */ - drive->select.b.lba = 1; + lba = 1; drive->capacity64 = ata_id_u32(id, ATA_ID_LBA_CAPACITY); - if (hpa) - idedisk_check_hpa(drive); } else { /* drive speaks boring old 28-bit CHS */ + lba = 0; drive->capacity64 = drive->cyl * drive->head * drive->sect; } -} - -static sector_t idedisk_capacity(ide_drive_t *drive) -{ - return drive->capacity64; -} - -#ifdef CONFIG_IDE_PROC_FS -static int smart_enable(ide_drive_t *drive) -{ - ide_task_t args; - struct ide_taskfile *tf = &args.tf; - - memset(&args, 0, sizeof(ide_task_t)); - tf->feature = ATA_SMART_ENABLE; - tf->lbam = ATA_SMART_LBAM_PASS; - tf->lbah = ATA_SMART_LBAH_PASS; - tf->command = ATA_CMD_SMART; - args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - return ide_no_data_taskfile(drive, &args); -} -static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) -{ - ide_task_t args; - struct ide_taskfile *tf = &args.tf; + if (lba) { + drive->dev_flags |= IDE_DFLAG_LBA; - memset(&args, 0, sizeof(ide_task_t)); - tf->feature = sub_cmd; - tf->nsect = 0x01; - tf->lbam = ATA_SMART_LBAM_PASS; - tf->lbah = ATA_SMART_LBAH_PASS; - tf->command = ATA_CMD_SMART; - args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - args.data_phase = TASKFILE_IN; - (void) smart_enable(drive); - return ide_raw_taskfile(drive, &args, buf, 1); -} - -static int proc_idedisk_read_cache - (char *page, char **start, off_t off, int count, int *eof, void *data) -{ - ide_drive_t *drive = (ide_drive_t *) data; - char *out = page; - int len; - - if (drive->id_read) - len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2); - else - len = sprintf(out, "(none)\n"); - - PROC_IDE_READ_RETURN(page, start, off, count, eof, len); -} - -static int proc_idedisk_read_capacity - (char *page, char **start, off_t off, int count, int *eof, void *data) -{ - ide_drive_t*drive = (ide_drive_t *)data; - int len; - - len = sprintf(page, "%llu\n", (long long)idedisk_capacity(drive)); - - PROC_IDE_READ_RETURN(page, start, off, count, eof, len); -} - -static int proc_idedisk_read_smart(char *page, char **start, off_t off, - int count, int *eof, void *data, u8 sub_cmd) -{ - ide_drive_t *drive = (ide_drive_t *)data; - int len = 0, i = 0; - - if (get_smart_data(drive, page, sub_cmd) == 0) { - unsigned short *val = (unsigned short *) page; - char *out = (char *)val + SECTOR_SIZE; - - page = out; - do { - out += sprintf(out, "%04x%c", le16_to_cpu(*val), - (++i & 7) ? ' ' : '\n'); - val += 1; - } while (i < SECTOR_SIZE / 2); - len = out - page; + /* + * If this device supports the Host Protected Area feature set, + * then we may need to change our opinion about its capacity. + */ + if (ata_id_hpa_enabled(id)) + idedisk_check_hpa(drive); } - PROC_IDE_READ_RETURN(page, start, off, count, eof, len); -} + /* limit drive capacity to 137GB if LBA48 cannot be used */ + if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 && + drive->capacity64 > 1ULL << 28) { + printk(KERN_WARNING "%s: cannot use LBA48 - full capacity " + "%llu sectors (%llu MB)\n", + drive->name, (unsigned long long)drive->capacity64, + sectors_to_MB(drive->capacity64)); + drive->capacity64 = 1ULL << 28; + } -static int proc_idedisk_read_sv - (char *page, char **start, off_t off, int count, int *eof, void *data) -{ - return proc_idedisk_read_smart(page, start, off, count, eof, data, - ATA_SMART_READ_VALUES); -} + if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && + (drive->dev_flags & IDE_DFLAG_LBA48)) { + if (drive->capacity64 > 1ULL << 28) { + printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode" + " will be used for accessing sectors " + "> %u\n", drive->name, 1 << 28); + } else + drive->dev_flags &= ~IDE_DFLAG_LBA48; + } -static int proc_idedisk_read_st - (char *page, char **start, off_t off, int count, int *eof, void *data) -{ - return proc_idedisk_read_smart(page, start, off, count, eof, data, - ATA_SMART_READ_THRESHOLDS); + return 0; } -static ide_proc_entry_t idedisk_proc[] = { - { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL }, - { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL }, - { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, - { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL }, - { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL }, - { NULL, 0, NULL, NULL } -}; -#endif /* CONFIG_IDE_PROC_FS */ - static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) { ide_drive_t *drive = q->queuedata; @@ -568,25 +437,43 @@ static int set_multcount(ide_drive_t *drive, int arg) return (drive->mult_count == arg) ? 0 : -EIO; } -ide_devset_get(nowerr, nowerr); +ide_devset_get_flag(nowerr, IDE_DFLAG_NOWERR); static int set_nowerr(ide_drive_t *drive, int arg) { if (arg < 0 || arg > 1) return -EINVAL; - drive->nowerr = arg; + if (arg) + drive->dev_flags |= IDE_DFLAG_NOWERR; + else + drive->dev_flags &= ~IDE_DFLAG_NOWERR; + drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; + return 0; } +static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect) +{ + ide_task_t task; + + memset(&task, 0, sizeof(task)); + task.tf.feature = feature; + task.tf.nsect = nsect; + task.tf.command = ATA_CMD_SET_FEATURES; + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + + return ide_no_data_taskfile(drive, &task); +} + static void update_ordered(ide_drive_t *drive) { u16 *id = drive->id; unsigned ordered = QUEUE_ORDERED_NONE; prepare_flush_fn *prep_fn = NULL; - if (drive->wcache) { + if (drive->dev_flags & IDE_DFLAG_WCACHE) { unsigned long long capacity; int barrier; /* @@ -597,9 +484,11 @@ static void update_ordered(ide_drive_t *drive) * time we have trimmed the drive capacity if LBA48 is * not available so we don't need to recheck that. */ - capacity = idedisk_capacity(drive); - barrier = ata_id_flush_enabled(id) && !drive->noflush && - (drive->addressing == 0 || capacity <= (1ULL << 28) || + capacity = ide_gd_capacity(drive); + barrier = ata_id_flush_enabled(id) && + (drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 && + ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 || + capacity <= (1ULL << 28) || ata_id_flush_ext_enabled(id)); printk(KERN_INFO "%s: cache flushes %ssupported\n", @@ -615,25 +504,24 @@ static void update_ordered(ide_drive_t *drive) blk_queue_ordered(drive->queue, ordered, prep_fn); } -ide_devset_get(wcache, wcache); +ide_devset_get_flag(wcache, IDE_DFLAG_WCACHE); static int set_wcache(ide_drive_t *drive, int arg) { - ide_task_t args; int err = 1; if (arg < 0 || arg > 1) return -EINVAL; if (ata_id_flush_enabled(drive->id)) { - memset(&args, 0, sizeof(ide_task_t)); - args.tf.feature = arg ? - SETFEATURES_WC_ON : SETFEATURES_WC_OFF; - args.tf.command = ATA_CMD_SET_FEATURES; - args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - err = ide_no_data_taskfile(drive, &args); - if (err == 0) - drive->wcache = arg; + err = ide_do_setfeature(drive, + arg ? SETFEATURES_WC_ON : SETFEATURES_WC_OFF, 0); + if (err == 0) { + if (arg) + drive->dev_flags |= IDE_DFLAG_WCACHE; + else + drive->dev_flags &= ~IDE_DFLAG_WCACHE; + } } update_ordered(drive); @@ -658,22 +546,18 @@ ide_devset_get(acoustic, acoustic); static int set_acoustic(ide_drive_t *drive, int arg) { - ide_task_t args; - if (arg < 0 || arg > 254) return -EINVAL; - memset(&args, 0, sizeof(ide_task_t)); - args.tf.feature = arg ? SETFEATURES_AAM_ON : SETFEATURES_AAM_OFF; - args.tf.nsect = arg; - args.tf.command = ATA_CMD_SET_FEATURES; - args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - ide_no_data_taskfile(drive, &args); + ide_do_setfeature(drive, + arg ? SETFEATURES_AAM_ON : SETFEATURES_AAM_OFF, arg); + drive->acoustic = arg; + return 0; } -ide_devset_get(addressing, addressing); +ide_devset_get_flag(addressing, IDE_DFLAG_LBA48); /* * drive->addressing: @@ -686,51 +570,34 @@ static int set_addressing(ide_drive_t *drive, int arg) if (arg < 0 || arg > 2) return -EINVAL; - drive->addressing = 0; - - if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) - return 0; - - if (ata_id_lba48_enabled(drive->id) == 0) + if (arg && ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) || + ata_id_lba48_enabled(drive->id) == 0)) return -EIO; - drive->addressing = arg; + if (arg == 2) + arg = 0; + + if (arg) + drive->dev_flags |= IDE_DFLAG_LBA48; + else + drive->dev_flags &= ~IDE_DFLAG_LBA48; return 0; } -ide_devset_rw(acoustic, acoustic); -ide_devset_rw(address, addressing); -ide_devset_rw(multcount, multcount); -ide_devset_rw(wcache, wcache); - -ide_devset_rw_sync(nowerr, nowerr); - -#ifdef CONFIG_IDE_PROC_FS -ide_devset_rw_field(bios_cyl, bios_cyl); -ide_devset_rw_field(bios_head, bios_head); -ide_devset_rw_field(bios_sect, bios_sect); -ide_devset_rw_field(failures, failures); -ide_devset_rw_field(lun, lun); -ide_devset_rw_field(max_failures, max_failures); - -static const struct ide_proc_devset idedisk_settings[] = { - IDE_PROC_DEVSET(acoustic, 0, 254), - IDE_PROC_DEVSET(address, 0, 2), - IDE_PROC_DEVSET(bios_cyl, 0, 65535), - IDE_PROC_DEVSET(bios_head, 0, 255), - IDE_PROC_DEVSET(bios_sect, 0, 63), - IDE_PROC_DEVSET(failures, 0, 65535), - IDE_PROC_DEVSET(lun, 0, 7), - IDE_PROC_DEVSET(max_failures, 0, 65535), - IDE_PROC_DEVSET(multcount, 0, 16), - IDE_PROC_DEVSET(nowerr, 0, 1), - IDE_PROC_DEVSET(wcache, 0, 1), - { 0 }, -}; -#endif +ide_ext_devset_rw(acoustic, acoustic); +ide_ext_devset_rw(address, addressing); +ide_ext_devset_rw(multcount, multcount); +ide_ext_devset_rw(wcache, wcache); + +ide_ext_devset_rw_sync(nowerr, nowerr); -static void idedisk_setup(ide_drive_t *drive) +static int ide_disk_check(ide_drive_t *drive, const char *s) +{ + return 1; +} + +static void ide_disk_setup(ide_drive_t *drive) { struct ide_disk_obj *idkp = drive->driver_data; ide_hwif_t *hwif = drive->hwif; @@ -740,20 +607,20 @@ static void idedisk_setup(ide_drive_t *drive) ide_proc_register_driver(drive, idkp->driver); - if (drive->id_read == 0) + if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) return; - if (drive->removable) { + if (drive->dev_flags & IDE_DFLAG_REMOVABLE) { /* * Removable disks (eg. SYQUEST); ignore 'WD' drives */ if (m[0] != 'W' || m[1] != 'D') - drive->doorlocking = 1; + drive->dev_flags |= IDE_DFLAG_DOORLOCKING; } (void)set_addressing(drive, 1); - if (drive->addressing == 1) { + if (drive->dev_flags & IDE_DFLAG_LBA48) { int max_s = 2048; if (max_s > hwif->rqsize) @@ -766,33 +633,15 @@ static void idedisk_setup(ide_drive_t *drive) drive->queue->max_sectors / 2); /* calculate drive capacity, and select LBA if possible */ - init_idedisk_capacity(drive); - - /* limit drive capacity to 137GB if LBA48 cannot be used */ - if (drive->addressing == 0 && drive->capacity64 > 1ULL << 28) { - printk(KERN_WARNING "%s: cannot use LBA48 - full capacity " - "%llu sectors (%llu MB)\n", - drive->name, (unsigned long long)drive->capacity64, - sectors_to_MB(drive->capacity64)); - drive->capacity64 = 1ULL << 28; - } - - if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) { - if (drive->capacity64 > 1ULL << 28) { - printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode" - " will be used for accessing sectors " - "> %u\n", drive->name, 1 << 28); - } else - drive->addressing = 0; - } + ide_disk_get_capacity(drive); /* * if possible, give fdisk access to more of the drive, * by correcting bios_cyls: */ - capacity = idedisk_capacity(drive); + capacity = ide_gd_capacity(drive); - if (!drive->forced_geom) { + if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) { if (ata_id_lba48_enabled(drive->id)) { /* compatibility */ drive->bios_sect = 63; @@ -827,301 +676,63 @@ static void idedisk_setup(ide_drive_t *drive) /* write cache enabled? */ if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id)) - drive->wcache = 1; + drive->dev_flags |= IDE_DFLAG_WCACHE; set_wcache(drive, 1); + + if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 && + (drive->head == 0 || drive->head > 16)) { + printk(KERN_ERR "%s: invalid geometry: %d physical heads?\n", + drive->name, drive->head); + drive->dev_flags &= ~IDE_DFLAG_ATTACH; + } else + drive->dev_flags |= IDE_DFLAG_ATTACH; } -static void ide_cacheflush_p(ide_drive_t *drive) +static void ide_disk_flush(ide_drive_t *drive) { - if (!drive->wcache || ata_id_flush_enabled(drive->id) == 0) + if (ata_id_flush_enabled(drive->id) == 0 || + (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) return; if (do_idedisk_flushcache(drive)) printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); } -static void ide_disk_remove(ide_drive_t *drive) -{ - struct ide_disk_obj *idkp = drive->driver_data; - struct gendisk *g = idkp->disk; - - ide_proc_unregister_driver(drive, idkp->driver); - - del_gendisk(g); - - ide_cacheflush_p(drive); - - ide_disk_put(idkp); -} - -static void ide_disk_release(struct kref *kref) -{ - struct ide_disk_obj *idkp = to_ide_disk(kref); - ide_drive_t *drive = idkp->drive; - struct gendisk *g = idkp->disk; - - drive->driver_data = NULL; - g->private_data = NULL; - put_disk(g); - kfree(idkp); -} - -static int ide_disk_probe(ide_drive_t *drive); - -/* - * On HPA drives the capacity needs to be - * reinitilized on resume otherwise the disk - * can not be used and a hard reset is required - */ -static void ide_disk_resume(ide_drive_t *drive) -{ - if (ata_id_hpa_enabled(drive->id)) - init_idedisk_capacity(drive); -} - -static void ide_device_shutdown(ide_drive_t *drive) +static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk) { -#ifdef CONFIG_ALPHA - /* On Alpha, halt(8) doesn't actually turn the machine off, - it puts you into the sort of firmware monitor. Typically, - it's used to boot another kernel image, so it's not much - different from reboot(8). Therefore, we don't need to - spin down the disk in this case, especially since Alpha - firmware doesn't handle disks in standby mode properly. - On the other hand, it's reasonably safe to turn the power - off when the shutdown process reaches the firmware prompt, - as the firmware initialization takes rather long time - - at least 10 seconds, which should be sufficient for - the disk to expire its write cache. */ - if (system_state != SYSTEM_POWER_OFF) { -#else - if (system_state == SYSTEM_RESTART) { -#endif - ide_cacheflush_p(drive); - return; - } - - printk(KERN_INFO "Shutdown: %s\n", drive->name); - - drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND); + return 0; } -static ide_driver_t idedisk_driver = { - .gen_driver = { - .owner = THIS_MODULE, - .name = "ide-disk", - .bus = &ide_bus_type, - }, - .probe = ide_disk_probe, - .remove = ide_disk_remove, - .resume = ide_disk_resume, - .shutdown = ide_device_shutdown, - .version = IDEDISK_VERSION, - .media = ide_disk, - .do_request = ide_do_rw_disk, - .end_request = ide_end_request, - .error = __ide_error, -#ifdef CONFIG_IDE_PROC_FS - .proc = idedisk_proc, - .settings = idedisk_settings, -#endif -}; - -static int idedisk_set_doorlock(ide_drive_t *drive, int on) +static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk, + int on) { ide_task_t task; + int ret; + + if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) + return 0; memset(&task, 0, sizeof(task)); task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - return ide_no_data_taskfile(drive, &task); -} - -static int idedisk_open(struct inode *inode, struct file *filp) -{ - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_disk_obj *idkp; - ide_drive_t *drive; - - idkp = ide_disk_get(disk); - if (idkp == NULL) - return -ENXIO; - - drive = idkp->drive; - - idkp->openers++; - - if (drive->removable && idkp->openers == 1) { - check_disk_change(inode->i_bdev); - /* - * Ignore the return code from door_lock, - * since the open() has already succeeded, - * and the door_lock is irrelevant at this point. - */ - if (drive->doorlocking && idedisk_set_doorlock(drive, 1)) - drive->doorlocking = 0; - } - return 0; -} - -static int idedisk_release(struct inode *inode, struct file *filp) -{ - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_disk_obj *idkp = ide_disk_g(disk); - ide_drive_t *drive = idkp->drive; - - if (idkp->openers == 1) - ide_cacheflush_p(drive); - - if (drive->removable && idkp->openers == 1) { - if (drive->doorlocking && idedisk_set_doorlock(drive, 0)) - drive->doorlocking = 0; - } - - idkp->openers--; - - ide_disk_put(idkp); + ret = ide_no_data_taskfile(drive, &task); - return 0; -} - -static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); - ide_drive_t *drive = idkp->drive; - - geo->heads = drive->bios_head; - geo->sectors = drive->bios_sect; - geo->cylinders = (u16)drive->bios_cyl; /* truncate */ - return 0; -} - -static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { -{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, &ide_devset_address }, -{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, &ide_devset_multcount }, -{ HDIO_GET_NOWERR, HDIO_SET_NOWERR, &ide_devset_nowerr }, -{ HDIO_GET_WCACHE, HDIO_SET_WCACHE, &ide_devset_wcache }, -{ HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, &ide_devset_acoustic }, -{ 0 } -}; - -static int idedisk_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct block_device *bdev = inode->i_bdev; - struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); - ide_drive_t *drive = idkp->drive; - int err; - - err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); - if (err != -EOPNOTSUPP) - return err; - - return generic_ide_ioctl(drive, file, bdev, cmd, arg); -} - -static int idedisk_media_changed(struct gendisk *disk) -{ - struct ide_disk_obj *idkp = ide_disk_g(disk); - ide_drive_t *drive = idkp->drive; - - /* do not scan partitions twice if this is a removable device */ - if (drive->attach) { - drive->attach = 0; - return 0; - } - /* if removable, always assume it was changed */ - return drive->removable; -} + if (ret) + drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; -static int idedisk_revalidate_disk(struct gendisk *disk) -{ - struct ide_disk_obj *idkp = ide_disk_g(disk); - set_capacity(disk, idedisk_capacity(idkp->drive)); - return 0; + return ret; } -static struct block_device_operations idedisk_ops = { - .owner = THIS_MODULE, - .open = idedisk_open, - .release = idedisk_release, - .ioctl = idedisk_ioctl, - .getgeo = idedisk_getgeo, - .media_changed = idedisk_media_changed, - .revalidate_disk = idedisk_revalidate_disk +const struct ide_disk_ops ide_ata_disk_ops = { + .check = ide_disk_check, + .get_capacity = ide_disk_get_capacity, + .setup = ide_disk_setup, + .flush = ide_disk_flush, + .init_media = ide_disk_init_media, + .set_doorlock = ide_disk_set_doorlock, + .do_request = ide_do_rw_disk, + .end_request = ide_end_request, + .ioctl = ide_disk_ioctl, }; - -MODULE_DESCRIPTION("ATA DISK Driver"); - -static int ide_disk_probe(ide_drive_t *drive) -{ - struct ide_disk_obj *idkp; - struct gendisk *g; - - /* strstr("foo", "") is non-NULL */ - if (!strstr("ide-disk", drive->driver_req)) - goto failed; - - if (drive->media != ide_disk) - goto failed; - - idkp = kzalloc(sizeof(*idkp), GFP_KERNEL); - if (!idkp) - goto failed; - - g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); - if (!g) - goto out_free_idkp; - - ide_init_disk(g, drive); - - kref_init(&idkp->kref); - - idkp->drive = drive; - idkp->driver = &idedisk_driver; - idkp->disk = g; - - g->private_data = &idkp->driver; - - drive->driver_data = idkp; - - idedisk_setup(drive); - if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { - printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", - drive->name, drive->head); - drive->attach = 0; - } else - drive->attach = 1; - - g->minors = IDE_DISK_MINORS; - g->driverfs_dev = &drive->gendev; - g->flags |= GENHD_FL_EXT_DEVT; - if (drive->removable) - g->flags |= GENHD_FL_REMOVABLE; - set_capacity(g, idedisk_capacity(drive)); - g->fops = &idedisk_ops; - add_disk(g); - return 0; - -out_free_idkp: - kfree(idkp); -failed: - return -ENODEV; -} - -static void __exit idedisk_exit(void) -{ - driver_unregister(&idedisk_driver.gen_driver); -} - -static int __init idedisk_init(void) -{ - return driver_register(&idedisk_driver.gen_driver); -} - -MODULE_ALIAS("ide:*m-disk*"); -module_init(idedisk_init); -module_exit(idedisk_exit); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/ide-disk.h b/drivers/ide/ide-disk.h new file mode 100644 index 00000000000..b234b0feaf7 --- /dev/null +++ b/drivers/ide/ide-disk.h @@ -0,0 +1,29 @@ +#ifndef __IDE_DISK_H +#define __IDE_DISK_H + +#include "ide-gd.h" + +#ifdef CONFIG_IDE_GD_ATA +/* ide-disk.c */ +extern const struct ide_disk_ops ide_ata_disk_ops; +ide_decl_devset(address); +ide_decl_devset(multcount); +ide_decl_devset(nowerr); +ide_decl_devset(wcache); +ide_decl_devset(acoustic); + +/* ide-disk_ioctl.c */ +int ide_disk_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, + unsigned long); + +#ifdef CONFIG_IDE_PROC_FS +/* ide-disk_proc.c */ +extern ide_proc_entry_t ide_disk_proc[]; +extern const struct ide_proc_devset ide_disk_settings[]; +#endif +#else +#define ide_disk_proc NULL +#define ide_disk_settings NULL +#endif + +#endif /* __IDE_DISK_H */ diff --git a/drivers/ide/ide-disk_ioctl.c b/drivers/ide/ide-disk_ioctl.c new file mode 100644 index 00000000000..a49698bcf96 --- /dev/null +++ b/drivers/ide/ide-disk_ioctl.c @@ -0,0 +1,27 @@ +#include <linux/kernel.h> +#include <linux/ide.h> +#include <linux/hdreg.h> + +#include "ide-disk.h" + +static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { +{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, &ide_devset_address }, +{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, &ide_devset_multcount }, +{ HDIO_GET_NOWERR, HDIO_SET_NOWERR, &ide_devset_nowerr }, +{ HDIO_GET_WCACHE, HDIO_SET_WCACHE, &ide_devset_wcache }, +{ HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, &ide_devset_acoustic }, +{ 0 } +}; + +int ide_disk_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct block_device *bdev = inode->i_bdev; + int err; + + err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); + if (err != -EOPNOTSUPP) + return err; + + return generic_ide_ioctl(drive, file, bdev, cmd, arg); +} diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c new file mode 100644 index 00000000000..1146f4204c6 --- /dev/null +++ b/drivers/ide/ide-disk_proc.c @@ -0,0 +1,129 @@ +#include <linux/kernel.h> +#include <linux/ide.h> +#include <linux/hdreg.h> + +#include "ide-disk.h" + +static int smart_enable(ide_drive_t *drive) +{ + ide_task_t args; + struct ide_taskfile *tf = &args.tf; + + memset(&args, 0, sizeof(ide_task_t)); + tf->feature = ATA_SMART_ENABLE; + tf->lbam = ATA_SMART_LBAM_PASS; + tf->lbah = ATA_SMART_LBAH_PASS; + tf->command = ATA_CMD_SMART; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + return ide_no_data_taskfile(drive, &args); +} + +static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) +{ + ide_task_t args; + struct ide_taskfile *tf = &args.tf; + + memset(&args, 0, sizeof(ide_task_t)); + tf->feature = sub_cmd; + tf->nsect = 0x01; + tf->lbam = ATA_SMART_LBAM_PASS; + tf->lbah = ATA_SMART_LBAH_PASS; + tf->command = ATA_CMD_SMART; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args.data_phase = TASKFILE_IN; + (void) smart_enable(drive); + return ide_raw_taskfile(drive, &args, buf, 1); +} + +static int proc_idedisk_read_cache + (char *page, char **start, off_t off, int count, int *eof, void *data) +{ + ide_drive_t *drive = (ide_drive_t *) data; + char *out = page; + int len; + + if (drive->dev_flags & IDE_DFLAG_ID_READ) + len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2); + else + len = sprintf(out, "(none)\n"); + + PROC_IDE_READ_RETURN(page, start, off, count, eof, len); +} + +static int proc_idedisk_read_capacity + (char *page, char **start, off_t off, int count, int *eof, void *data) +{ + ide_drive_t*drive = (ide_drive_t *)data; + int len; + + len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive)); + + PROC_IDE_READ_RETURN(page, start, off, count, eof, len); +} + +static int proc_idedisk_read_smart(char *page, char **start, off_t off, + int count, int *eof, void *data, u8 sub_cmd) +{ + ide_drive_t *drive = (ide_drive_t *)data; + int len = 0, i = 0; + + if (get_smart_data(drive, page, sub_cmd) == 0) { + unsigned short *val = (unsigned short *) page; + char *out = (char *)val + SECTOR_SIZE; + + page = out; + do { + out += sprintf(out, "%04x%c", le16_to_cpu(*val), + (++i & 7) ? ' ' : '\n'); + val += 1; + } while (i < SECTOR_SIZE / 2); + len = out - page; + } + + PROC_IDE_READ_RETURN(page, start, off, count, eof, len); +} + +static int proc_idedisk_read_sv + (char *page, char **start, off_t off, int count, int *eof, void *data) +{ + return proc_idedisk_read_smart(page, start, off, count, eof, data, + ATA_SMART_READ_VALUES); +} + +static int proc_idedisk_read_st + (char *page, char **start, off_t off, int count, int *eof, void *data) +{ + return proc_idedisk_read_smart(page, start, off, count, eof, data, + ATA_SMART_READ_THRESHOLDS); +} + +ide_proc_entry_t ide_disk_proc[] = { + { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL }, + { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL }, + { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, + { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL }, + { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL }, + { NULL, 0, NULL, NULL } +}; + +ide_devset_rw_field(bios_cyl, bios_cyl); +ide_devset_rw_field(bios_head, bios_head); +ide_devset_rw_field(bios_sect, bios_sect); +ide_devset_rw_field(failures, failures); +ide_devset_rw_field(lun, lun); +ide_devset_rw_field(max_failures, max_failures); + +const struct ide_proc_devset ide_disk_settings[] = { + IDE_PROC_DEVSET(acoustic, 0, 254), + IDE_PROC_DEVSET(address, 0, 2), + IDE_PROC_DEVSET(bios_cyl, 0, 65535), + IDE_PROC_DEVSET(bios_head, 0, 255), + IDE_PROC_DEVSET(bios_sect, 0, 63), + IDE_PROC_DEVSET(failures, 0, 65535), + IDE_PROC_DEVSET(lun, 0, 7), + IDE_PROC_DEVSET(max_failures, 0, 65535), + IDE_PROC_DEVSET(multcount, 0, 16), + IDE_PROC_DEVSET(nowerr, 0, 1), + IDE_PROC_DEVSET(wcache, 0, 1), + { 0 }, +}; diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c new file mode 100644 index 00000000000..cac431f0df1 --- /dev/null +++ b/drivers/ide/ide-dma-sff.c @@ -0,0 +1,356 @@ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/ide.h> +#include <linux/scatterlist.h> +#include <linux/dma-mapping.h> +#include <linux/io.h> + +/** + * config_drive_for_dma - attempt to activate IDE DMA + * @drive: the drive to place in DMA mode + * + * If the drive supports at least mode 2 DMA or UDMA of any kind + * then attempt to place it into DMA mode. Drives that are known to + * support DMA but predate the DMA properties or that are known + * to have DMA handling bugs are also set up appropriately based + * on the good/bad drive lists. + */ + +int config_drive_for_dma(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u16 *id = drive->id; + + if (drive->media != ide_disk) { + if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA) + return 0; + } + + /* + * Enable DMA on any drive that has + * UltraDMA (mode 0/1/2/3/4/5/6) enabled + */ + if ((id[ATA_ID_FIELD_VALID] & 4) && + ((id[ATA_ID_UDMA_MODES] >> 8) & 0x7f)) + return 1; + + /* + * Enable DMA on any drive that has mode2 DMA + * (multi or single) enabled + */ + if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */ + if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 || + (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404) + return 1; + + /* Consult the list of known "good" drives */ + if (ide_dma_good_drive(drive)) + return 1; + + return 0; +} + +/** + * ide_dma_host_set - Enable/disable DMA on a host + * @drive: drive to control + * + * Enable/disable DMA on an IDE controller following generic + * bus-mastering IDE controller behaviour. + */ + +void ide_dma_host_set(ide_drive_t *drive, int on) +{ + ide_hwif_t *hwif = drive->hwif; + u8 unit = drive->dn & 1; + u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + + if (on) + dma_stat |= (1 << (5 + unit)); + else + dma_stat &= ~(1 << (5 + unit)); + + if (hwif->host_flags & IDE_HFLAG_MMIO) + writeb(dma_stat, + (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); + else + outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS); +} +EXPORT_SYMBOL_GPL(ide_dma_host_set); + +/** + * ide_build_dmatable - build IDE DMA table + * + * ide_build_dmatable() prepares a dma request. We map the command + * to get the pci bus addresses of the buffers and then build up + * the PRD table that the IDE layer wants to be fed. + * + * Most chipsets correctly interpret a length of 0x0000 as 64KB, + * but at least one (e.g. CS5530) misinterprets it as zero (!). + * So we break the 64KB entry into two 32KB entries instead. + * + * Returns the number of built PRD entries if all went okay, + * returns 0 otherwise. + * + * May also be invoked from trm290.c + */ + +int ide_build_dmatable(ide_drive_t *drive, struct request *rq) +{ + ide_hwif_t *hwif = drive->hwif; + __le32 *table = (__le32 *)hwif->dmatable_cpu; + unsigned int is_trm290 = (hwif->chipset == ide_trm290) ? 1 : 0; + unsigned int count = 0; + int i; + struct scatterlist *sg; + + hwif->sg_nents = ide_build_sglist(drive, rq); + if (hwif->sg_nents == 0) + return 0; + + for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) { + u32 cur_addr, cur_len, xcount, bcount; + + cur_addr = sg_dma_address(sg); + cur_len = sg_dma_len(sg); + + /* + * Fill in the dma table, without crossing any 64kB boundaries. + * Most hardware requires 16-bit alignment of all blocks, + * but the trm290 requires 32-bit alignment. + */ + + while (cur_len) { + if (count++ >= PRD_ENTRIES) + goto use_pio_instead; + + bcount = 0x10000 - (cur_addr & 0xffff); + if (bcount > cur_len) + bcount = cur_len; + *table++ = cpu_to_le32(cur_addr); + xcount = bcount & 0xffff; + if (is_trm290) + xcount = ((xcount >> 2) - 1) << 16; + else if (xcount == 0x0000) { + if (count++ >= PRD_ENTRIES) + goto use_pio_instead; + *table++ = cpu_to_le32(0x8000); + *table++ = cpu_to_le32(cur_addr + 0x8000); + xcount = 0x8000; + } + *table++ = cpu_to_le32(xcount); + cur_addr += bcount; + cur_len -= bcount; + } + } + + if (count) { + if (!is_trm290) + *--table |= cpu_to_le32(0x80000000); + return count; + } + +use_pio_instead: + printk(KERN_ERR "%s: %s\n", drive->name, + count ? "DMA table too small" : "empty DMA table?"); + + ide_destroy_dmatable(drive); + + return 0; /* revert to PIO for this request */ +} +EXPORT_SYMBOL_GPL(ide_build_dmatable); + +/** + * ide_dma_setup - begin a DMA phase + * @drive: target device + * + * Build an IDE DMA PRD (IDE speak for scatter gather table) + * and then set up the DMA transfer registers for a device + * that follows generic IDE PCI DMA behaviour. Controllers can + * override this function if they need to + * + * Returns 0 on success. If a PIO fallback is required then 1 + * is returned. + */ + +int ide_dma_setup(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->hwgroup->rq; + unsigned int reading; + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + u8 dma_stat; + + if (rq_data_dir(rq)) + reading = 0; + else + reading = 1 << 3; + + /* fall back to pio! */ + if (!ide_build_dmatable(drive, rq)) { + ide_map_sg(drive, rq); + return 1; + } + + /* PRD table */ + if (hwif->host_flags & IDE_HFLAG_MMIO) + writel(hwif->dmatable_dma, + (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); + else + outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS); + + /* specify r/w */ + if (mmio) + writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + else + outb(reading, hwif->dma_base + ATA_DMA_CMD); + + /* read DMA status for INTR & ERROR flags */ + dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + + /* clear INTR & ERROR flags */ + if (mmio) + writeb(dma_stat | 6, + (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); + else + outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); + + drive->waiting_for_dma = 1; + return 0; +} +EXPORT_SYMBOL_GPL(ide_dma_setup); + +/** + * dma_timer_expiry - handle a DMA timeout + * @drive: Drive that timed out + * + * An IDE DMA transfer timed out. In the event of an error we ask + * the driver to resolve the problem, if a DMA transfer is still + * in progress we continue to wait (arguably we need to add a + * secondary 'I don't care what the drive thinks' timeout here) + * Finally if we have an interrupt we let it complete the I/O. + * But only one time - we clear expiry and if it's still not + * completed after WAIT_CMD, we error and retry in PIO. + * This can occur if an interrupt is lost or due to hang or bugs. + */ + +static int dma_timer_expiry(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + + printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n", + drive->name, __func__, dma_stat); + + if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */ + return WAIT_CMD; + + hwif->hwgroup->expiry = NULL; /* one free ride for now */ + + /* 1 dmaing, 2 error, 4 intr */ + if (dma_stat & 2) /* ERROR */ + return -1; + + if (dma_stat & 1) /* DMAing */ + return WAIT_CMD; + + if (dma_stat & 4) /* Got an Interrupt */ + return WAIT_CMD; + + return 0; /* Status is unknown -- reset the bus */ +} + +void ide_dma_exec_cmd(ide_drive_t *drive, u8 command) +{ + /* issue cmd to drive */ + ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD, + dma_timer_expiry); +} +EXPORT_SYMBOL_GPL(ide_dma_exec_cmd); + +void ide_dma_start(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u8 dma_cmd; + + /* Note that this is done *after* the cmd has + * been issued to the drive, as per the BM-IDE spec. + * The Promise Ultra33 doesn't work correctly when + * we do this part before issuing the drive cmd. + */ + if (hwif->host_flags & IDE_HFLAG_MMIO) { + dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + /* start DMA */ + writeb(dma_cmd | 1, + (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + } else { + dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); + outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD); + } + + wmb(); +} +EXPORT_SYMBOL_GPL(ide_dma_start); + +/* returns 1 on error, 0 otherwise */ +int ide_dma_end(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + u8 dma_stat = 0, dma_cmd = 0; + + drive->waiting_for_dma = 0; + + if (mmio) { + /* get DMA command mode */ + dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + /* stop DMA */ + writeb(dma_cmd & ~1, + (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + } else { + dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); + outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); + } + + /* get DMA status */ + dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + + if (mmio) + /* clear the INTR & ERROR bits */ + writeb(dma_stat | 6, + (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); + else + outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); + + /* purge DMA mappings */ + ide_destroy_dmatable(drive); + /* verify good DMA status */ + wmb(); + return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; +} +EXPORT_SYMBOL_GPL(ide_dma_end); + +/* returns 1 if dma irq issued, 0 otherwise */ +int ide_dma_test_irq(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + + /* return 1 if INTR asserted */ + if ((dma_stat & 4) == 4) + return 1; + + return 0; +} +EXPORT_SYMBOL_GPL(ide_dma_test_irq); + +const struct ide_dma_ops sff_dma_ops = { + .dma_host_set = ide_dma_host_set, + .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, + .dma_start = ide_dma_start, + .dma_end = ide_dma_end, + .dma_test_irq = ide_dma_test_irq, + .dma_timeout = ide_dma_timeout, + .dma_lost_irq = ide_dma_lost_irq, +}; +EXPORT_SYMBOL_GPL(sff_dma_ops); diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index ef2f1504c0d..fffd11717b2 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -28,24 +28,13 @@ * for supplying a Promise UDMA board & WD UDMA drive for this work! */ -#include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/init.h> #include <linux/ide.h> -#include <linux/delay.h> #include <linux/scatterlist.h> #include <linux/dma-mapping.h> -#include <asm/io.h> -#include <asm/irq.h> - -static const struct drive_list_entry drive_whitelist [] = { - +static const struct drive_list_entry drive_whitelist[] = { { "Micropolis 2112A" , NULL }, { "CONNER CTMA 4000" , NULL }, { "CONNER CTT8000-A" , NULL }, @@ -53,8 +42,7 @@ static const struct drive_list_entry drive_whitelist [] = { { NULL , NULL } }; -static const struct drive_list_entry drive_blacklist [] = { - +static const struct drive_list_entry drive_blacklist[] = { { "WDC AC11000H" , NULL }, { "WDC AC22100H" , NULL }, { "WDC AC32500H" , NULL }, @@ -94,11 +82,11 @@ static const struct drive_list_entry drive_blacklist [] = { * ide_dma_intr - IDE DMA interrupt handler * @drive: the drive the interrupt is for * - * Handle an interrupt completing a read/write DMA transfer on an + * Handle an interrupt completing a read/write DMA transfer on an * IDE device */ - -ide_startstop_t ide_dma_intr (ide_drive_t *drive) + +ide_startstop_t ide_dma_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; u8 stat = 0, dma_stat = 0; @@ -108,20 +96,19 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive) if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) { if (!dma_stat) { - struct request *rq = HWGROUP(drive)->rq; + struct request *rq = hwif->hwgroup->rq; task_end_request(drive, rq, stat); return ide_stopped; } - printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", - drive->name, dma_stat); + printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n", + drive->name, __func__, dma_stat); } return ide_error(drive, "dma_intr", stat); } - EXPORT_SYMBOL_GPL(ide_dma_intr); -static int ide_dma_good_drive(ide_drive_t *drive) +int ide_dma_good_drive(ide_drive_t *drive) { return ide_in_drive_list(drive->id, drive_whitelist); } @@ -139,7 +126,7 @@ static int ide_dma_good_drive(ide_drive_t *drive) int ide_build_sglist(ide_drive_t *drive, struct request *rq) { - ide_hwif_t *hwif = HWIF(drive); + ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; ide_map_sg(drive, rq); @@ -152,106 +139,8 @@ int ide_build_sglist(ide_drive_t *drive, struct request *rq) return dma_map_sg(hwif->dev, sg, hwif->sg_nents, hwif->sg_dma_direction); } - EXPORT_SYMBOL_GPL(ide_build_sglist); -#ifdef CONFIG_BLK_DEV_IDEDMA_SFF -/** - * ide_build_dmatable - build IDE DMA table - * - * ide_build_dmatable() prepares a dma request. We map the command - * to get the pci bus addresses of the buffers and then build up - * the PRD table that the IDE layer wants to be fed. The code - * knows about the 64K wrap bug in the CS5530. - * - * Returns the number of built PRD entries if all went okay, - * returns 0 otherwise. - * - * May also be invoked from trm290.c - */ - -int ide_build_dmatable (ide_drive_t *drive, struct request *rq) -{ - ide_hwif_t *hwif = HWIF(drive); - __le32 *table = (__le32 *)hwif->dmatable_cpu; - unsigned int is_trm290 = (hwif->chipset == ide_trm290) ? 1 : 0; - unsigned int count = 0; - int i; - struct scatterlist *sg; - - hwif->sg_nents = i = ide_build_sglist(drive, rq); - - if (!i) - return 0; - - sg = hwif->sg_table; - while (i) { - u32 cur_addr; - u32 cur_len; - - cur_addr = sg_dma_address(sg); - cur_len = sg_dma_len(sg); - - /* - * Fill in the dma table, without crossing any 64kB boundaries. - * Most hardware requires 16-bit alignment of all blocks, - * but the trm290 requires 32-bit alignment. - */ - - while (cur_len) { - if (count++ >= PRD_ENTRIES) { - printk(KERN_ERR "%s: DMA table too small\n", drive->name); - goto use_pio_instead; - } else { - u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff); - - if (bcount > cur_len) - bcount = cur_len; - *table++ = cpu_to_le32(cur_addr); - xcount = bcount & 0xffff; - if (is_trm290) - xcount = ((xcount >> 2) - 1) << 16; - else if (xcount == 0x0000) { - /* - * Most chipsets correctly interpret a length of 0x0000 as 64KB, - * but at least one (e.g. CS5530) misinterprets it as zero (!). - * So here we break the 64KB entry into two 32KB entries instead. - */ - if (count++ >= PRD_ENTRIES) { - printk(KERN_ERR "%s: DMA table too small\n", drive->name); - goto use_pio_instead; - } - *table++ = cpu_to_le32(0x8000); - *table++ = cpu_to_le32(cur_addr + 0x8000); - xcount = 0x8000; - } - *table++ = cpu_to_le32(xcount); - cur_addr += bcount; - cur_len -= bcount; - } - } - - sg = sg_next(sg); - i--; - } - - if (count) { - if (!is_trm290) - *--table |= cpu_to_le32(0x80000000); - return count; - } - - printk(KERN_ERR "%s: empty DMA table?\n", drive->name); - -use_pio_instead: - ide_destroy_dmatable(drive); - - return 0; /* revert to PIO for this request */ -} - -EXPORT_SYMBOL_GPL(ide_build_dmatable); -#endif - /** * ide_destroy_dmatable - clean up DMA mapping * @drive: The drive to unmap @@ -262,147 +151,30 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable); * an oops as only one mapping can be live for each target at a given * time. */ - -void ide_destroy_dmatable (ide_drive_t *drive) + +void ide_destroy_dmatable(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->sg_nents, hwif->sg_dma_direction); } - EXPORT_SYMBOL_GPL(ide_destroy_dmatable); -#ifdef CONFIG_BLK_DEV_IDEDMA_SFF -/** - * config_drive_for_dma - attempt to activate IDE DMA - * @drive: the drive to place in DMA mode - * - * If the drive supports at least mode 2 DMA or UDMA of any kind - * then attempt to place it into DMA mode. Drives that are known to - * support DMA but predate the DMA properties or that are known - * to have DMA handling bugs are also set up appropriately based - * on the good/bad drive lists. - */ - -static int config_drive_for_dma (ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u16 *id = drive->id; - - if (drive->media != ide_disk) { - if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA) - return 0; - } - - /* - * Enable DMA on any drive that has - * UltraDMA (mode 0/1/2/3/4/5/6) enabled - */ - if ((id[ATA_ID_FIELD_VALID] & 4) && - ((id[ATA_ID_UDMA_MODES] >> 8) & 0x7f)) - return 1; - - /* - * Enable DMA on any drive that has mode2 DMA - * (multi or single) enabled - */ - if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */ - if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 || - (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404) - return 1; - - /* Consult the list of known "good" drives */ - if (ide_dma_good_drive(drive)) - return 1; - - return 0; -} - -/** - * dma_timer_expiry - handle a DMA timeout - * @drive: Drive that timed out - * - * An IDE DMA transfer timed out. In the event of an error we ask - * the driver to resolve the problem, if a DMA transfer is still - * in progress we continue to wait (arguably we need to add a - * secondary 'I don't care what the drive thinks' timeout here) - * Finally if we have an interrupt we let it complete the I/O. - * But only one time - we clear expiry and if it's still not - * completed after WAIT_CMD, we error and retry in PIO. - * This can occur if an interrupt is lost or due to hang or bugs. - */ - -static int dma_timer_expiry (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - - printk(KERN_WARNING "%s: dma_timer_expiry: dma status == 0x%02x\n", - drive->name, dma_stat); - - if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */ - return WAIT_CMD; - - HWGROUP(drive)->expiry = NULL; /* one free ride for now */ - - /* 1 dmaing, 2 error, 4 intr */ - if (dma_stat & 2) /* ERROR */ - return -1; - - if (dma_stat & 1) /* DMAing */ - return WAIT_CMD; - - if (dma_stat & 4) /* Got an Interrupt */ - return WAIT_CMD; - - return 0; /* Status is unknown -- reset the bus */ -} - -/** - * ide_dma_host_set - Enable/disable DMA on a host - * @drive: drive to control - * - * Enable/disable DMA on an IDE controller following generic - * bus-mastering IDE controller behaviour. - */ - -void ide_dma_host_set(ide_drive_t *drive, int on) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 unit = (drive->select.b.unit & 0x01); - u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - - if (on) - dma_stat |= (1 << (5 + unit)); - else - dma_stat &= ~(1 << (5 + unit)); - - if (hwif->host_flags & IDE_HFLAG_MMIO) - writeb(dma_stat, - (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); - else - outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS); -} - -EXPORT_SYMBOL_GPL(ide_dma_host_set); -#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ - /** * ide_dma_off_quietly - Generic DMA kill * @drive: drive to control * - * Turn off the current DMA on this IDE controller. + * Turn off the current DMA on this IDE controller. */ void ide_dma_off_quietly(ide_drive_t *drive) { - drive->using_dma = 0; + drive->dev_flags &= ~IDE_DFLAG_USING_DMA; ide_toggle_bounce(drive, 0); drive->hwif->dma_ops->dma_host_set(drive, 0); } - EXPORT_SYMBOL(ide_dma_off_quietly); /** @@ -418,7 +190,6 @@ void ide_dma_off(ide_drive_t *drive) printk(KERN_INFO "%s: DMA disabled\n", drive->name); ide_dma_off_quietly(drive); } - EXPORT_SYMBOL(ide_dma_off); /** @@ -430,167 +201,13 @@ EXPORT_SYMBOL(ide_dma_off); void ide_dma_on(ide_drive_t *drive) { - drive->using_dma = 1; + drive->dev_flags |= IDE_DFLAG_USING_DMA; ide_toggle_bounce(drive, 1); drive->hwif->dma_ops->dma_host_set(drive, 1); } -#ifdef CONFIG_BLK_DEV_IDEDMA_SFF -/** - * ide_dma_setup - begin a DMA phase - * @drive: target device - * - * Build an IDE DMA PRD (IDE speak for scatter gather table) - * and then set up the DMA transfer registers for a device - * that follows generic IDE PCI DMA behaviour. Controllers can - * override this function if they need to - * - * Returns 0 on success. If a PIO fallback is required then 1 - * is returned. - */ - -int ide_dma_setup(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - struct request *rq = HWGROUP(drive)->rq; - unsigned int reading; - u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 dma_stat; - - if (rq_data_dir(rq)) - reading = 0; - else - reading = 1 << 3; - - /* fall back to pio! */ - if (!ide_build_dmatable(drive, rq)) { - ide_map_sg(drive, rq); - return 1; - } - - /* PRD table */ - if (hwif->host_flags & IDE_HFLAG_MMIO) - writel(hwif->dmatable_dma, - (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); - else - outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS); - - /* specify r/w */ - if (mmio) - writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - else - outb(reading, hwif->dma_base + ATA_DMA_CMD); - - /* read DMA status for INTR & ERROR flags */ - dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - - /* clear INTR & ERROR flags */ - if (mmio) - writeb(dma_stat | 6, - (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); - else - outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); - - drive->waiting_for_dma = 1; - return 0; -} - -EXPORT_SYMBOL_GPL(ide_dma_setup); - -void ide_dma_exec_cmd(ide_drive_t *drive, u8 command) -{ - /* issue cmd to drive */ - ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry); -} -EXPORT_SYMBOL_GPL(ide_dma_exec_cmd); - -void ide_dma_start(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 dma_cmd; - - /* Note that this is done *after* the cmd has - * been issued to the drive, as per the BM-IDE spec. - * The Promise Ultra33 doesn't work correctly when - * we do this part before issuing the drive cmd. - */ - if (hwif->host_flags & IDE_HFLAG_MMIO) { - dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - /* start DMA */ - writeb(dma_cmd | 1, - (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - } else { - dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); - outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD); - } - - hwif->dma = 1; - wmb(); -} - -EXPORT_SYMBOL_GPL(ide_dma_start); - -/* returns 1 on error, 0 otherwise */ -int __ide_dma_end (ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 dma_stat = 0, dma_cmd = 0; - - drive->waiting_for_dma = 0; - - if (mmio) { - /* get DMA command mode */ - dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - /* stop DMA */ - writeb(dma_cmd & ~1, - (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - } else { - dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); - outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); - } - - /* get DMA status */ - dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - - if (mmio) - /* clear the INTR & ERROR bits */ - writeb(dma_stat | 6, - (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); - else - outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); - - /* purge DMA mappings */ - ide_destroy_dmatable(drive); - /* verify good DMA status */ - hwif->dma = 0; - wmb(); - return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; -} - -EXPORT_SYMBOL(__ide_dma_end); - -/* returns 1 if dma irq issued, 0 otherwise */ -int ide_dma_test_irq(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - - /* return 1 if INTR asserted */ - if ((dma_stat & 4) == 4) - return 1; - if (!drive->waiting_for_dma) - printk(KERN_WARNING "%s: (%s) called while not waiting\n", - drive->name, __func__); - return 0; -} -EXPORT_SYMBOL_GPL(ide_dma_test_irq); -#else -static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; } -#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ - -int __ide_dma_bad_drive (ide_drive_t *drive) +int __ide_dma_bad_drive(ide_drive_t *drive) { u16 *id = drive->id; @@ -602,7 +219,6 @@ int __ide_dma_bad_drive (ide_drive_t *drive) } return 0; } - EXPORT_SYMBOL(__ide_dma_bad_drive); static const u8 xfer_mode_bases[] = { @@ -618,7 +234,7 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode) const struct ide_port_ops *port_ops = hwif->port_ops; unsigned int mask = 0; - switch(base) { + switch (base) { case XFER_UDMA_0: if ((id[ATA_ID_FIELD_VALID] & 4) == 0) break; @@ -719,7 +335,6 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode) return mode; } - EXPORT_SYMBOL_GPL(ide_find_dma_mode); static int ide_tune_dma(ide_drive_t *drive) @@ -727,7 +342,8 @@ static int ide_tune_dma(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; u8 speed; - if (drive->nodma || ata_id_has_dma(drive->id) == 0) + if (ata_id_has_dma(drive->id) == 0 || + (drive->dev_flags & IDE_DFLAG_NODMA)) return 0; /* consult the list of known "bad" drives */ @@ -827,66 +443,59 @@ void ide_check_dma_crc(ide_drive_t *drive) ide_dma_on(drive); } -#ifdef CONFIG_BLK_DEV_IDEDMA_SFF -void ide_dma_lost_irq (ide_drive_t *drive) +void ide_dma_lost_irq(ide_drive_t *drive) { - printk("%s: DMA interrupt recovery\n", drive->name); + printk(KERN_ERR "%s: DMA interrupt recovery\n", drive->name); } +EXPORT_SYMBOL_GPL(ide_dma_lost_irq); -EXPORT_SYMBOL(ide_dma_lost_irq); - -void ide_dma_timeout (ide_drive_t *drive) +void ide_dma_timeout(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); + ide_hwif_t *hwif = drive->hwif; printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); if (hwif->dma_ops->dma_test_irq(drive)) return; + ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif)); + hwif->dma_ops->dma_end(drive); } - -EXPORT_SYMBOL(ide_dma_timeout); +EXPORT_SYMBOL_GPL(ide_dma_timeout); void ide_release_dma_engine(ide_hwif_t *hwif) { if (hwif->dmatable_cpu) { - struct pci_dev *pdev = to_pci_dev(hwif->dev); + int prd_size = hwif->prd_max_nents * hwif->prd_ent_size; - pci_free_consistent(pdev, PRD_ENTRIES * PRD_BYTES, - hwif->dmatable_cpu, hwif->dmatable_dma); + dma_free_coherent(hwif->dev, prd_size, + hwif->dmatable_cpu, hwif->dmatable_dma); hwif->dmatable_cpu = NULL; } } +EXPORT_SYMBOL_GPL(ide_release_dma_engine); int ide_allocate_dma_engine(ide_hwif_t *hwif) { - struct pci_dev *pdev = to_pci_dev(hwif->dev); + int prd_size; - hwif->dmatable_cpu = pci_alloc_consistent(pdev, - PRD_ENTRIES * PRD_BYTES, - &hwif->dmatable_dma); + if (hwif->prd_max_nents == 0) + hwif->prd_max_nents = PRD_ENTRIES; + if (hwif->prd_ent_size == 0) + hwif->prd_ent_size = PRD_BYTES; - if (hwif->dmatable_cpu) - return 0; + prd_size = hwif->prd_max_nents * hwif->prd_ent_size; - printk(KERN_ERR "%s: -- Error, unable to allocate DMA table.\n", + hwif->dmatable_cpu = dma_alloc_coherent(hwif->dev, prd_size, + &hwif->dmatable_dma, + GFP_ATOMIC); + if (hwif->dmatable_cpu == NULL) { + printk(KERN_ERR "%s: unable to allocate PRD table\n", hwif->name); + return -ENOMEM; + } - return 1; + return 0; } EXPORT_SYMBOL_GPL(ide_allocate_dma_engine); - -const struct ide_dma_ops sff_dma_ops = { - .dma_host_set = ide_dma_host_set, - .dma_setup = ide_dma_setup, - .dma_exec_cmd = ide_dma_exec_cmd, - .dma_start = ide_dma_start, - .dma_end = __ide_dma_end, - .dma_test_irq = ide_dma_test_irq, - .dma_timeout = ide_dma_timeout, - .dma_lost_irq = ide_dma_lost_irq, -}; -EXPORT_SYMBOL_GPL(sff_dma_ops); -#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index d36f155470a..aeb1ad782f5 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -15,11 +15,6 @@ * Documentation/ide/ChangeLog.ide-floppy.1996-2002 */ -#define DRV_NAME "ide-floppy" - -#define IDEFLOPPY_VERSION "1.00" - -#include <linux/module.h> #include <linux/types.h> #include <linux/string.h> #include <linux/kernel.h> @@ -48,19 +43,6 @@ #include "ide-floppy.h" -/* define to see debug info */ -#define IDEFLOPPY_DEBUG_LOG 0 - -/* #define IDEFLOPPY_DEBUG(fmt, args...) printk(KERN_INFO fmt, ## args) */ -#define IDEFLOPPY_DEBUG(fmt, args...) - -#if IDEFLOPPY_DEBUG_LOG -#define debug_log(fmt, args...) \ - printk(KERN_INFO "ide-floppy: " fmt, ## args) -#else -#define debug_log(fmt, args...) do {} while (0) -#endif - /* * After each failed packet command we issue a request sense command and retry * the packet command IDEFLOPPY_MAX_PC_RETRIES times. @@ -73,63 +55,40 @@ #define CAPACITY_CURRENT 0x02 #define CAPACITY_NO_CARTRIDGE 0x03 -#define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */ +/* + * The following delay solves a problem with ATAPI Zip 100 drive where BSY bit + * was apparently being deasserted before the unit was ready to receive data. + */ +#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */ /* Error code returned in rq->errors to the higher part of the driver. */ #define IDEFLOPPY_ERROR_GENERAL 101 -static DEFINE_MUTEX(idefloppy_ref_mutex); - -#define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref) - -#define ide_floppy_g(disk) \ - container_of((disk)->private_data, struct ide_floppy_obj, driver) - -static void idefloppy_cleanup_obj(struct kref *); - -static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) -{ - struct ide_floppy_obj *floppy = NULL; - - mutex_lock(&idefloppy_ref_mutex); - floppy = ide_floppy_g(disk); - if (floppy) { - if (ide_device_get(floppy->drive)) - floppy = NULL; - else - kref_get(&floppy->kref); - } - mutex_unlock(&idefloppy_ref_mutex); - return floppy; -} - -static void ide_floppy_put(struct ide_floppy_obj *floppy) -{ - ide_drive_t *drive = floppy->drive; - - mutex_lock(&idefloppy_ref_mutex); - kref_put(&floppy->kref, idefloppy_cleanup_obj); - ide_device_put(drive); - mutex_unlock(&idefloppy_ref_mutex); -} - /* * Used to finish servicing a request. For read/write requests, we will call * ide_end_request to pass to the next buffer. */ -static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) +static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) { - idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_disk_obj *floppy = drive->driver_data; struct request *rq = HWGROUP(drive)->rq; int error; - debug_log("Reached %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); switch (uptodate) { - case 0: error = IDEFLOPPY_ERROR_GENERAL; break; - case 1: error = 0; break; - default: error = uptodate; + case 0: + error = IDEFLOPPY_ERROR_GENERAL; + break; + + case 1: + error = 0; + break; + + default: + error = uptodate; } + if (error) floppy->failed_pc = NULL; /* Why does this happen? */ @@ -153,16 +112,16 @@ static void idefloppy_update_buffers(ide_drive_t *drive, struct bio *bio = rq->bio; while ((bio = rq->bio) != NULL) - idefloppy_end_request(drive, 1, 0); + ide_floppy_end_request(drive, 1, 0); } -static void ide_floppy_callback(ide_drive_t *drive) +static void ide_floppy_callback(ide_drive_t *drive, int dsc) { - idefloppy_floppy_t *floppy = drive->driver_data; - struct ide_atapi_pc *pc = floppy->pc; + struct ide_disk_obj *floppy = drive->driver_data; + struct ide_atapi_pc *pc = drive->pc; int uptodate = pc->error ? 0 : 1; - debug_log("Reached %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if (floppy->failed_pc == pc) floppy->failed_pc = NULL; @@ -171,7 +130,7 @@ static void ide_floppy_callback(ide_drive_t *drive) (pc->rq && blk_pc_request(pc->rq))) uptodate = 1; /* FIXME */ else if (pc->c[0] == GPCMD_REQUEST_SENSE) { - u8 *buf = floppy->pc->buf; + u8 *buf = pc->buf; if (!pc->error) { floppy->sense_key = buf[2] & 0x0F; @@ -181,100 +140,21 @@ static void ide_floppy_callback(ide_drive_t *drive) (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; if (floppy->failed_pc) - debug_log("pc = %x, ", floppy->failed_pc->c[0]); + ide_debug_log(IDE_DBG_PC, "pc = %x, ", + floppy->failed_pc->c[0]); - debug_log("sense key = %x, asc = %x, ascq = %x\n", - floppy->sense_key, floppy->asc, floppy->ascq); + ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x," + "ascq = %x\n", floppy->sense_key, + floppy->asc, floppy->ascq); } else - printk(KERN_ERR "Error in REQUEST SENSE itself - " - "Aborting request!\n"); - } - - idefloppy_end_request(drive, uptodate, 0); -} - -void ide_floppy_create_request_sense_cmd(struct ide_atapi_pc *pc) -{ - ide_init_pc(pc); - pc->c[0] = GPCMD_REQUEST_SENSE; - pc->c[4] = 255; - pc->req_xfer = 18; -} - -/* - * Called when an error was detected during the last packet command. We queue a - * request sense packet command in the head of the request list. - */ -static void idefloppy_retry_pc(ide_drive_t *drive) -{ - struct ide_floppy_obj *floppy = drive->driver_data; - struct request *rq = &floppy->request_sense_rq; - struct ide_atapi_pc *pc = &floppy->request_sense_pc; - - (void)ide_read_error(drive); - ide_floppy_create_request_sense_cmd(pc); - ide_queue_pc_head(drive, floppy->disk, pc, rq); -} - -/* The usual interrupt handler called during a packet command. */ -static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - - return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr, - WAIT_FLOPPY_CMD, NULL, idefloppy_update_buffers, - idefloppy_retry_pc, NULL, ide_io_buffers); -} - -/* - * What we have here is a classic case of a top half / bottom half interrupt - * service routine. In interrupt mode, the device sends an interrupt to signal - * that it is ready to receive a packet. However, we need to delay about 2-3 - * ticks before issuing the packet or we gets in trouble. - */ -static int idefloppy_transfer_pc(ide_drive_t *drive) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - - /* Send the actual packet */ - drive->hwif->tp_ops->output_data(drive, NULL, floppy->pc->c, 12); - - /* Timeout for the packet command */ - return WAIT_FLOPPY_CMD; -} - -/* - * Called as an interrupt (or directly). When the device says it's ready for a - * packet, we schedule the packet transfer to occur about 2-3 ticks later in - * transfer_pc. - */ -static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - struct ide_atapi_pc *pc = floppy->pc; - ide_expiry_t *expiry; - unsigned int timeout; - - /* - * The following delay solves a problem with ATAPI Zip 100 drives - * where the Busy flag was apparently being deasserted before the - * unit was ready to receive data. This was happening on a - * 1200 MHz Athlon system. 10/26/01 25msec is too short, - * 40 and 50msec work well. idefloppy_pc_intr will not be actually - * used until after the packet is moved in about 50 msec. - */ - if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { - timeout = floppy->ticks; - expiry = &idefloppy_transfer_pc; - } else { - timeout = WAIT_FLOPPY_CMD; - expiry = NULL; + printk(KERN_ERR PFX "Error in REQUEST SENSE itself - " + "Aborting request!\n"); } - return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry); + ide_floppy_end_request(drive, uptodate, 0); } -static void ide_floppy_report_error(idefloppy_floppy_t *floppy, +static void ide_floppy_report_error(struct ide_disk_obj *floppy, struct ide_atapi_pc *pc) { /* supress error messages resulting from Medium not present */ @@ -283,7 +163,7 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy, floppy->ascq == 0x00) return; - printk(KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, " + printk(KERN_ERR PFX "%s: I/O error, pc = %2x, key = %2x, " "asc = %2x, ascq = %2x\n", floppy->drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq); @@ -293,13 +173,14 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy, static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc) { - idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_disk_obj *floppy = drive->driver_data; if (floppy->failed_pc == NULL && pc->c[0] != GPCMD_REQUEST_SENSE) floppy->failed_pc = pc; + /* Set the current packet command */ - floppy->pc = pc; + drive->pc = pc; if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) @@ -308,16 +189,15 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, pc->error = IDEFLOPPY_ERROR_GENERAL; floppy->failed_pc = NULL; - drive->pc_callback(drive); + drive->pc_callback(drive, 0); return ide_stopped; } - debug_log("Retry number - %d\n", pc->retries); + ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries); pc->retries++; - return ide_issue_pc(drive, pc, idefloppy_start_pc_transfer, - WAIT_FLOPPY_CMD, NULL); + return ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL); } void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) @@ -347,23 +227,23 @@ void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) length += 32; break; default: - printk(KERN_ERR "ide-floppy: unsupported page code " - "in create_mode_sense_cmd\n"); + printk(KERN_ERR PFX "unsupported page code in %s\n", __func__); } put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); pc->req_xfer = length; } -static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, +static void idefloppy_create_rw_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc, struct request *rq, unsigned long sector) { + struct ide_disk_obj *floppy = drive->driver_data; int block = sector / floppy->bs_factor; int blocks = rq->nr_sectors / floppy->bs_factor; int cmd = rq_data_dir(rq); - debug_log("create_rw10_cmd: block == %d, blocks == %d\n", - block, blocks); + ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__, + block, blocks); ide_init_pc(pc); pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; @@ -381,7 +261,7 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, pc->flags |= PC_FLAG_DMA_OK; } -static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, +static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, struct ide_atapi_pc *pc, struct request *rq) { ide_init_pc(pc); @@ -400,50 +280,50 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, pc->req_xfer = pc->buf_size = rq->data_len; } -static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, - struct request *rq, sector_t block_s) +static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, + struct request *rq, sector_t block) { - idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_disk_obj *floppy = drive->driver_data; ide_hwif_t *hwif = drive->hwif; struct ide_atapi_pc *pc; - unsigned long block = (unsigned long)block_s; - debug_log("%s: dev: %s, cmd: 0x%x, cmd_type: %x, errors: %d\n", - __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?", - rq->cmd[0], rq->cmd_type, rq->errors); + ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " + "errors: %d\n", + __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?", + rq->cmd[0], rq->cmd_type, rq->errors); - debug_log("%s: sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n", - __func__, (long)rq->sector, rq->nr_sectors, - rq->current_nr_sectors); + ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, " + "current_nr_sectors: %d\n", + __func__, (long)rq->sector, rq->nr_sectors, + rq->current_nr_sectors); if (rq->errors >= ERROR_MAX) { if (floppy->failed_pc) ide_floppy_report_error(floppy, floppy->failed_pc); else - printk(KERN_ERR "ide-floppy: %s: I/O error\n", - drive->name); - idefloppy_end_request(drive, 0, 0); + printk(KERN_ERR PFX "%s: I/O error\n", drive->name); + + ide_floppy_end_request(drive, 0, 0); return ide_stopped; } if (blk_fs_request(rq)) { if (((long)rq->sector % floppy->bs_factor) || (rq->nr_sectors % floppy->bs_factor)) { - printk(KERN_ERR "%s: unsupported r/w request size\n", - drive->name); - idefloppy_end_request(drive, 0, 0); + printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", + drive->name); + ide_floppy_end_request(drive, 0, 0); return ide_stopped; } pc = &floppy->queued_pc; - idefloppy_create_rw_cmd(floppy, pc, rq, block); + idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); } else if (blk_special_request(rq)) { pc = (struct ide_atapi_pc *) rq->buffer; } else if (blk_pc_request(rq)) { pc = &floppy->queued_pc; idefloppy_blockpc_cmd(floppy, pc, rq); } else { - blk_dump_rq_flags(rq, - "ide-floppy: unsupported command in queue"); - idefloppy_end_request(drive, 0, 0); + blk_dump_rq_flags(rq, PFX "unsupported command in queue"); + ide_floppy_end_request(drive, 0, 0); return ide_stopped; } @@ -464,7 +344,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, */ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) { - idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_disk_obj *floppy = drive->driver_data; struct gendisk *disk = floppy->disk; struct ide_atapi_pc pc; u8 *page; @@ -475,17 +355,16 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); if (ide_queue_pc_tail(drive, disk, &pc)) { - printk(KERN_ERR "ide-floppy: Can't get flexible disk page" - " parameters\n"); + printk(KERN_ERR PFX "Can't get flexible disk page params\n"); return 1; } if (pc.buf[3] & 0x80) - drive->atapi_flags |= IDE_AFLAG_WP; + drive->dev_flags |= IDE_DFLAG_WP; else - drive->atapi_flags &= ~IDE_AFLAG_WP; + drive->dev_flags &= ~IDE_DFLAG_WP; - set_disk_ro(disk, !!(drive->atapi_flags & IDE_AFLAG_WP)); + set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); page = &pc.buf[8]; @@ -499,7 +378,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) capacity = cyls * heads * sectors * sector_size; if (memcmp(page, &floppy->flexible_disk_page, 32)) - printk(KERN_INFO "%s: %dkB, %d/%d/%d CHS, %d kBps, " + printk(KERN_INFO PFX "%s: %dkB, %d/%d/%d CHS, %d kBps, " "%d sector size, %d rpm\n", drive->name, capacity / 1024, cyls, heads, sectors, transfer_rate / 8, sector_size, rpm); @@ -511,12 +390,14 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) lba_capacity = floppy->blocks * floppy->block_size; if (capacity < lba_capacity) { - printk(KERN_NOTICE "%s: The disk reports a capacity of %d " + printk(KERN_NOTICE PFX "%s: The disk reports a capacity of %d " "bytes, but the drive only handles %d\n", drive->name, lba_capacity, capacity); floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0; + drive->capacity64 = floppy->blocks * floppy->bs_factor; } + return 0; } @@ -526,7 +407,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) */ static int ide_floppy_get_capacity(ide_drive_t *drive) { - idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_disk_obj *floppy = drive->driver_data; struct gendisk *disk = floppy->disk; struct ide_atapi_pc pc; u8 *cap_desc; @@ -537,11 +418,11 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) drive->bios_head = drive->bios_sect = 0; floppy->blocks = 0; floppy->bs_factor = 1; - set_capacity(floppy->disk, 0); + drive->capacity64 = 0; ide_floppy_create_read_capacity_cmd(&pc); if (ide_queue_pc_tail(drive, disk, &pc)) { - printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); + printk(KERN_ERR PFX "Can't get floppy parameters\n"); return 1; } header_len = pc.buf[3]; @@ -554,8 +435,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); - debug_log("Descriptor %d: %dkB, %d blocks, %d sector size\n", - i, blocks * length / 1024, blocks, length); + ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " + "%d sector size\n", + i, blocks * length / 1024, blocks, length); if (i) continue; @@ -575,23 +457,26 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) case CAPACITY_CURRENT: /* Normal Zip/LS-120 disks */ if (memcmp(cap_desc, &floppy->cap_desc, 8)) - printk(KERN_INFO "%s: %dkB, %d blocks, %d " - "sector size\n", drive->name, - blocks * length / 1024, blocks, length); + printk(KERN_INFO PFX "%s: %dkB, %d blocks, %d " + "sector size\n", + drive->name, blocks * length / 1024, + blocks, length); memcpy(&floppy->cap_desc, cap_desc, 8); if (!length || length % 512) { - printk(KERN_NOTICE "%s: %d bytes block size " - "not supported\n", drive->name, length); + printk(KERN_NOTICE PFX "%s: %d bytes block size" + " not supported\n", drive->name, length); } else { floppy->blocks = blocks; floppy->block_size = length; floppy->bs_factor = length / 512; if (floppy->bs_factor != 1) - printk(KERN_NOTICE "%s: warning: non " - "512 bytes block size not " - "fully supported\n", - drive->name); + printk(KERN_NOTICE PFX "%s: Warning: " + "non 512 bytes block size not " + "fully supported\n", + drive->name); + drive->capacity64 = + floppy->blocks * floppy->bs_factor; rc = 0; } break; @@ -600,74 +485,34 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) * This is a KERN_ERR so it appears on screen * for the user to see */ - printk(KERN_ERR "%s: No disk in drive\n", drive->name); + printk(KERN_ERR PFX "%s: No disk in drive\n", + drive->name); break; case CAPACITY_INVALID: - printk(KERN_ERR "%s: Invalid capacity for disk " + printk(KERN_ERR PFX "%s: Invalid capacity for disk " "in drive\n", drive->name); break; } - debug_log("Descriptor 0 Code: %d\n", - pc.buf[desc_start + 4] & 0x03); + ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n", + pc.buf[desc_start + 4] & 0x03); } /* Clik! disk does not support get_flexible_disk_page */ if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) (void) ide_floppy_get_flexible_disk_page(drive); - set_capacity(disk, floppy->blocks * floppy->bs_factor); - return rc; } -static sector_t idefloppy_capacity(ide_drive_t *drive) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - unsigned long capacity = floppy->blocks * floppy->bs_factor; - - return capacity; -} - -#ifdef CONFIG_IDE_PROC_FS -ide_devset_rw_field(bios_cyl, bios_cyl); -ide_devset_rw_field(bios_head, bios_head); -ide_devset_rw_field(bios_sect, bios_sect); - -static int get_ticks(ide_drive_t *drive) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - return floppy->ticks; -} - -static int set_ticks(ide_drive_t *drive, int arg) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - floppy->ticks = arg; - return 0; -} - -IDE_DEVSET(ticks, DS_SYNC, get_ticks, set_ticks); - -static const struct ide_proc_devset idefloppy_settings[] = { - IDE_PROC_DEVSET(bios_cyl, 0, 1023), - IDE_PROC_DEVSET(bios_head, 0, 255), - IDE_PROC_DEVSET(bios_sect, 0, 63), - IDE_PROC_DEVSET(ticks, 0, 255), - { 0 }, -}; -#endif - -static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) +static void ide_floppy_setup(ide_drive_t *drive) { + struct ide_disk_obj *floppy = drive->driver_data; u16 *id = drive->id; - u8 gcw[2]; - *((u16 *)&gcw) = id[ATA_ID_CONFIG]; + drive->pc_callback = ide_floppy_callback; + drive->pc_update_buffers = idefloppy_update_buffers; + drive->pc_io_buffers = ide_io_buffers; - drive->pc_callback = ide_floppy_callback; - - if (((gcw[0] & 0x60) >> 5) == 1) - drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; /* * We used to check revisions here. At this point however I'm giving up. * Just assume they are all broken, its easier. @@ -680,7 +525,7 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) if (!strncmp((char *)&id[ATA_ID_PROD], "IOMEGA ZIP 100 ATAPI", 20)) { drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE; /* This value will be visible in the /proc/ide/hdx/settings */ - floppy->ticks = IDEFLOPPY_TICKS_DELAY; + drive->pc_delay = IDEFLOPPY_PC_DELAY; blk_queue_max_sectors(drive->queue, 64); } @@ -692,316 +537,42 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) blk_queue_max_sectors(drive->queue, 64); drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; /* IOMEGA Clik! drives do not support lock/unlock commands */ - drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; + drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; } (void) ide_floppy_get_capacity(drive); ide_proc_register_driver(drive, floppy->driver); -} -static void ide_floppy_remove(ide_drive_t *drive) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - struct gendisk *g = floppy->disk; - - ide_proc_unregister_driver(drive, floppy->driver); - - del_gendisk(g); - - ide_floppy_put(floppy); + drive->dev_flags |= IDE_DFLAG_ATTACH; } -static void idefloppy_cleanup_obj(struct kref *kref) +static void ide_floppy_flush(ide_drive_t *drive) { - struct ide_floppy_obj *floppy = to_ide_floppy(kref); - ide_drive_t *drive = floppy->drive; - struct gendisk *g = floppy->disk; - - drive->driver_data = NULL; - g->private_data = NULL; - put_disk(g); - kfree(floppy); } -#ifdef CONFIG_IDE_PROC_FS -static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk) { - ide_drive_t*drive = (ide_drive_t *)data; - int len; - - len = sprintf(page, "%llu\n", (long long)idefloppy_capacity(drive)); - PROC_IDE_READ_RETURN(page, start, off, count, eof, len); -} - -static ide_proc_entry_t idefloppy_proc[] = { - { "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL }, - { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, - { NULL, 0, NULL, NULL } -}; -#endif /* CONFIG_IDE_PROC_FS */ - -static int ide_floppy_probe(ide_drive_t *); - -static ide_driver_t idefloppy_driver = { - .gen_driver = { - .owner = THIS_MODULE, - .name = "ide-floppy", - .bus = &ide_bus_type, - }, - .probe = ide_floppy_probe, - .remove = ide_floppy_remove, - .version = IDEFLOPPY_VERSION, - .media = ide_floppy, - .do_request = idefloppy_do_request, - .end_request = idefloppy_end_request, - .error = __ide_error, -#ifdef CONFIG_IDE_PROC_FS - .proc = idefloppy_proc, - .settings = idefloppy_settings, -#endif -}; - -static int idefloppy_open(struct inode *inode, struct file *filp) -{ - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_floppy_obj *floppy; - ide_drive_t *drive; int ret = 0; - debug_log("Reached %s\n", __func__); - - floppy = ide_floppy_get(disk); - if (!floppy) - return -ENXIO; - - drive = floppy->drive; - - floppy->openers++; - - if (floppy->openers == 1) { - drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; - /* Just in case */ - - if (ide_do_test_unit_ready(drive, disk)) - ide_do_start_stop(drive, disk, 1); - - if (ide_floppy_get_capacity(drive) - && (filp->f_flags & O_NDELAY) == 0 - /* - * Allow O_NDELAY to open a drive without a disk, or with an - * unreadable disk, so that we can get the format capacity - * of the drive or begin the format - Sam - */ - ) { - ret = -EIO; - goto out_put_floppy; - } + if (ide_do_test_unit_ready(drive, disk)) + ide_do_start_stop(drive, disk, 1); - if ((drive->atapi_flags & IDE_AFLAG_WP) && (filp->f_mode & 2)) { - ret = -EROFS; - goto out_put_floppy; - } + ret = ide_floppy_get_capacity(drive); - drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED; - ide_set_media_lock(drive, disk, 1); - check_disk_change(inode->i_bdev); - } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) { - ret = -EBUSY; - goto out_put_floppy; - } - return 0; + set_capacity(disk, ide_gd_capacity(drive)); -out_put_floppy: - floppy->openers--; - ide_floppy_put(floppy); return ret; } -static int idefloppy_release(struct inode *inode, struct file *filp) -{ - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_floppy_obj *floppy = ide_floppy_g(disk); - ide_drive_t *drive = floppy->drive; - - debug_log("Reached %s\n", __func__); - - if (floppy->openers == 1) { - ide_set_media_lock(drive, disk, 0); - drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; - } - - floppy->openers--; - - ide_floppy_put(floppy); - - return 0; -} - -static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); - ide_drive_t *drive = floppy->drive; - - geo->heads = drive->bios_head; - geo->sectors = drive->bios_sect; - geo->cylinders = (u16)drive->bios_cyl; /* truncate */ - return 0; -} - -static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned long arg, unsigned int cmd) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - struct gendisk *disk = floppy->disk; - int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; - - if (floppy->openers > 1) - return -EBUSY; - - ide_set_media_lock(drive, disk, prevent); - - if (cmd == CDROMEJECT) - ide_do_start_stop(drive, disk, 2); - - return 0; -} - -static int idefloppy_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct block_device *bdev = inode->i_bdev; - struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); - ide_drive_t *drive = floppy->drive; - struct ide_atapi_pc pc; - void __user *argp = (void __user *)arg; - int err; - - if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) - return ide_floppy_lockdoor(drive, &pc, arg, cmd); - - err = ide_floppy_format_ioctl(drive, file, cmd, argp); - if (err != -ENOTTY) - return err; - - /* - * skip SCSI_IOCTL_SEND_COMMAND (deprecated) - * and CDROM_SEND_PACKET (legacy) ioctls - */ - if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND) - err = scsi_cmd_ioctl(file, bdev->bd_disk->queue, - bdev->bd_disk, cmd, argp); - - if (err == -ENOTTY) - err = generic_ide_ioctl(drive, file, bdev, cmd, arg); - - return err; -} - -static int idefloppy_media_changed(struct gendisk *disk) -{ - struct ide_floppy_obj *floppy = ide_floppy_g(disk); - ide_drive_t *drive = floppy->drive; - int ret; - - /* do not scan partitions twice if this is a removable device */ - if (drive->attach) { - drive->attach = 0; - return 0; - } - ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED); - drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED; - return ret; -} - -static int idefloppy_revalidate_disk(struct gendisk *disk) -{ - struct ide_floppy_obj *floppy = ide_floppy_g(disk); - set_capacity(disk, idefloppy_capacity(floppy->drive)); - return 0; -} - -static struct block_device_operations idefloppy_ops = { - .owner = THIS_MODULE, - .open = idefloppy_open, - .release = idefloppy_release, - .ioctl = idefloppy_ioctl, - .getgeo = idefloppy_getgeo, - .media_changed = idefloppy_media_changed, - .revalidate_disk = idefloppy_revalidate_disk +const struct ide_disk_ops ide_atapi_disk_ops = { + .check = ide_check_atapi_device, + .get_capacity = ide_floppy_get_capacity, + .setup = ide_floppy_setup, + .flush = ide_floppy_flush, + .init_media = ide_floppy_init_media, + .set_doorlock = ide_set_media_lock, + .do_request = ide_floppy_do_request, + .end_request = ide_floppy_end_request, + .ioctl = ide_floppy_ioctl, }; - -static int ide_floppy_probe(ide_drive_t *drive) -{ - idefloppy_floppy_t *floppy; - struct gendisk *g; - - if (!strstr("ide-floppy", drive->driver_req)) - goto failed; - - if (drive->media != ide_floppy) - goto failed; - - if (!ide_check_atapi_device(drive, DRV_NAME)) { - printk(KERN_ERR "ide-floppy: %s: not supported by this version" - " of ide-floppy\n", drive->name); - goto failed; - } - floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); - if (!floppy) { - printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy" - " structure\n", drive->name); - goto failed; - } - - g = alloc_disk(1 << PARTN_BITS); - if (!g) - goto out_free_floppy; - - ide_init_disk(g, drive); - - kref_init(&floppy->kref); - - floppy->drive = drive; - floppy->driver = &idefloppy_driver; - floppy->disk = g; - - g->private_data = &floppy->driver; - - drive->driver_data = floppy; - - idefloppy_setup(drive, floppy); - - g->minors = 1 << PARTN_BITS; - g->driverfs_dev = &drive->gendev; - g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; - g->fops = &idefloppy_ops; - drive->attach = 1; - add_disk(g); - return 0; - -out_free_floppy: - kfree(floppy); -failed: - return -ENODEV; -} - -static void __exit idefloppy_exit(void) -{ - driver_unregister(&idefloppy_driver.gen_driver); -} - -static int __init idefloppy_init(void) -{ - printk("ide-floppy driver " IDEFLOPPY_VERSION "\n"); - return driver_register(&idefloppy_driver.gen_driver); -} - -MODULE_ALIAS("ide:*m-floppy*"); -MODULE_ALIAS("ide-floppy"); -module_init(idefloppy_init); -module_exit(idefloppy_exit); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); - diff --git a/drivers/ide/ide-floppy.h b/drivers/ide/ide-floppy.h index ecadc2bc322..c17124dd607 100644 --- a/drivers/ide/ide-floppy.h +++ b/drivers/ide/ide-floppy.h @@ -1,43 +1,9 @@ #ifndef __IDE_FLOPPY_H #define __IDE_FLOPPY_H -/* - * Most of our global data which we need to save even as we leave the driver - * due to an interrupt or a timer event is stored in a variable of type - * idefloppy_floppy_t, defined below. - */ -typedef struct ide_floppy_obj { - ide_drive_t *drive; - ide_driver_t *driver; - struct gendisk *disk; - struct kref kref; - unsigned int openers; /* protected by BKL for now */ - - /* Current packet command */ - struct ide_atapi_pc *pc; - /* Last failed packet command */ - struct ide_atapi_pc *failed_pc; - /* used for blk_{fs,pc}_request() requests */ - struct ide_atapi_pc queued_pc; - - struct ide_atapi_pc request_sense_pc; - struct request request_sense_rq; - - /* Last error information */ - u8 sense_key, asc, ascq; - /* delay this long before sending packet command */ - u8 ticks; - int progress_indication; - - /* Device information */ - /* Current format */ - int blocks, block_size, bs_factor; - /* Last format capacity descriptor */ - u8 cap_desc[8]; - /* Copy of the flexible disk page */ - u8 flexible_disk_page[32]; -} idefloppy_floppy_t; +#include "ide-gd.h" +#ifdef CONFIG_IDE_GD_ATAPI /* * Pages of the SELECT SENSE / MODE SENSE packet commands. * See SFF-8070i spec. @@ -52,12 +18,22 @@ typedef struct ide_floppy_obj { #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 /* ide-floppy.c */ +extern const struct ide_disk_ops ide_atapi_disk_ops; void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8); void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *); -void ide_floppy_create_request_sense_cmd(struct ide_atapi_pc *); /* ide-floppy_ioctl.c */ -int ide_floppy_format_ioctl(ide_drive_t *, struct file *, unsigned int, - void __user *); +int ide_floppy_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, + unsigned long); + +#ifdef CONFIG_IDE_PROC_FS +/* ide-floppy_proc.c */ +extern ide_proc_entry_t ide_floppy_proc[]; +extern const struct ide_proc_devset ide_floppy_settings[]; +#endif +#else +#define ide_floppy_proc NULL +#define ide_floppy_settings NULL +#endif #endif /*__IDE_FLOPPY_H */ diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c index 5ffc4512d14..409e4c15f9b 100644 --- a/drivers/ide/ide-floppy_ioctl.c +++ b/drivers/ide/ide-floppy_ioctl.c @@ -33,7 +33,7 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) { - struct ide_floppy_obj *floppy = drive->driver_data; + struct ide_disk_obj *floppy = drive->driver_data; struct ide_atapi_pc pc; u8 header_len, desc_cnt; int i, blocks, length, u_array_size, u_index; @@ -113,7 +113,7 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, static int ide_floppy_get_sfrp_bit(ide_drive_t *drive) { - idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_disk_obj *floppy = drive->driver_data; struct ide_atapi_pc pc; drive->atapi_flags &= ~IDE_AFLAG_SRFP; @@ -132,17 +132,17 @@ static int ide_floppy_get_sfrp_bit(ide_drive_t *drive) static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) { - idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_disk_obj *floppy = drive->driver_data; struct ide_atapi_pc pc; int blocks, length, flags, err = 0; if (floppy->openers > 1) { /* Don't format if someone is using the disk */ - drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; + drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; return -EBUSY; } - drive->atapi_flags |= IDE_AFLAG_FORMAT_IN_PROGRESS; + drive->dev_flags |= IDE_DFLAG_FORMAT_IN_PROGRESS; /* * Send ATAPI_FORMAT_UNIT to the drive. @@ -174,7 +174,7 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) out: if (err) - drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; + drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; return err; } @@ -190,12 +190,12 @@ out: static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) { - idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_disk_obj *floppy = drive->driver_data; struct ide_atapi_pc pc; int progress_indication = 0x10000; if (drive->atapi_flags & IDE_AFLAG_SRFP) { - ide_floppy_create_request_sense_cmd(&pc); + ide_create_request_sense_cmd(drive, &pc); if (ide_queue_pc_tail(drive, floppy->disk, &pc)) return -EIO; @@ -223,8 +223,26 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) return 0; } -int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, - unsigned int cmd, void __user *argp) +static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, + unsigned long arg, unsigned int cmd) +{ + struct ide_disk_obj *floppy = drive->driver_data; + struct gendisk *disk = floppy->disk; + int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; + + if (floppy->openers > 1) + return -EBUSY; + + ide_set_media_lock(drive, disk, prevent); + + if (cmd == CDROMEJECT) + ide_do_start_stop(drive, disk, 2); + + return 0; +} + +static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, + unsigned int cmd, void __user *argp) { switch (cmd) { case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED: @@ -241,3 +259,32 @@ int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, return -ENOTTY; } } + +int ide_floppy_ioctl(ide_drive_t *drive, struct inode *inode, + struct file *file, unsigned int cmd, unsigned long arg) +{ + struct block_device *bdev = inode->i_bdev; + struct ide_atapi_pc pc; + void __user *argp = (void __user *)arg; + int err; + + if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) + return ide_floppy_lockdoor(drive, &pc, arg, cmd); + + err = ide_floppy_format_ioctl(drive, file, cmd, argp); + if (err != -ENOTTY) + return err; + + /* + * skip SCSI_IOCTL_SEND_COMMAND (deprecated) + * and CDROM_SEND_PACKET (legacy) ioctls + */ + if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND) + err = scsi_cmd_ioctl(file, bdev->bd_disk->queue, + bdev->bd_disk, cmd, argp); + + if (err == -ENOTTY) + err = generic_ide_ioctl(drive, file, bdev, cmd, arg); + + return err; +} diff --git a/drivers/ide/ide-floppy_proc.c b/drivers/ide/ide-floppy_proc.c new file mode 100644 index 00000000000..3ec762cb60a --- /dev/null +++ b/drivers/ide/ide-floppy_proc.c @@ -0,0 +1,33 @@ +#include <linux/kernel.h> +#include <linux/ide.h> + +#include "ide-floppy.h" + +static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + ide_drive_t*drive = (ide_drive_t *)data; + int len; + + len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive)); + PROC_IDE_READ_RETURN(page, start, off, count, eof, len); +} + +ide_proc_entry_t ide_floppy_proc[] = { + { "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL }, + { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, + { NULL, 0, NULL, NULL } +}; + +ide_devset_rw_field(bios_cyl, bios_cyl); +ide_devset_rw_field(bios_head, bios_head); +ide_devset_rw_field(bios_sect, bios_sect); +ide_devset_rw_field(ticks, pc_delay); + +const struct ide_proc_devset ide_floppy_settings[] = { + IDE_PROC_DEVSET(bios_cyl, 0, 1023), + IDE_PROC_DEVSET(bios_head, 0, 255), + IDE_PROC_DEVSET(bios_sect, 0, 63), + IDE_PROC_DEVSET(ticks, 0, 255), + { 0 }, +}; diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c new file mode 100644 index 00000000000..d44898f46c3 --- /dev/null +++ b/drivers/ide/ide-gd.c @@ -0,0 +1,398 @@ +#include <linux/module.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/genhd.h> +#include <linux/mutex.h> +#include <linux/ide.h> +#include <linux/hdreg.h> + +#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) +#define IDE_DISK_MINORS (1 << PARTN_BITS) +#else +#define IDE_DISK_MINORS 0 +#endif + +#include "ide-disk.h" +#include "ide-floppy.h" + +#define IDE_GD_VERSION "1.18" + +/* module parameters */ +static unsigned long debug_mask; +module_param(debug_mask, ulong, 0644); + +static DEFINE_MUTEX(ide_disk_ref_mutex); + +static void ide_disk_release(struct kref *); + +static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) +{ + struct ide_disk_obj *idkp = NULL; + + mutex_lock(&ide_disk_ref_mutex); + idkp = ide_drv_g(disk, ide_disk_obj); + if (idkp) { + if (ide_device_get(idkp->drive)) + idkp = NULL; + else + kref_get(&idkp->kref); + } + mutex_unlock(&ide_disk_ref_mutex); + return idkp; +} + +static void ide_disk_put(struct ide_disk_obj *idkp) +{ + ide_drive_t *drive = idkp->drive; + + mutex_lock(&ide_disk_ref_mutex); + kref_put(&idkp->kref, ide_disk_release); + ide_device_put(drive); + mutex_unlock(&ide_disk_ref_mutex); +} + +sector_t ide_gd_capacity(ide_drive_t *drive) +{ + return drive->capacity64; +} + +static int ide_gd_probe(ide_drive_t *); + +static void ide_gd_remove(ide_drive_t *drive) +{ + struct ide_disk_obj *idkp = drive->driver_data; + struct gendisk *g = idkp->disk; + + ide_proc_unregister_driver(drive, idkp->driver); + + del_gendisk(g); + + drive->disk_ops->flush(drive); + + ide_disk_put(idkp); +} + +static void ide_disk_release(struct kref *kref) +{ + struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj); + ide_drive_t *drive = idkp->drive; + struct gendisk *g = idkp->disk; + + drive->disk_ops = NULL; + drive->driver_data = NULL; + g->private_data = NULL; + put_disk(g); + kfree(idkp); +} + +/* + * On HPA drives the capacity needs to be + * reinitilized on resume otherwise the disk + * can not be used and a hard reset is required + */ +static void ide_gd_resume(ide_drive_t *drive) +{ + if (ata_id_hpa_enabled(drive->id)) + (void)drive->disk_ops->get_capacity(drive); +} + +static void ide_gd_shutdown(ide_drive_t *drive) +{ +#ifdef CONFIG_ALPHA + /* On Alpha, halt(8) doesn't actually turn the machine off, + it puts you into the sort of firmware monitor. Typically, + it's used to boot another kernel image, so it's not much + different from reboot(8). Therefore, we don't need to + spin down the disk in this case, especially since Alpha + firmware doesn't handle disks in standby mode properly. + On the other hand, it's reasonably safe to turn the power + off when the shutdown process reaches the firmware prompt, + as the firmware initialization takes rather long time - + at least 10 seconds, which should be sufficient for + the disk to expire its write cache. */ + if (system_state != SYSTEM_POWER_OFF) { +#else + if (system_state == SYSTEM_RESTART) { +#endif + drive->disk_ops->flush(drive); + return; + } + + printk(KERN_INFO "Shutdown: %s\n", drive->name); + + drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND); +} + +#ifdef CONFIG_IDE_PROC_FS +static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive) +{ + return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc; +} + +static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive) +{ + return (drive->media == ide_disk) ? ide_disk_settings + : ide_floppy_settings; +} +#endif + +static ide_startstop_t ide_gd_do_request(ide_drive_t *drive, + struct request *rq, sector_t sector) +{ + return drive->disk_ops->do_request(drive, rq, sector); +} + +static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs) +{ + return drive->disk_ops->end_request(drive, uptodate, nrsecs); +} + +static ide_driver_t ide_gd_driver = { + .gen_driver = { + .owner = THIS_MODULE, + .name = "ide-gd", + .bus = &ide_bus_type, + }, + .probe = ide_gd_probe, + .remove = ide_gd_remove, + .resume = ide_gd_resume, + .shutdown = ide_gd_shutdown, + .version = IDE_GD_VERSION, + .do_request = ide_gd_do_request, + .end_request = ide_gd_end_request, + .error = __ide_error, +#ifdef CONFIG_IDE_PROC_FS + .proc_entries = ide_disk_proc_entries, + .proc_devsets = ide_disk_proc_devsets, +#endif +}; + +static int ide_gd_open(struct inode *inode, struct file *filp) +{ + struct gendisk *disk = inode->i_bdev->bd_disk; + struct ide_disk_obj *idkp; + ide_drive_t *drive; + int ret = 0; + + idkp = ide_disk_get(disk); + if (idkp == NULL) + return -ENXIO; + + drive = idkp->drive; + + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + + idkp->openers++; + + if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { + drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; + /* Just in case */ + + ret = drive->disk_ops->init_media(drive, disk); + + /* + * Allow O_NDELAY to open a drive without a disk, or with an + * unreadable disk, so that we can get the format capacity + * of the drive or begin the format - Sam + */ + if (ret && (filp->f_flags & O_NDELAY) == 0) { + ret = -EIO; + goto out_put_idkp; + } + + if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) { + ret = -EROFS; + goto out_put_idkp; + } + + /* + * Ignore the return code from door_lock, + * since the open() has already succeeded, + * and the door_lock is irrelevant at this point. + */ + drive->disk_ops->set_doorlock(drive, disk, 1); + drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; + check_disk_change(inode->i_bdev); + } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) { + ret = -EBUSY; + goto out_put_idkp; + } + return 0; + +out_put_idkp: + idkp->openers--; + ide_disk_put(idkp); + return ret; +} + +static int ide_gd_release(struct inode *inode, struct file *filp) +{ + struct gendisk *disk = inode->i_bdev->bd_disk; + struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); + ide_drive_t *drive = idkp->drive; + + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + + if (idkp->openers == 1) + drive->disk_ops->flush(drive); + + if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { + drive->disk_ops->set_doorlock(drive, disk, 0); + drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; + } + + idkp->openers--; + + ide_disk_put(idkp); + + return 0; +} + +static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo) +{ + struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); + ide_drive_t *drive = idkp->drive; + + geo->heads = drive->bios_head; + geo->sectors = drive->bios_sect; + geo->cylinders = (u16)drive->bios_cyl; /* truncate */ + return 0; +} + +static int ide_gd_media_changed(struct gendisk *disk) +{ + struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); + ide_drive_t *drive = idkp->drive; + int ret; + + /* do not scan partitions twice if this is a removable device */ + if (drive->dev_flags & IDE_DFLAG_ATTACH) { + drive->dev_flags &= ~IDE_DFLAG_ATTACH; + return 0; + } + + ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED); + drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; + + return ret; +} + +static int ide_gd_revalidate_disk(struct gendisk *disk) +{ + struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); + set_capacity(disk, ide_gd_capacity(idkp->drive)); + return 0; +} + +static int ide_gd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct block_device *bdev = inode->i_bdev; + struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); + ide_drive_t *drive = idkp->drive; + + return drive->disk_ops->ioctl(drive, inode, file, cmd, arg); +} + +static struct block_device_operations ide_gd_ops = { + .owner = THIS_MODULE, + .open = ide_gd_open, + .release = ide_gd_release, + .ioctl = ide_gd_ioctl, + .getgeo = ide_gd_getgeo, + .media_changed = ide_gd_media_changed, + .revalidate_disk = ide_gd_revalidate_disk +}; + +static int ide_gd_probe(ide_drive_t *drive) +{ + const struct ide_disk_ops *disk_ops = NULL; + struct ide_disk_obj *idkp; + struct gendisk *g; + + /* strstr("foo", "") is non-NULL */ + if (!strstr("ide-gd", drive->driver_req)) + goto failed; + +#ifdef CONFIG_IDE_GD_ATA + if (drive->media == ide_disk) + disk_ops = &ide_ata_disk_ops; +#endif +#ifdef CONFIG_IDE_GD_ATAPI + if (drive->media == ide_floppy) + disk_ops = &ide_atapi_disk_ops; +#endif + if (disk_ops == NULL) + goto failed; + + if (disk_ops->check(drive, DRV_NAME) == 0) { + printk(KERN_ERR PFX "%s: not supported by this driver\n", + drive->name); + goto failed; + } + + idkp = kzalloc(sizeof(*idkp), GFP_KERNEL); + if (!idkp) { + printk(KERN_ERR PFX "%s: can't allocate a disk structure\n", + drive->name); + goto failed; + } + + g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); + if (!g) + goto out_free_idkp; + + ide_init_disk(g, drive); + + kref_init(&idkp->kref); + + idkp->drive = drive; + idkp->driver = &ide_gd_driver; + idkp->disk = g; + + g->private_data = &idkp->driver; + + drive->driver_data = idkp; + drive->debug_mask = debug_mask; + drive->disk_ops = disk_ops; + + disk_ops->setup(drive); + + set_capacity(g, ide_gd_capacity(drive)); + + g->minors = IDE_DISK_MINORS; + g->driverfs_dev = &drive->gendev; + g->flags |= GENHD_FL_EXT_DEVT; + if (drive->dev_flags & IDE_DFLAG_REMOVABLE) + g->flags = GENHD_FL_REMOVABLE; + g->fops = &ide_gd_ops; + add_disk(g); + return 0; + +out_free_idkp: + kfree(idkp); +failed: + return -ENODEV; +} + +static int __init ide_gd_init(void) +{ + printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n"); + return driver_register(&ide_gd_driver.gen_driver); +} + +static void __exit ide_gd_exit(void) +{ + driver_unregister(&ide_gd_driver.gen_driver); +} + +MODULE_ALIAS("ide:*m-disk*"); +MODULE_ALIAS("ide-disk"); +MODULE_ALIAS("ide:*m-floppy*"); +MODULE_ALIAS("ide-floppy"); +module_init(ide_gd_init); +module_exit(ide_gd_exit); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("generic ATA/ATAPI disk driver"); diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h new file mode 100644 index 00000000000..7d3d101713e --- /dev/null +++ b/drivers/ide/ide-gd.h @@ -0,0 +1,44 @@ +#ifndef __IDE_GD_H +#define __IDE_GD_H + +#define DRV_NAME "ide-gd" +#define PFX DRV_NAME ": " + +/* define to see debug info */ +#define IDE_GD_DEBUG_LOG 0 + +#if IDE_GD_DEBUG_LOG +#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) +#else +#define ide_debug_log(lvl, fmt, args...) do {} while (0) +#endif + +struct ide_disk_obj { + ide_drive_t *drive; + ide_driver_t *driver; + struct gendisk *disk; + struct kref kref; + unsigned int openers; /* protected by BKL for now */ + + /* Last failed packet command */ + struct ide_atapi_pc *failed_pc; + /* used for blk_{fs,pc}_request() requests */ + struct ide_atapi_pc queued_pc; + + /* Last error information */ + u8 sense_key, asc, ascq; + + int progress_indication; + + /* Device information */ + /* Current format */ + int blocks, block_size, bs_factor; + /* Last format capacity descriptor */ + u8 cap_desc[8]; + /* Copy of the flexible disk page */ + u8 flexible_disk_page[32]; +}; + +sector_t ide_gd_capacity(ide_drive_t *); + +#endif /* __IDE_GD_H */ diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index 0a3cb0c33ae..81a5282ce1e 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c @@ -137,15 +137,10 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary) static int __init ide_generic_init(void) { - hw_regs_t hw[MAX_HWIFS], *hws[MAX_HWIFS]; - struct ide_host *host; + hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; unsigned long io_addr; - int i, rc, primary = 0, secondary = 0; + int i, rc = 0, primary = 0, secondary = 0; -#ifdef CONFIG_MIPS - if (!ide_probe_legacy()) - return -ENODEV; -#endif ide_generic_check_pci_legacy_iobases(&primary, &secondary); if (!probe_mask) { @@ -161,13 +156,9 @@ static int __init ide_generic_init(void) printk(KERN_INFO DRV_NAME ": enforcing probing of I/O ports " "upon user request\n"); - memset(hws, 0, sizeof(hw_regs_t *) * MAX_HWIFS); - for (i = 0; i < ARRAY_SIZE(legacy_bases); i++) { io_addr = legacy_bases[i]; - hws[i] = NULL; - if ((probe_mask & (1 << i)) && io_addr) { if (!request_region(io_addr, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX " @@ -184,45 +175,27 @@ static int __init ide_generic_init(void) continue; } - memset(&hw[i], 0, sizeof(hw[i])); - ide_std_init_ports(&hw[i], io_addr, io_addr + 0x206); + memset(&hw, 0, sizeof(hw)); + ide_std_init_ports(&hw, io_addr, io_addr + 0x206); #ifdef CONFIG_IA64 - hw[i].irq = isa_irq_to_vector(legacy_irqs[i]); + hw.irq = isa_irq_to_vector(legacy_irqs[i]); #else - hw[i].irq = legacy_irqs[i]; + hw.irq = legacy_irqs[i]; #endif - hw[i].chipset = ide_generic; + hw.chipset = ide_generic; - hws[i] = &hw[i]; + rc = ide_host_add(NULL, hws, NULL); + if (rc) { + release_region(io_addr + 0x206, 1); + release_region(io_addr, 8); + } } } - host = ide_host_alloc_all(NULL, hws); - if (host == NULL) { - rc = -ENOMEM; - goto err; - } - - rc = ide_host_register(host, NULL, hws); - if (rc) - goto err_free; - if (ide_generic_sysfs_init()) printk(KERN_ERR DRV_NAME ": failed to create ide_generic " "class\n"); - return 0; -err_free: - ide_host_free(host); -err: - for (i = 0; i < MAX_HWIFS; i++) { - if (hws[i] == NULL) - continue; - - io_addr = hws[i]->io_ports.data_addr; - release_region(io_addr + 0x206, 1); - release_region(io_addr, 8); - } return rc; } diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/ide-h8300.c index bde7a585f19..e2cdd2e9cde 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/ide-h8300.c @@ -80,7 +80,7 @@ static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task) outb(tf->lbah, io_ports->lbah_addr); if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) - outb((tf->device & HIHI) | drive->select.all, + outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 1c51949833b..7162d67562a 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -78,8 +78,9 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, * decide whether to reenable DMA -- 3 is a random magic for now, * if we DMA timeout more than 3 times, just stay in PIO */ - if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { - drive->state = 0; + if ((drive->dev_flags & IDE_DFLAG_DMA_PIO_RETRY) && + drive->retry_pio <= 3) { + drive->dev_flags &= ~IDE_DFLAG_DMA_PIO_RETRY; ide_dma_on(drive); } @@ -131,21 +132,6 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) } EXPORT_SYMBOL(ide_end_request); -/* - * Power Management state machine. This one is rather trivial for now, - * we should probably add more, like switching back to PIO on suspend - * to help some BIOSes, re-do the door locking on resume, etc... - */ - -enum { - ide_pm_flush_cache = ide_pm_state_start_suspend, - idedisk_pm_standby, - - idedisk_pm_restore_pio = ide_pm_state_start_resume, - idedisk_pm_idle, - ide_pm_restore_dma, -}; - static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 stat, u8 error) { struct request_pm_state *pm = rq->data; @@ -154,20 +140,20 @@ static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 s return; switch (pm->pm_step) { - case ide_pm_flush_cache: /* Suspend step 1 (flush cache) complete */ + case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ if (pm->pm_state == PM_EVENT_FREEZE) - pm->pm_step = ide_pm_state_completed; + pm->pm_step = IDE_PM_COMPLETED; else - pm->pm_step = idedisk_pm_standby; + pm->pm_step = IDE_PM_STANDBY; break; - case idedisk_pm_standby: /* Suspend step 2 (standby) complete */ - pm->pm_step = ide_pm_state_completed; + case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ + pm->pm_step = IDE_PM_COMPLETED; break; - case idedisk_pm_restore_pio: /* Resume step 1 complete */ - pm->pm_step = idedisk_pm_idle; + case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ + pm->pm_step = IDE_PM_IDLE; break; - case idedisk_pm_idle: /* Resume step 2 (idle) complete */ - pm->pm_step = ide_pm_restore_dma; + case IDE_PM_IDLE: /* Resume step 2 (idle)*/ + pm->pm_step = IDE_PM_RESTORE_DMA; break; } } @@ -180,11 +166,12 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * memset(args, 0, sizeof(*args)); switch (pm->pm_step) { - case ide_pm_flush_cache: /* Suspend step 1 (flush cache) */ + case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ if (drive->media != ide_disk) break; /* Not supported? Switch to next step now. */ - if (!drive->wcache || ata_id_flush_enabled(drive->id) == 0) { + if (ata_id_flush_enabled(drive->id) == 0 || + (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) { ide_complete_power_step(drive, rq, 0, 0); return ide_stopped; } @@ -193,27 +180,23 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * else args->tf.command = ATA_CMD_FLUSH; goto out_do_tf; - - case idedisk_pm_standby: /* Suspend step 2 (standby) */ + case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ args->tf.command = ATA_CMD_STANDBYNOW1; goto out_do_tf; - - case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */ + case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ ide_set_max_pio(drive); /* - * skip idedisk_pm_idle for ATAPI devices + * skip IDE_PM_IDLE for ATAPI devices */ if (drive->media != ide_disk) - pm->pm_step = ide_pm_restore_dma; + pm->pm_step = IDE_PM_RESTORE_DMA; else ide_complete_power_step(drive, rq, 0, 0); return ide_stopped; - - case idedisk_pm_idle: /* Resume step 2 (idle) */ + case IDE_PM_IDLE: /* Resume step 2 (idle) */ args->tf.command = ATA_CMD_IDLEIMMEDIATE; goto out_do_tf; - - case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */ + case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ /* * Right now, all we do is call ide_set_dma(drive), * we could be smarter and check for current xfer_speed @@ -222,12 +205,13 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * if (drive->hwif->dma_ops == NULL) break; /* - * TODO: respect ->using_dma setting + * TODO: respect IDE_DFLAG_USING_DMA */ ide_set_dma(drive); break; } - pm->pm_step = ide_pm_state_completed; + + pm->pm_step = IDE_PM_COMPLETED; return ide_stopped; out_do_tf: @@ -287,7 +271,7 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) if (blk_pm_suspend_request(rq)) { blk_stop_queue(drive->queue); } else { - drive->blocked = 0; + drive->dev_flags &= ~IDE_DFLAG_BLOCKED; blk_start_queue(drive->queue); } HWGROUP(drive)->rq = NULL; @@ -343,7 +327,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) drive->name, rq->pm->pm_step, stat, err); #endif ide_complete_power_step(drive, rq, stat, err); - if (pm->pm_step == ide_pm_state_completed) + if (pm->pm_step == IDE_PM_COMPLETED) ide_complete_pm_request(drive, rq); return; } @@ -374,13 +358,14 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 { ide_hwif_t *hwif = drive->hwif; - if ((stat & ATA_BUSY) || ((stat & ATA_DF) && !drive->nowerr)) { + if ((stat & ATA_BUSY) || + ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) { /* other bits are useless when BUSY */ rq->errors |= ERROR_RESET; } else if (stat & ATA_ERR) { /* err has different meaning on cdrom and tape */ if (err == ATA_ABORTED) { - if (drive->select.b.lba && + if ((drive->dev_flags & IDE_DFLAG_LBA) && /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */ hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS) return ide_stopped; @@ -428,7 +413,8 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u { ide_hwif_t *hwif = drive->hwif; - if ((stat & ATA_BUSY) || ((stat & ATA_DF) && !drive->nowerr)) { + if ((stat & ATA_BUSY) || + ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) { /* other bits are useless when BUSY */ rq->errors |= ERROR_RESET; } else { @@ -509,7 +495,7 @@ static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) tf->lbal = drive->sect; tf->lbam = drive->cyl; tf->lbah = drive->cyl >> 8; - tf->device = ((drive->head - 1) | drive->select.all) & ~ATA_LBA; + tf->device = (drive->head - 1) | drive->select; tf->command = ATA_CMD_INIT_DEV_PARAMS; } @@ -557,30 +543,6 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) return ide_started; } -/* - * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away - */ -static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) -{ - switch (req_pio) { - case 202: - case 201: - case 200: - case 102: - case 101: - case 100: - return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0; - case 9: - case 8: - return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0; - case 7: - case 6: - return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0; - default: - return 0; - } -} - /** * do_special - issue some special commands * @drive: drive the command is for @@ -598,45 +560,12 @@ static ide_startstop_t do_special (ide_drive_t *drive) #ifdef DEBUG printk("%s: do_special: 0x%02x\n", drive->name, s->all); #endif - if (s->b.set_tune) { - ide_hwif_t *hwif = drive->hwif; - const struct ide_port_ops *port_ops = hwif->port_ops; - u8 req_pio = drive->tune_req; - - s->b.set_tune = 0; - - if (set_pio_mode_abuse(drive->hwif, req_pio)) { - /* - * take ide_lock for drive->[no_]unmask/[no_]io_32bit - */ - if (req_pio == 8 || req_pio == 9) { - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); - port_ops->set_pio_mode(drive, req_pio); - spin_unlock_irqrestore(&ide_lock, flags); - } else - port_ops->set_pio_mode(drive, req_pio); - } else { - int keep_dma = drive->using_dma; - - ide_set_pio(drive, req_pio); - - if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { - if (keep_dma) - ide_dma_on(drive); - } - } - - return ide_stopped; - } else { - if (drive->media == ide_disk) - return ide_disk_special(drive); + if (drive->media == ide_disk) + return ide_disk_special(drive); - s->all = 0; - drive->mult_req = 0; - return ide_stopped; - } + s->all = 0; + drive->mult_req = 0; + return ide_stopped; } void ide_map_sg(ide_drive_t *drive, struct request *rq) @@ -726,10 +655,7 @@ int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting, if (!(setting->flags & DS_SYNC)) return setting->set(drive, arg); - rq = blk_get_request(q, READ, GFP_KERNEL); - if (!rq) - return -ENOMEM; - + rq = blk_get_request(q, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_len = 5; rq->cmd[0] = REQ_DEVSET_EXEC; @@ -746,7 +672,32 @@ EXPORT_SYMBOL_GPL(ide_devset_execute); static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) { - switch (rq->cmd[0]) { + u8 cmd = rq->cmd[0]; + + if (cmd == REQ_PARK_HEADS || cmd == REQ_UNPARK_HEADS) { + ide_task_t task; + struct ide_taskfile *tf = &task.tf; + + memset(&task, 0, sizeof(task)); + if (cmd == REQ_PARK_HEADS) { + drive->sleep = *(unsigned long *)rq->special; + drive->dev_flags |= IDE_DFLAG_SLEEPING; + tf->command = ATA_CMD_IDLEIMMEDIATE; + tf->feature = 0x44; + tf->lbal = 0x4c; + tf->lbam = 0x4e; + tf->lbah = 0x55; + task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER; + } else /* cmd == REQ_UNPARK_HEADS */ + tf->command = ATA_CMD_CHK_POWER; + + task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + task.rq = rq; + drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA; + return do_rw_taskfile(drive, &task); + } + + switch (cmd) { case REQ_DEVSET_EXEC: { int err, (*setfunc)(ide_drive_t *, int) = rq->special; @@ -773,11 +724,11 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) struct request_pm_state *pm = rq->data; if (blk_pm_suspend_request(rq) && - pm->pm_step == ide_pm_state_start_suspend) + pm->pm_step == IDE_PM_START_SUSPEND) /* Mark drive blocked when starting the suspend sequence. */ - drive->blocked = 1; + drive->dev_flags |= IDE_DFLAG_BLOCKED; else if (blk_pm_resume_request(rq) && - pm->pm_step == ide_pm_state_start_resume) { + pm->pm_step == IDE_PM_START_RESUME) { /* * The first thing we do on wakeup is to wait for BSY bit to * go away (with a looong timeout) as a drive on this hwif may @@ -857,7 +808,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) #endif startstop = ide_start_power_step(drive, rq); if (startstop == ide_stopped && - pm->pm_step == ide_pm_state_completed) + pm->pm_step == IDE_PM_COMPLETED) ide_complete_pm_request(drive, rq); return startstop; } else if (!rq->rq_disk && blk_special_request(rq)) @@ -895,7 +846,7 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) if (timeout > WAIT_WORSTCASE) timeout = WAIT_WORSTCASE; drive->sleep = timeout + jiffies; - drive->sleeping = 1; + drive->dev_flags |= IDE_DFLAG_SLEEPING; } EXPORT_SYMBOL(ide_stall_queue); @@ -935,18 +886,23 @@ repeat: } do { - if ((!drive->sleeping || time_after_eq(jiffies, drive->sleep)) - && !elv_queue_empty(drive->queue)) { - if (!best - || (drive->sleeping && (!best->sleeping || time_before(drive->sleep, best->sleep))) - || (!best->sleeping && time_before(WAKEUP(drive), WAKEUP(best)))) - { + u8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING); + u8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING)); + + if ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) && + !elv_queue_empty(drive->queue)) { + if (best == NULL || + (dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) || + (best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) { if (!blk_queue_plugged(drive->queue)) best = drive; } } } while ((drive = drive->next) != hwgroup->drive); - if (best && best->nice1 && !best->sleeping && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) { + + if (best && (best->dev_flags & IDE_DFLAG_NICE1) && + (best->dev_flags & IDE_DFLAG_SLEEPING) == 0 && + best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) { long t = (signed long)(WAKEUP(best) - jiffies); if (t >= WAIT_MIN_SLEEP) { /* @@ -955,7 +911,7 @@ repeat: */ drive = best->next; do { - if (!drive->sleeping + if ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0 && time_before(jiffies - best->service_time, WAKEUP(drive)) && time_before(WAKEUP(drive), jiffies + t)) { @@ -1026,7 +982,9 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) hwgroup->rq = NULL; drive = hwgroup->drive; do { - if (drive->sleeping && (!sleeping || time_before(drive->sleep, sleep))) { + if ((drive->dev_flags & IDE_DFLAG_SLEEPING) && + (sleeping == 0 || + time_before(drive->sleep, sleep))) { sleeping = 1; sleep = drive->sleep; } @@ -1075,7 +1033,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) } hwgroup->hwif = hwif; hwgroup->drive = drive; - drive->sleeping = 0; + drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); drive->service_start = jiffies; if (blk_queue_plugged(drive->queue)) { @@ -1109,7 +1067,9 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) * We count how many times we loop here to make sure we service * all drives in the hwgroup without looping for ever */ - if (drive->blocked && !blk_pm_request(rq) && !(rq->cmd_flags & REQ_PREEMPT)) { + if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && + blk_pm_request(rq) == 0 && + (rq->cmd_flags & REQ_PREEMPT) == 0) { drive = drive->next ? drive->next : hwgroup->drive; if (loops++ < 4 && !blk_queue_plugged(drive->queue)) goto again; @@ -1182,8 +1142,8 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) * a timeout -- we'll reenable after we finish this next request * (or rather the first chunk of it) in pio. */ + drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY; drive->retry_pio++; - drive->state = DMA_PIO_RETRY; ide_dma_off_quietly(drive); /* @@ -1480,23 +1440,16 @@ irqreturn_t ide_intr (int irq, void *dev_id) del_timer(&hwgroup->timer); spin_unlock(&ide_lock); - /* Some controllers might set DMA INTR no matter DMA or PIO; - * bmdma status might need to be cleared even for - * PIO interrupts to prevent spurious/lost irq. - */ - if (hwif->ide_dma_clear_irq && !(drive->waiting_for_dma)) - /* ide_dma_end() needs bmdma status for error checking. - * So, skip clearing bmdma status here and leave it - * to ide_dma_end() if this is dma interrupt. - */ - hwif->ide_dma_clear_irq(drive); + if (hwif->port_ops && hwif->port_ops->clear_irq) + hwif->port_ops->clear_irq(drive); - if (drive->unmask) + if (drive->dev_flags & IDE_DFLAG_UNMASK) local_irq_enable_in_hardirq(); + /* service this interrupt, may set handler for next interrupt */ startstop = handler(drive); - spin_lock_irq(&ide_lock); + spin_lock_irq(&ide_lock); /* * Note that handler() may have set things up for another * interrupt to occur soon, but it cannot happen until @@ -1540,8 +1493,8 @@ void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq) spin_lock_irqsave(&ide_lock, flags); hwgroup->rq = NULL; - __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 1); - __generic_unplug_device(drive->queue); + __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); + blk_start_queueing(drive->queue); spin_unlock_irqrestore(&ide_lock, flags); } diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index cf01564901a..a90945f4979 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -62,7 +62,7 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd, int size = (cmd == HDIO_GET_IDENTITY) ? (ATA_ID_WORDS * 2) : 142; int rc = 0; - if (drive->id_read == 0) { + if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { rc = -ENOMSG; goto out; } @@ -86,8 +86,10 @@ out: static int ide_get_nice_ioctl(ide_drive_t *drive, unsigned long arg) { - return put_user((drive->dsc_overlap << IDE_NICE_DSC_OVERLAP) | - (drive->nice1 << IDE_NICE_1), (long __user *)arg); + return put_user((!!(drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) + << IDE_NICE_DSC_OVERLAP) | + (!!(drive->dev_flags & IDE_DFLAG_NICE1) + << IDE_NICE_1), (long __user *)arg); } static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) @@ -97,11 +99,18 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) if (((arg >> IDE_NICE_DSC_OVERLAP) & 1) && (drive->media == ide_disk || drive->media == ide_floppy || - drive->scsi)) + (drive->dev_flags & IDE_DFLAG_SCSI))) return -EPERM; - drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1; - drive->nice1 = (arg >> IDE_NICE_1) & 1; + if ((arg >> IDE_NICE_DSC_OVERLAP) & 1) + drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; + else + drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; + + if ((arg >> IDE_NICE_1) & 1) + drive->dev_flags |= IDE_DFLAG_NICE1; + else + drive->dev_flags &= ~IDE_DFLAG_NICE1; return 0; } diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 0a2fd3b37ac..bb7a1ed8094 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -181,7 +181,7 @@ void ide_tf_load(ide_drive_t *drive, ide_task_t *task) tf_outb(tf->lbah, io_ports->lbah_addr); if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) - tf_outb((tf->device & HIHI) | drive->select.all, + tf_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } EXPORT_SYMBOL_GPL(ide_tf_load); @@ -647,7 +647,7 @@ u8 eighty_ninty_three (ide_drive_t *drive) return 1; no_80w: - if (drive->udma33_warned == 1) + if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED) return 0; printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, " @@ -655,7 +655,7 @@ no_80w: drive->name, hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host"); - drive->udma33_warned = 1; + drive->dev_flags |= IDE_DFLAG_UDMA33_WARNED; return 0; } @@ -711,7 +711,7 @@ int ide_driveid_update(ide_drive_t *drive) kfree(id); - if (drive->using_dma && ide_id_dma_bug(drive)) + if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive)) ide_dma_off(drive); return 1; @@ -755,7 +755,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) udelay(1); SELECT_DRIVE(drive); - SELECT_MASK(drive, 0); + SELECT_MASK(drive, 1); udelay(1); tp_ops->set_irq(hwif, 0); @@ -790,7 +790,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) skip: #ifdef CONFIG_BLK_DEV_IDEDMA - if (speed >= XFER_SW_DMA_0 && drive->using_dma) + if (speed >= XFER_SW_DMA_0 && (drive->dev_flags & IDE_DFLAG_USING_DMA)) hwif->dma_ops->dma_host_set(drive, 1); else if (hwif->dma_ops) /* check if host supports DMA */ ide_dma_off_quietly(drive); @@ -940,6 +940,25 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) return ide_stopped; } +static void ide_reset_report_error(ide_hwif_t *hwif, u8 err) +{ + static const char *err_master_vals[] = + { NULL, "passed", "formatter device error", + "sector buffer error", "ECC circuitry error", + "controlling MPU error" }; + + u8 err_master = err & 0x7f; + + printk(KERN_ERR "%s: reset: master: ", hwif->name); + if (err_master && err_master < 6) + printk(KERN_CONT "%s", err_master_vals[err_master]); + else + printk(KERN_CONT "error (0x%02x?)", err); + if (err & 0x80) + printk(KERN_CONT "; slave: failed"); + printk(KERN_CONT "\n"); +} + /* * reset_pollfunc() gets invoked to poll the interface for completion every 50ms * during an ide reset operation. If the drives have not yet responded, @@ -975,31 +994,14 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) drive->failures++; err = -EIO; } else { - printk("%s: reset: ", hwif->name); tmp = ide_read_error(drive); if (tmp == 1) { - printk("success\n"); + printk(KERN_INFO "%s: reset: success\n", hwif->name); drive->failures = 0; } else { + ide_reset_report_error(hwif, tmp); drive->failures++; - printk("master: "); - switch (tmp & 0x7f) { - case 1: printk("passed"); - break; - case 2: printk("formatter device error"); - break; - case 3: printk("sector buffer error"); - break; - case 4: printk("ECC circuitry error"); - break; - case 5: printk("controlling MPU error"); - break; - default:printk("error (0x%02x?)", tmp); - } - if (tmp & 0x80) - printk("; slave: failed"); - printk("\n"); err = -EIO; } } @@ -1016,9 +1018,14 @@ static void ide_disk_pre_reset(ide_drive_t *drive) drive->special.all = 0; drive->special.b.set_geometry = legacy; drive->special.b.recalibrate = legacy; + drive->mult_count = 0; - if (!drive->keep_settings && !drive->using_dma) + drive->dev_flags &= ~IDE_DFLAG_PARKED; + + if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 && + (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) drive->mult_req = 0; + if (drive->mult_req != drive->mult_count) drive->special.b.set_multmode = 1; } @@ -1030,18 +1037,18 @@ static void pre_reset(ide_drive_t *drive) if (drive->media == ide_disk) ide_disk_pre_reset(drive); else - drive->post_reset = 1; + drive->dev_flags |= IDE_DFLAG_POST_RESET; - if (drive->using_dma) { + if (drive->dev_flags & IDE_DFLAG_USING_DMA) { if (drive->crc_count) ide_check_dma_crc(drive); else ide_dma_off(drive); } - if (!drive->keep_settings) { - if (!drive->using_dma) { - drive->unmask = 0; + if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) { + if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) { + drive->dev_flags &= ~IDE_DFLAG_UNMASK; drive->io_32bit = 0; } return; @@ -1073,12 +1080,13 @@ static void pre_reset(ide_drive_t *drive) static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) { unsigned int unit; - unsigned long flags; + unsigned long flags, timeout; ide_hwif_t *hwif; ide_hwgroup_t *hwgroup; struct ide_io_ports *io_ports; const struct ide_tp_ops *tp_ops; const struct ide_port_ops *port_ops; + DEFINE_WAIT(wait); spin_lock_irqsave(&ide_lock, flags); hwif = HWIF(drive); @@ -1105,6 +1113,31 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) return ide_started; } + /* We must not disturb devices in the IDE_DFLAG_PARKED state. */ + do { + unsigned long now; + + prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE); + timeout = jiffies; + for (unit = 0; unit < MAX_DRIVES; unit++) { + ide_drive_t *tdrive = &hwif->drives[unit]; + + if (tdrive->dev_flags & IDE_DFLAG_PRESENT && + tdrive->dev_flags & IDE_DFLAG_PARKED && + time_after(tdrive->sleep, timeout)) + timeout = tdrive->sleep; + } + + now = jiffies; + if (time_before_eq(timeout, now)) + break; + + spin_unlock_irqrestore(&ide_lock, flags); + timeout = schedule_timeout_uninterruptible(timeout - now); + spin_lock_irqsave(&ide_lock, flags); + } while (timeout); + finish_wait(&ide_park_wq, &wait); + /* * First, reset any device state data we were maintaining * for any of the drives on this interface. diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index ed426dd0fdd..9fc4cfb2a27 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -317,7 +317,7 @@ static void ide_dump_sector(ide_drive_t *drive) { ide_task_t task; struct ide_taskfile *tf = &task.tf; - int lba48 = (drive->addressing == 1) ? 1 : 0; + u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); memset(&task, 0, sizeof(task)); if (lba48) diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c new file mode 100644 index 00000000000..03b00e57e93 --- /dev/null +++ b/drivers/ide/ide-park.c @@ -0,0 +1,121 @@ +#include <linux/kernel.h> +#include <linux/ide.h> +#include <linux/jiffies.h> +#include <linux/blkdev.h> + +DECLARE_WAIT_QUEUE_HEAD(ide_park_wq); + +static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) +{ + struct request_queue *q = drive->queue; + struct request *rq; + int rc; + + timeout += jiffies; + spin_lock_irq(&ide_lock); + if (drive->dev_flags & IDE_DFLAG_PARKED) { + ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; + int reset_timer; + + reset_timer = time_before(timeout, drive->sleep); + drive->sleep = timeout; + wake_up_all(&ide_park_wq); + if (reset_timer && hwgroup->sleeping && + del_timer(&hwgroup->timer)) { + hwgroup->sleeping = 0; + hwgroup->busy = 0; + blk_start_queueing(q); + } + spin_unlock_irq(&ide_lock); + return; + } + spin_unlock_irq(&ide_lock); + + rq = blk_get_request(q, READ, __GFP_WAIT); + rq->cmd[0] = REQ_PARK_HEADS; + rq->cmd_len = 1; + rq->cmd_type = REQ_TYPE_SPECIAL; + rq->special = &timeout; + rc = blk_execute_rq(q, NULL, rq, 1); + blk_put_request(rq); + if (rc) + goto out; + + /* + * Make sure that *some* command is sent to the drive after the + * timeout has expired, so power management will be reenabled. + */ + rq = blk_get_request(q, READ, GFP_NOWAIT); + if (unlikely(!rq)) + goto out; + + rq->cmd[0] = REQ_UNPARK_HEADS; + rq->cmd_len = 1; + rq->cmd_type = REQ_TYPE_SPECIAL; + elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 1); + +out: + return; +} + +ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + ide_drive_t *drive = to_ide_device(dev); + unsigned long now; + unsigned int msecs; + + if (drive->dev_flags & IDE_DFLAG_NO_UNLOAD) + return -EOPNOTSUPP; + + spin_lock_irq(&ide_lock); + now = jiffies; + if (drive->dev_flags & IDE_DFLAG_PARKED && + time_after(drive->sleep, now)) + msecs = jiffies_to_msecs(drive->sleep - now); + else + msecs = 0; + spin_unlock_irq(&ide_lock); + + return snprintf(buf, 20, "%u\n", msecs); +} + +ssize_t ide_park_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) +{ +#define MAX_PARK_TIMEOUT 30000 + ide_drive_t *drive = to_ide_device(dev); + long int input; + int rc; + + rc = strict_strtol(buf, 10, &input); + if (rc || input < -2) + return -EINVAL; + if (input > MAX_PARK_TIMEOUT) { + input = MAX_PARK_TIMEOUT; + rc = -EOVERFLOW; + } + + mutex_lock(&ide_setting_mtx); + if (input >= 0) { + if (drive->dev_flags & IDE_DFLAG_NO_UNLOAD) + rc = -EOPNOTSUPP; + else if (input || drive->dev_flags & IDE_DFLAG_PARKED) + issue_park_cmd(drive, msecs_to_jiffies(input)); + } else { + if (drive->media == ide_disk) + switch (input) { + case -1: + drive->dev_flags &= ~IDE_DFLAG_NO_UNLOAD; + break; + case -2: + drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; + break; + } + else + rc = -EOPNOTSUPP; + } + mutex_unlock(&ide_setting_mtx); + + return rc ? rc : len; +} diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 06575a12b63..1649ea54f76 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -121,7 +121,8 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) /* read 512 bytes of id info */ hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); - drive->id_read = 1; + drive->dev_flags |= IDE_DFLAG_ID_READ; + local_irq_enable(); #ifdef DEBUG printk(KERN_INFO "%s: dumping identify data\n", drive->name); @@ -153,8 +154,8 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) printk(KERN_INFO "%s: %s, ", drive->name, m); - drive->present = 1; - drive->dead = 0; + drive->dev_flags |= IDE_DFLAG_PRESENT; + drive->dev_flags &= ~IDE_DFLAG_DEAD; /* * Check for an ATAPI device @@ -172,14 +173,14 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) printk(KERN_CONT "cdrom or floppy?, assuming "); if (drive->media != ide_cdrom) { printk(KERN_CONT "FLOPPY"); - drive->removable = 1; + drive->dev_flags |= IDE_DFLAG_REMOVABLE; break; } } /* Early cdrom models used zero */ type = ide_cdrom; case ide_cdrom: - drive->removable = 1; + drive->dev_flags |= IDE_DFLAG_REMOVABLE; #ifdef CONFIG_PPC /* kludge for Apple PowerBook internal zip */ if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) { @@ -195,7 +196,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) break; case ide_optical: printk(KERN_CONT "OPTICAL"); - drive->removable = 1; + drive->dev_flags |= IDE_DFLAG_REMOVABLE; break; default: printk(KERN_CONT "UNKNOWN (type %d)", type); @@ -205,6 +206,11 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) drive->media = type; /* an ATAPI device ignores DRDY */ drive->ready_stat = 0; + if (ata_id_cdb_intr(id)) + drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; + drive->dev_flags |= IDE_DFLAG_DOORLOCKING; + /* we don't do head unloading on ATAPI devices */ + drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; return; } @@ -216,17 +222,20 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) /* CF devices are *not* removable in Linux definition of the term */ if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7))) - drive->removable = 1; + drive->dev_flags |= IDE_DFLAG_REMOVABLE; drive->media = ide_disk; + if (!ata_id_has_unload(drive->id)) + drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; + printk(KERN_CONT "%s DISK drive\n", is_cfa ? "CFA" : "ATA"); return; err_misc: kfree(id); - drive->present = 0; + drive->dev_flags &= ~IDE_DFLAG_PRESENT; return; } @@ -426,16 +435,15 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ide_hwif_t *hwif = HWIF(drive); const struct ide_tp_ops *tp_ops = hwif->tp_ops; int rc; - u8 stat; + u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat; + + /* avoid waiting for inappropriate probes */ + if (present && drive->media != ide_disk && cmd == ATA_CMD_ID_ATA) + return 4; - if (drive->present) { - /* avoid waiting for inappropriate probes */ - if (drive->media != ide_disk && cmd == ATA_CMD_ID_ATA) - return 4; - } #ifdef DEBUG printk(KERN_INFO "probing for %s: present=%d, media=%d, probetype=%s\n", - drive->name, drive->present, drive->media, + drive->name, present, drive->media, (cmd == ATA_CMD_ID_ATA) ? "ATA" : "ATAPI"); #endif @@ -446,8 +454,8 @@ static int do_probe (ide_drive_t *drive, u8 cmd) SELECT_DRIVE(drive); msleep(50); - if (ide_read_device(drive) != drive->select.all && !drive->present) { - if (drive->select.b.unit != 0) { + if (ide_read_device(drive) != drive->select && present == 0) { + if (drive->dn & 1) { /* exit with drive0 selected */ SELECT_DRIVE(&hwif->drives[0]); /* allow ATA_BUSY to assert & clear */ @@ -460,7 +468,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) stat = tp_ops->read_status(hwif); if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) || - drive->present || cmd == ATA_CMD_ID_ATAPI) { + present || cmd == ATA_CMD_ID_ATAPI) { /* send cmd and wait */ if ((rc = try_to_identify(drive, cmd))) { /* failed: try again */ @@ -493,7 +501,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) /* not present or maybe ATAPI */ rc = 3; } - if (drive->select.b.unit != 0) { + if (drive->dn & 1) { /* exit with drive0 selected */ SELECT_DRIVE(&hwif->drives[0]); msleep(50); @@ -542,8 +550,8 @@ static void enable_nest (ide_drive_t *drive) * and presents things to the user as needed. * * Returns: 0 no device was found - * 1 device was found (note: drive->present might - * still be 0) + * 1 device was found + * (note: IDE_DFLAG_PRESENT might still be not set) */ static inline u8 probe_for_drive (ide_drive_t *drive) @@ -559,10 +567,10 @@ static inline u8 probe_for_drive (ide_drive_t *drive) * Also note that 0 everywhere means "can't do X" */ + drive->dev_flags &= ~IDE_DFLAG_ID_READ; + drive->id = kzalloc(SECTOR_SIZE, GFP_KERNEL); - drive->id_read = 0; - if(drive->id == NULL) - { + if (drive->id == NULL) { printk(KERN_ERR "ide: out of memory for id data.\n"); return 0; } @@ -571,14 +579,14 @@ static inline u8 probe_for_drive (ide_drive_t *drive) strcpy(m, "UNKNOWN"); /* skip probing? */ - if (!drive->noprobe) { + if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) { retry: /* if !(success||timed-out) */ if (do_probe(drive, ATA_CMD_ID_ATA) >= 2) /* look for ATAPI device */ (void)do_probe(drive, ATA_CMD_ID_ATAPI); - if (!drive->present) + if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) /* drive not found */ return 0; @@ -588,7 +596,7 @@ retry: } /* identification failed? */ - if (!drive->id_read) { + if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { if (drive->media == ide_disk) { printk(KERN_INFO "%s: non-IDE drive, CHS=%d/%d/%d\n", drive->name, drive->cyl, @@ -598,15 +606,17 @@ retry: } else { /* nuke it */ printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name); - drive->present = 0; + drive->dev_flags &= ~IDE_DFLAG_PRESENT; } } /* drive was found */ } - if(!drive->present) + + if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) return 0; + /* The drive wasn't being helpful. Add generic info only */ - if (drive->id_read == 0) { + if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { generic_id(drive); return 1; } @@ -616,7 +626,7 @@ retry: ide_disk_init_mult_count(drive); } - return drive->present; + return !!(drive->dev_flags & IDE_DFLAG_PRESENT); } static void hwif_release_dev(struct device *dev) @@ -648,8 +658,8 @@ static int ide_register_port(ide_hwif_t *hwif) goto out; } - hwif->portdev = device_create_drvdata(ide_port_class, &hwif->gendev, - MKDEV(0, 0), hwif, hwif->name); + hwif->portdev = device_create(ide_port_class, &hwif->gendev, + MKDEV(0, 0), hwif, hwif->name); if (IS_ERR(hwif->portdev)) { ret = PTR_ERR(hwif->portdev); device_unregister(&hwif->gendev); @@ -707,7 +717,8 @@ static int ide_port_wait_ready(ide_hwif_t *hwif) ide_drive_t *drive = &hwif->drives[unit]; /* Ignore disks that we will not probe for later. */ - if (!drive->noprobe || drive->present) { + if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 || + (drive->dev_flags & IDE_DFLAG_PRESENT)) { SELECT_DRIVE(drive); hwif->tp_ops->set_irq(hwif, 1); mdelay(2); @@ -739,7 +750,7 @@ void ide_undecoded_slave(ide_drive_t *dev1) { ide_drive_t *dev0 = &dev1->hwif->drives[0]; - if ((dev1->dn & 1) == 0 || dev0->present == 0) + if ((dev1->dn & 1) == 0 || (dev0->dev_flags & IDE_DFLAG_PRESENT) == 0) return; /* If the models don't match they are not the same product */ @@ -759,7 +770,7 @@ void ide_undecoded_slave(ide_drive_t *dev1) /* Appears to be an IDE flash adapter with decode bugs */ printk(KERN_WARNING "ide-probe: ignoring undecoded slave\n"); - dev1->present = 0; + dev1->dev_flags &= ~IDE_DFLAG_PRESENT; } EXPORT_SYMBOL_GPL(ide_undecoded_slave); @@ -772,7 +783,8 @@ static int ide_probe_port(ide_hwif_t *hwif) BUG_ON(hwif->present); - if (hwif->drives[0].noprobe && hwif->drives[1].noprobe) + if ((hwif->drives[0].dev_flags & IDE_DFLAG_NOPROBE) && + (hwif->drives[1].dev_flags & IDE_DFLAG_NOPROBE)) return -EACCES; /* @@ -794,9 +806,9 @@ static int ide_probe_port(ide_hwif_t *hwif) */ for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; - drive->dn = (hwif->channel ? 2 : 0) + unit; + (void) probe_for_drive(drive); - if (drive->present) + if (drive->dev_flags & IDE_DFLAG_PRESENT) rc = 0; } @@ -820,17 +832,19 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) for (unit = 0; unit < MAX_DRIVES; unit++) { ide_drive_t *drive = &hwif->drives[unit]; - if (drive->present && port_ops && port_ops->quirkproc) - port_ops->quirkproc(drive); + if (drive->dev_flags & IDE_DFLAG_PRESENT) { + if (port_ops && port_ops->quirkproc) + port_ops->quirkproc(drive); + } } for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; - if (drive->present) { + if (drive->dev_flags & IDE_DFLAG_PRESENT) { ide_set_max_pio(drive); - drive->nice1 = 1; + drive->dev_flags |= IDE_DFLAG_NICE1; if (hwif->dma_ops) ide_set_dma(drive); @@ -840,14 +854,14 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; - if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) - drive->no_io_32bit = 1; + if ((hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) || + drive->id[ATA_ID_DWORD_IO]) + drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT; else - drive->no_io_32bit = drive->id[ATA_ID_DWORD_IO] ? 1 : 0; + drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT; } } -#if MAX_HWIFS > 1 /* * save_match() is used to simplify logic in init_irq() below. * @@ -872,7 +886,6 @@ static void save_match(ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match) if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */ *match = new; } -#endif /* MAX_HWIFS > 1 */ /* * init request queue @@ -951,26 +964,33 @@ static void ide_add_drive_to_hwgroup(ide_drive_t *drive) * - allocate the block device queue * - link drive into the hwgroup */ -static void ide_port_setup_devices(ide_hwif_t *hwif) +static int ide_port_setup_devices(ide_hwif_t *hwif) { - int i; + int i, j = 0; mutex_lock(&ide_cfg_mtx); for (i = 0; i < MAX_DRIVES; i++) { ide_drive_t *drive = &hwif->drives[i]; - if (!drive->present) + if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) continue; if (ide_init_queue(drive)) { printk(KERN_ERR "ide: failed to init %s\n", drive->name); + kfree(drive->id); + drive->id = NULL; + drive->dev_flags &= ~IDE_DFLAG_PRESENT; continue; } + j++; + ide_add_drive_to_hwgroup(drive); } mutex_unlock(&ide_cfg_mtx); + + return j; } static ide_hwif_t *ide_ports[MAX_HWIFS]; @@ -1029,7 +1049,7 @@ static int init_irq (ide_hwif_t *hwif) mutex_lock(&ide_cfg_mtx); hwif->hwgroup = NULL; -#if MAX_HWIFS > 1 + /* * Group up with any other hwifs that share our irq(s). */ @@ -1054,7 +1074,7 @@ static int init_irq (ide_hwif_t *hwif) } } } -#endif /* MAX_HWIFS > 1 */ + /* * If we are still without a hwgroup, then form a new one */ @@ -1153,12 +1173,13 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data) ide_hwif_t *hwif = data; int unit = *part >> PARTN_BITS; ide_drive_t *drive = &hwif->drives[unit]; - if (!drive->present) + + if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) return NULL; if (drive->media == ide_disk) request_module("ide-disk"); - if (drive->scsi) + if (drive->dev_flags & IDE_DFLAG_SCSI) request_module("ide-scsi"); if (drive->media == ide_cdrom || drive->media == ide_optical) request_module("ide-cd"); @@ -1205,7 +1226,7 @@ EXPORT_SYMBOL_GPL(ide_unregister_region); void ide_init_disk(struct gendisk *disk, ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - unsigned int unit = (drive->select.all >> 4) & 1; + unsigned int unit = drive->dn & 1; disk->major = hwif->major; disk->first_minor = unit << PARTN_BITS; @@ -1248,7 +1269,7 @@ static void drive_release_dev (struct device *dev) ide_remove_drive_from_hwgroup(drive); kfree(drive->id); drive->id = NULL; - drive->present = 0; + drive->dev_flags &= ~IDE_DFLAG_PRESENT; /* Messed up locking ... */ spin_unlock_irq(&ide_lock); blk_cleanup_queue(drive->queue); @@ -1327,7 +1348,7 @@ static void hwif_register_devices(ide_hwif_t *hwif) struct device *dev = &drive->gendev; int ret; - if (!drive->present) + if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) continue; snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i); @@ -1351,12 +1372,14 @@ static void ide_port_init_devices(ide_hwif_t *hwif) for (i = 0; i < MAX_DRIVES; i++) { ide_drive_t *drive = &hwif->drives[i]; + drive->dn = i + hwif->channel * 2; + if (hwif->host_flags & IDE_HFLAG_IO_32BIT) drive->io_32bit = 1; if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS) - drive->unmask = 1; + drive->dev_flags |= IDE_DFLAG_UNMASK; if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS) - drive->no_unmask = 1; + drive->dev_flags |= IDE_DFLAG_NO_UNMASK; if (port_ops && port_ops->init_dev) port_ops->init_dev(drive); @@ -1513,19 +1536,14 @@ static int ide_find_port_slot(const struct ide_port_info *d) * ports 0x1f0/0x170 (the ide0/ide1 defaults). */ mutex_lock(&ide_cfg_mtx); - if (MAX_HWIFS == 1) { - if (ide_indexes == 0 && i == 0) - idx = 1; + if (bootable) { + if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1) + idx = ffz(ide_indexes | i); } else { - if (bootable) { - if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1) - idx = ffz(ide_indexes | i); - } else { - if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1) - idx = ffz(ide_indexes | 3); - else if ((ide_indexes & 3) != 3) - idx = ffz(ide_indexes); - } + if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1) + idx = ffz(ide_indexes | 3); + else if ((ide_indexes & 3) != 3) + idx = ffz(ide_indexes); } if (idx >= 0) ide_indexes |= (1 << idx); @@ -1541,8 +1559,7 @@ static void ide_free_port_slot(int idx) mutex_unlock(&ide_cfg_mtx); } -struct ide_host *ide_host_alloc_all(const struct ide_port_info *d, - hw_regs_t **hws) +struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) { struct ide_host *host; int i; @@ -1551,7 +1568,7 @@ struct ide_host *ide_host_alloc_all(const struct ide_port_info *d, if (host == NULL) return NULL; - for (i = 0; i < MAX_HWIFS; i++) { + for (i = 0; i < MAX_HOST_PORTS; i++) { ide_hwif_t *hwif; int idx; @@ -1593,18 +1610,6 @@ struct ide_host *ide_host_alloc_all(const struct ide_port_info *d, return host; } -EXPORT_SYMBOL_GPL(ide_host_alloc_all); - -struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) -{ - hw_regs_t *hws_all[MAX_HWIFS]; - int i; - - for (i = 0; i < MAX_HWIFS; i++) - hws_all[i] = (i < 4) ? hws[i] : NULL; - - return ide_host_alloc_all(d, hws_all); -} EXPORT_SYMBOL_GPL(ide_host_alloc); int ide_host_register(struct ide_host *host, const struct ide_port_info *d, @@ -1613,7 +1618,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, ide_hwif_t *hwif, *mate = NULL; int i, j = 0; - for (i = 0; i < MAX_HWIFS; i++) { + for (i = 0; i < MAX_HOST_PORTS; i++) { hwif = host->ports[i]; if (hwif == NULL) { @@ -1626,22 +1631,22 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, if (d == NULL) { mate = NULL; - continue; - } + } else { + if ((i & 1) && mate) { + hwif->mate = mate; + mate->mate = hwif; + } - if ((i & 1) && mate) { - hwif->mate = mate; - mate->mate = hwif; - } + mate = (i & 1) ? NULL : hwif; - mate = (i & 1) ? NULL : hwif; + ide_init_port(hwif, i & 1, d); + ide_port_cable_detect(hwif); + } - ide_init_port(hwif, i & 1, d); - ide_port_cable_detect(hwif); ide_port_init_devices(hwif); } - for (i = 0; i < MAX_HWIFS; i++) { + for (i = 0; i < MAX_HOST_PORTS; i++) { hwif = host->ports[i]; if (hwif == NULL) @@ -1658,7 +1663,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, ide_port_tune_devices(hwif); } - for (i = 0; i < MAX_HWIFS; i++) { + for (i = 0; i < MAX_HOST_PORTS; i++) { hwif = host->ports[i]; if (hwif == NULL) @@ -1671,10 +1676,13 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, continue; } - j++; - if (hwif->present) - ide_port_setup_devices(hwif); + if (ide_port_setup_devices(hwif) == 0) { + hwif->present = 0; + continue; + } + + j++; ide_acpi_init(hwif); @@ -1682,7 +1690,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, ide_acpi_port_init_devices(hwif); } - for (i = 0; i < MAX_HWIFS; i++) { + for (i = 0; i < MAX_HOST_PORTS; i++) { hwif = host->ports[i]; if (hwif == NULL) @@ -1695,7 +1703,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, hwif_register_devices(hwif); } - for (i = 0; i < MAX_HWIFS; i++) { + for (i = 0; i < MAX_HOST_PORTS; i++) { hwif = host->ports[i]; if (hwif == NULL) @@ -1740,7 +1748,7 @@ void ide_host_free(struct ide_host *host) ide_hwif_t *hwif; int i; - for (i = 0; i < MAX_HWIFS; i++) { + for (i = 0; i < MAX_HOST_PORTS; i++) { hwif = host->ports[i]; if (hwif == NULL) @@ -1758,7 +1766,7 @@ void ide_host_remove(struct ide_host *host) { int i; - for (i = 0; i < MAX_HWIFS; i++) { + for (i = 0; i < MAX_HOST_PORTS; i++) { if (host->ports[i]) ide_unregister(host->ports[i]); } diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index e7030a49146..c31d0dd7a53 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -227,7 +227,7 @@ static int set_xfer_rate (ide_drive_t *drive, int arg) ide_devset_rw(current_speed, xfer_rate); ide_devset_rw_field(init_speed, init_speed); -ide_devset_rw_field(nice1, nice1); +ide_devset_rw_flag(nice1, IDE_DFLAG_NICE1); ide_devset_rw_field(number, dn); static const struct ide_proc_devset ide_generic_settings[] = { @@ -567,10 +567,10 @@ static void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) { mutex_lock(&ide_setting_mtx); - drive->settings = driver->settings; + drive->settings = driver->proc_devsets(drive); mutex_unlock(&ide_setting_mtx); - ide_add_proc_entries(drive->proc, driver->proc, drive); + ide_add_proc_entries(drive->proc, driver->proc_entries(drive), drive); } EXPORT_SYMBOL(ide_proc_register_driver); @@ -591,7 +591,7 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) { unsigned long flags; - ide_remove_proc_entries(drive->proc, driver->proc); + ide_remove_proc_entries(drive->proc, driver->proc_entries(drive)); mutex_lock(&ide_setting_mtx); spin_lock_irqsave(&ide_lock, flags); @@ -622,9 +622,7 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif) for (d = 0; d < MAX_DRIVES; d++) { ide_drive_t *drive = &hwif->drives[d]; - if (!drive->present) - continue; - if (drive->proc) + if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc) continue; drive->proc = proc_mkdir(drive->name, parent); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index f8c84df4a0b..b2b2e5e8d38 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -172,23 +172,16 @@ typedef struct ide_tape_obj { struct kref kref; /* - * pc points to the current processed packet command. - * * failed_pc points to the last failed packet command, or contains * NULL if we do not need to retry any packet command. This is * required since an additional packet command is needed before the * retry, to get detailed information on what went wrong. */ - /* Current packet command */ - struct ide_atapi_pc *pc; /* Last failed packet command */ struct ide_atapi_pc *failed_pc; /* used by REQ_IDETAPE_{READ,WRITE} requests */ struct ide_atapi_pc queued_pc; - struct ide_atapi_pc request_sense_pc; - struct request request_sense_rq; - /* * DSC polling variables. * @@ -274,11 +267,6 @@ static DEFINE_MUTEX(idetape_ref_mutex); static struct class *idetape_sysfs_class; -#define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref) - -#define ide_tape_g(disk) \ - container_of((disk)->private_data, struct ide_tape_obj, driver) - static void ide_tape_release(struct kref *); static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) @@ -286,7 +274,7 @@ static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) struct ide_tape_obj *tape = NULL; mutex_lock(&idetape_ref_mutex); - tape = ide_tape_g(disk); + tape = ide_drv_g(disk, ide_tape_obj); if (tape) { if (ide_device_get(tape->drive)) tape = NULL; @@ -313,8 +301,6 @@ static void ide_tape_put(struct ide_tape_obj *tape) */ static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES]; -#define ide_tape_f(file) ((file)->private_data) - static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) { struct ide_tape_obj *tape = NULL; @@ -522,14 +508,19 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) return 0; } -static void ide_tape_callback(ide_drive_t *drive) +static void ide_tape_handle_dsc(ide_drive_t *); + +static void ide_tape_callback(ide_drive_t *drive, int dsc) { idetape_tape_t *tape = drive->driver_data; - struct ide_atapi_pc *pc = tape->pc; + struct ide_atapi_pc *pc = drive->pc; int uptodate = pc->error ? 0 : 1; debug_log(DBG_PROCS, "Enter %s\n", __func__); + if (dsc) + ide_tape_handle_dsc(drive); + if (tape->failed_pc == pc) tape->failed_pc = NULL; @@ -558,7 +549,7 @@ static void ide_tape_callback(ide_drive_t *drive) if (pc->error) uptodate = pc->error; } else if (pc->c[0] == READ_POSITION && uptodate) { - u8 *readpos = tape->pc->buf; + u8 *readpos = pc->buf; debug_log(DBG_SENSE, "BOP - %s\n", (readpos[0] & 0x80) ? "Yes" : "No"); @@ -583,31 +574,6 @@ static void ide_tape_callback(ide_drive_t *drive) idetape_end_request(drive, uptodate, 0); } -static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc) -{ - ide_init_pc(pc); - pc->c[0] = REQUEST_SENSE; - pc->c[4] = 20; - pc->req_xfer = 20; -} - -/* - * idetape_retry_pc is called when an error was detected during the - * last packet command. We queue a request sense packet command in - * the head of the request list. - */ -static void idetape_retry_pc(ide_drive_t *drive) -{ - struct ide_tape_obj *tape = drive->driver_data; - struct request *rq = &tape->request_sense_rq; - struct ide_atapi_pc *pc = &tape->request_sense_pc; - - (void)ide_read_error(drive); - idetape_create_request_sense_cmd(pc); - set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - ide_queue_pc_head(drive, tape->disk, pc, rq); -} - /* * Postpone the current request so that ide.c will be able to service requests * from another device on the same hwgroup while we are polling for DSC. @@ -646,34 +612,18 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, } /* - * This is the usual interrupt handler which will be called during a packet - * command. We will transfer some of the data (as requested by the drive) and - * will re-point interrupt handler to us. When data transfer is finished, we - * will act according to the algorithm described before - * idetape_issue_pc. - */ -static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) -{ - idetape_tape_t *tape = drive->driver_data; - - return ide_pc_intr(drive, tape->pc, idetape_pc_intr, WAIT_TAPE_CMD, - NULL, idetape_update_buffers, idetape_retry_pc, - ide_tape_handle_dsc, ide_tape_io_buffers); -} - -/* * Packet Command Interface * - * The current Packet Command is available in tape->pc, and will not change + * The current Packet Command is available in drive->pc, and will not change * until we finish handling it. Each packet command is associated with a * callback function that will be called when the command is finished. * * The handling will be done in three stages: * * 1. idetape_issue_pc will send the packet command to the drive, and will set - * the interrupt handler to idetape_pc_intr. + * the interrupt handler to ide_pc_intr. * - * 2. On each interrupt, idetape_pc_intr will be called. This step will be + * 2. On each interrupt, ide_pc_intr will be called. This step will be * repeated until the device signals us that no more interrupts will be issued. * * 3. ATAPI Tape media access commands have immediate status with a delayed @@ -697,20 +647,13 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) * again, the callback function will be called and then we will handle the next * request. */ -static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) -{ - idetape_tape_t *tape = drive->driver_data; - - return ide_transfer_pc(drive, tape->pc, idetape_pc_intr, - WAIT_TAPE_CMD, NULL); -} static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc) { idetape_tape_t *tape = drive->driver_data; - if (tape->pc->c[0] == REQUEST_SENSE && + if (drive->pc->c[0] == REQUEST_SENSE && pc->c[0] == REQUEST_SENSE) { printk(KERN_ERR "ide-tape: possible ide-tape.c bug - " "Two request sense in serial were issued\n"); @@ -718,8 +661,9 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) tape->failed_pc = pc; + /* Set the current packet command */ - tape->pc = pc; + drive->pc = pc; if (pc->retries > IDETAPE_MAX_PC_RETRIES || (pc->flags & PC_FLAG_ABORT)) { @@ -743,15 +687,14 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, pc->error = IDETAPE_ERROR_GENERAL; } tape->failed_pc = NULL; - drive->pc_callback(drive); + drive->pc_callback(drive, 0); return ide_stopped; } debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); pc->retries++; - return ide_issue_pc(drive, pc, idetape_transfer_pc, - WAIT_TAPE_CMD, NULL); + return ide_issue_pc(drive, WAIT_TAPE_CMD, NULL); } /* A mode sense command is used to "sense" tape parameters. */ @@ -785,7 +728,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; idetape_tape_t *tape = drive->driver_data; - struct ide_atapi_pc *pc = tape->pc; + struct ide_atapi_pc *pc = drive->pc; u8 stat; stat = hwif->tp_ops->read_status(hwif); @@ -797,7 +740,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) printk(KERN_ERR "ide-tape: %s: I/O error, ", tape->name); /* Retry operation */ - idetape_retry_pc(drive); + ide_retry_pc(drive, tape->disk); return ide_stopped; } pc->error = 0; @@ -805,7 +748,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) pc->error = IDETAPE_ERROR_GENERAL; tape->failed_pc = NULL; } - drive->pc_callback(drive); + drive->pc_callback(drive, 0); return ide_stopped; } @@ -862,7 +805,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, } /* Retry a failed packet command */ - if (tape->failed_pc && tape->pc->c[0] == REQUEST_SENSE) { + if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { pc = tape->failed_pc; goto out; } @@ -883,12 +826,13 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, */ stat = hwif->tp_ops->read_status(hwif); - if (!drive->dsc_overlap && !(rq->cmd[13] & REQ_IDETAPE_PC2)) + if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 && + (rq->cmd[13] & REQ_IDETAPE_PC2) == 0) set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - if (drive->post_reset == 1) { + if (drive->dev_flags & IDE_DFLAG_POST_RESET) { set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - drive->post_reset = 0; + drive->dev_flags &= ~IDE_DFLAG_POST_RESET; } if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) && @@ -1411,7 +1355,7 @@ static int idetape_init_read(ide_drive_t *drive) * No point in issuing this if DSC overlap isn't supported, some * drives (Seagate STT3401A) will return an error. */ - if (drive->dsc_overlap) { + if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { bytes_read = idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, 0, tape->merge_bh); @@ -1592,7 +1536,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct ide_tape_obj *tape = ide_tape_f(file); + struct ide_tape_obj *tape = file->private_data; ide_drive_t *drive = tape->drive; ssize_t bytes_read, temp, actually_read = 0, rc; ssize_t ret = 0; @@ -1654,7 +1598,7 @@ finish: static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - struct ide_tape_obj *tape = ide_tape_f(file); + struct ide_tape_obj *tape = file->private_data; ide_drive_t *drive = tape->drive; ssize_t actually_written = 0; ssize_t ret = 0; @@ -1687,7 +1631,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, * point in issuing this if DSC overlap isn't supported, some * drives (Seagate STT3401A) will return an error. */ - if (drive->dsc_overlap) { + if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { ssize_t retval = idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 0, tape->merge_bh); @@ -1886,7 +1830,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct ide_tape_obj *tape = ide_tape_f(file); + struct ide_tape_obj *tape = file->private_data; ide_drive_t *drive = tape->drive; struct mtop mtop; struct mtget mtget; @@ -2063,7 +2007,7 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor) static int idetape_chrdev_release(struct inode *inode, struct file *filp) { - struct ide_tape_obj *tape = ide_tape_f(filp); + struct ide_tape_obj *tape = filp->private_data; ide_drive_t *drive = tape->drive; unsigned int minor = iminor(inode); @@ -2164,7 +2108,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive) /* device lacks locking support according to capabilities page */ if ((caps[6] & 1) == 0) - drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; + drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; if (caps[7] & 0x02) tape->blk_size = 512; @@ -2202,7 +2146,7 @@ static int divf_tdsc(ide_drive_t *drive) { return HZ; } static int divf_buffer(ide_drive_t *drive) { return 2; } static int divf_buffer_size(ide_drive_t *drive) { return 1024; } -ide_devset_rw_field(dsc_overlap, dsc_overlap); +ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP); ide_tape_devset_rw_field(debug_mask, debug_mask); ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq); @@ -2241,33 +2185,32 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) unsigned long t; int speed; int buffer_size; - u8 gcw[2]; u16 *ctl = (u16 *)&tape->caps[12]; - drive->pc_callback = ide_tape_callback; + drive->pc_callback = ide_tape_callback; + drive->pc_update_buffers = idetape_update_buffers; + drive->pc_io_buffers = ide_tape_io_buffers; spin_lock_init(&tape->lock); - drive->dsc_overlap = 1; + + drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; + if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { printk(KERN_INFO "ide-tape: %s: disabling DSC overlap\n", tape->name); - drive->dsc_overlap = 0; + drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; } + /* Seagate Travan drives do not support DSC overlap. */ if (strstr((char *)&drive->id[ATA_ID_PROD], "Seagate STT3401")) - drive->dsc_overlap = 0; + drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; + tape->minor = minor; tape->name[0] = 'h'; tape->name[1] = 't'; tape->name[2] = '0' + minor; tape->chrdev_dir = IDETAPE_DIR_NONE; - *((u16 *)&gcw) = drive->id[ATA_ID_CONFIG]; - - /* Command packet DRQ type */ - if (((gcw[0] & 0x60) >> 5) == 1) - set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags); - idetape_get_inquiry_results(drive); idetape_get_mode_sense_results(drive); ide_tape_get_bsize_from_bdesc(drive); @@ -2302,7 +2245,7 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) (*(u16 *)&tape->caps[16] * 512) / tape->buffer_size, tape->buffer_size / 1024, tape->best_dsc_rw_freq * 1000 / HZ, - drive->using_dma ? ", DMA":""); + (drive->dev_flags & IDE_DFLAG_USING_DMA) ? ", DMA" : ""); ide_proc_register_driver(drive, tape->driver); } @@ -2320,13 +2263,13 @@ static void ide_tape_remove(ide_drive_t *drive) static void ide_tape_release(struct kref *kref) { - struct ide_tape_obj *tape = to_ide_tape(kref); + struct ide_tape_obj *tape = to_ide_drv(kref, ide_tape_obj); ide_drive_t *drive = tape->drive; struct gendisk *g = tape->disk; BUG_ON(tape->merge_bh_size); - drive->dsc_overlap = 0; + drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; drive->driver_data = NULL; device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor)); device_destroy(idetape_sysfs_class, @@ -2355,6 +2298,16 @@ static ide_proc_entry_t idetape_proc[] = { { "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL }, { NULL, 0, NULL, NULL } }; + +static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive) +{ + return idetape_proc; +} + +static const struct ide_proc_devset *ide_tape_proc_devsets(ide_drive_t *drive) +{ + return idetape_settings; +} #endif static int ide_tape_probe(ide_drive_t *); @@ -2368,13 +2321,12 @@ static ide_driver_t idetape_driver = { .probe = ide_tape_probe, .remove = ide_tape_remove, .version = IDETAPE_VERSION, - .media = ide_tape, .do_request = idetape_do_request, .end_request = idetape_end_request, .error = __ide_error, #ifdef CONFIG_IDE_PROC_FS - .proc = idetape_proc, - .settings = idetape_settings, + .proc_entries = ide_tape_proc_entries, + .proc_devsets = ide_tape_proc_devsets, #endif }; @@ -2403,7 +2355,7 @@ static int idetape_open(struct inode *inode, struct file *filp) static int idetape_release(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_tape_obj *tape = ide_tape_g(disk); + struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj); ide_tape_put(tape); @@ -2414,7 +2366,7 @@ static int idetape_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct block_device *bdev = inode->i_bdev; - struct ide_tape_obj *tape = ide_tape_g(bdev->bd_disk); + struct ide_tape_obj *tape = ide_drv_g(bdev->bd_disk, ide_tape_obj); ide_drive_t *drive = tape->drive; int err = generic_ide_ioctl(drive, file, bdev, cmd, arg); if (err == -EINVAL) @@ -2441,7 +2393,8 @@ static int ide_tape_probe(ide_drive_t *drive) if (drive->media != ide_tape) goto failed; - if (drive->id_read == 1 && !ide_check_atapi_device(drive, DRV_NAME)) { + if ((drive->dev_flags & IDE_DFLAG_ID_READ) && + ide_check_atapi_device(drive, DRV_NAME) == 0) { printk(KERN_ERR "ide-tape: %s: not supported by this version of" " the driver\n", drive->name); goto failed; @@ -2477,12 +2430,11 @@ static int ide_tape_probe(ide_drive_t *drive) idetape_setup(drive, tape, minor); - device_create_drvdata(idetape_sysfs_class, &drive->gendev, - MKDEV(IDETAPE_MAJOR, minor), NULL, - "%s", tape->name); - device_create_drvdata(idetape_sysfs_class, &drive->gendev, - MKDEV(IDETAPE_MAJOR, minor + 128), NULL, - "n%s", tape->name); + device_create(idetape_sysfs_class, &drive->gendev, + MKDEV(IDETAPE_MAJOR, minor), NULL, "%s", tape->name); + device_create(idetape_sysfs_class, &drive->gendev, + MKDEV(IDETAPE_MAJOR, minor + 128), NULL, + "n%s", tape->name); g->fops = &idetape_block_ops; ide_register_region(g); diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 487b18b3eba..bf4fb9d8d17 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -53,9 +53,6 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) } static ide_startstop_t task_no_data_intr(ide_drive_t *); -static ide_startstop_t set_geometry_intr(ide_drive_t *); -static ide_startstop_t recal_intr(ide_drive_t *); -static ide_startstop_t set_multmode_intr(ide_drive_t *); static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); static ide_startstop_t task_in_intr(ide_drive_t *); @@ -79,6 +76,8 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) if (task->tf_flags & IDE_TFLAG_FLAGGED) task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS; + memcpy(&hwif->task, task, sizeof(*task)); + if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { ide_tf_dump(drive->name, tf); tp_ops->set_irq(hwif, 1); @@ -99,24 +98,12 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) case TASKFILE_NO_DATA: if (handler == NULL) handler = task_no_data_intr; - if (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) { - switch (tf->command) { - case ATA_CMD_INIT_DEV_PARAMS: - handler = set_geometry_intr; - break; - case ATA_CMD_RESTORE: - handler = recal_intr; - break; - case ATA_CMD_SET_MULTI: - handler = set_multmode_intr; - break; - } - } ide_execute_command(drive, tf->command, handler, WAIT_WORSTCASE, NULL); return ide_started; default: - if (drive->using_dma == 0 || dma_ops->dma_setup(drive)) + if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 || + dma_ops->dma_setup(drive)) return ide_stopped; dma_ops->dma_exec_cmd(drive, tf->command); dma_ops->dma_start(drive); @@ -126,33 +113,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) EXPORT_SYMBOL_GPL(do_rw_taskfile); /* - * set_multmode_intr() is invoked on completion of a ATA_CMD_SET_MULTI cmd. - */ -static ide_startstop_t set_multmode_intr(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 stat; - - local_irq_enable_in_hardirq(); - stat = hwif->tp_ops->read_status(hwif); - - if (OK_STAT(stat, ATA_DRDY, BAD_STAT)) - drive->mult_count = drive->mult_req; - else { - drive->mult_req = drive->mult_count = 0; - drive->special.b.recalibrate = 1; - (void) ide_dump_status(drive, "set_multmode", stat); - } - return ide_stopped; -} - -/* - * set_geometry_intr() is invoked on completion of a ATA_CMD_INIT_DEV_PARAMS cmd. + * Handler for commands without a data phase */ -static ide_startstop_t set_geometry_intr(ide_drive_t *drive) +static ide_startstop_t task_no_data_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - int retries = 5; + ide_task_t *task = &hwif->task; + struct ide_taskfile *tf = &task->tf; + int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0; + int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1; u8 stat; local_irq_enable_in_hardirq(); @@ -164,50 +133,36 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive) udelay(10); }; - if (OK_STAT(stat, ATA_DRDY, BAD_STAT)) - return ide_stopped; - - if (stat & (ATA_ERR | ATA_DRQ)) - return ide_error(drive, "set_geometry_intr", stat); - - ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL); - return ide_started; -} - -/* - * recal_intr() is invoked on completion of a ATA_CMD_RESTORE (recalibrate) cmd. - */ -static ide_startstop_t recal_intr(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 stat; - - local_irq_enable_in_hardirq(); - stat = hwif->tp_ops->read_status(hwif); - - if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) - return ide_error(drive, "recal_intr", stat); - return ide_stopped; -} - -/* - * Handler for commands without a data phase - */ -static ide_startstop_t task_no_data_intr(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - ide_task_t *args = hwif->hwgroup->rq->special; - u8 stat; - - local_irq_enable_in_hardirq(); - stat = hwif->tp_ops->read_status(hwif); - - if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) + if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) { + if (custom && tf->command == ATA_CMD_SET_MULTI) { + drive->mult_req = drive->mult_count = 0; + drive->special.b.recalibrate = 1; + (void)ide_dump_status(drive, __func__, stat); + return ide_stopped; + } else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) { + if ((stat & (ATA_ERR | ATA_DRQ)) == 0) { + ide_set_handler(drive, &task_no_data_intr, + WAIT_WORSTCASE, NULL); + return ide_started; + } + } return ide_error(drive, "task_no_data_intr", stat); /* calls ide_end_drive_cmd */ + } - if (args) + if (!custom) + ide_end_drive_cmd(drive, stat, ide_read_error(drive)); + else if (tf->command == ATA_CMD_IDLEIMMEDIATE) { + hwif->tp_ops->tf_read(drive, task); + if (tf->lbal != 0xc4) { + printk(KERN_ERR "%s: head unload failed!\n", + drive->name); + ide_tf_dump(drive->name, tf); + } else + drive->dev_flags |= IDE_DFLAG_PARKED; ide_end_drive_cmd(drive, stat, ide_read_error(drive)); + } else if (tf->command == ATA_CMD_SET_MULTI) + drive->mult_count = drive->mult_req; return ide_stopped; } @@ -469,13 +424,12 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) if (ide_wait_stat(&startstop, drive, ATA_DRQ, drive->bad_wstat, WAIT_DRQ)) { printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", - drive->name, - drive->hwif->data_phase ? "MULT" : "", - drive->addressing ? "_EXT" : ""); + drive->name, drive->hwif->data_phase ? "MULT" : "", + (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); return startstop; } - if (!drive->unmask) + if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0) local_irq_disable(); ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); @@ -591,7 +545,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | IDE_TFLAG_IN_TF; - if (drive->addressing == 1) + if (drive->dev_flags & IDE_DFLAG_LBA48) args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB); if (req_task->out_flags.all) { @@ -694,7 +648,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) && req_task->in_flags.all == 0) { req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; - if (drive->addressing == 1) + if (drive->dev_flags & IDE_DFLAG_LBA48) req_task->in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8); } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 9dcf5aed92c..04f8f13cb9d 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -114,7 +114,7 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif) memset(drive, 0, sizeof(*drive)); drive->media = ide_disk; - drive->select.all = (unit<<4)|0xa0; + drive->select = (unit << 4) | ATA_DEVICE_OBS; drive->hwif = hwif; drive->ready_stat = ATA_DRDY; drive->bad_wstat = BAD_W_STAT; @@ -138,7 +138,7 @@ static void __ide_port_unregister_devices(ide_hwif_t *hwif) for (i = 0; i < MAX_DRIVES; i++) { ide_drive_t *drive = &hwif->drives[i]; - if (drive->present) { + if (drive->dev_flags & IDE_DFLAG_PRESENT) { spin_unlock_irq(&ide_lock); device_unregister(&drive->gendev); wait_for_completion(&drive->gendev_rel_comp); @@ -227,8 +227,7 @@ void ide_unregister(ide_hwif_t *hwif) kfree(hwif->sg_table); unregister_blkdev(hwif->major, hwif->name); - if (hwif->dma_base) - ide_release_dma_engine(hwif); + ide_release_dma_engine(hwif); mutex_unlock(&ide_cfg_mtx); } @@ -254,7 +253,7 @@ ide_devset_get(io_32bit, io_32bit); static int set_io_32bit(ide_drive_t *drive, int arg) { - if (drive->no_io_32bit) + if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) return -EPERM; if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1)) @@ -265,19 +264,22 @@ static int set_io_32bit(ide_drive_t *drive, int arg) return 0; } -ide_devset_get(ksettings, keep_settings); +ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS); static int set_ksettings(ide_drive_t *drive, int arg) { if (arg < 0 || arg > 1) return -EINVAL; - drive->keep_settings = arg; + if (arg) + drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS; + else + drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS; return 0; } -ide_devset_get(using_dma, using_dma); +ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA); static int set_using_dma(ide_drive_t *drive, int arg) { @@ -311,9 +313,32 @@ out: #endif } +/* + * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away + */ +static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) +{ + switch (req_pio) { + case 202: + case 201: + case 200: + case 102: + case 101: + case 100: + return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0; + case 9: + case 8: + return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0; + case 7: + case 6: + return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0; + default: + return 0; + } +} + static int set_pio_mode(ide_drive_t *drive, int arg) { - struct request *rq; ide_hwif_t *hwif = drive->hwif; const struct ide_port_ops *port_ops = hwif->port_ops; @@ -324,56 +349,65 @@ static int set_pio_mode(ide_drive_t *drive, int arg) (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) return -ENOSYS; - if (drive->special.b.set_tune) - return -EBUSY; + if (set_pio_mode_abuse(drive->hwif, arg)) { + if (arg == 8 || arg == 9) { + unsigned long flags; - rq = blk_get_request(drive->queue, READ, __GFP_WAIT); - rq->cmd_type = REQ_TYPE_ATA_TASKFILE; + /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */ + spin_lock_irqsave(&ide_lock, flags); + port_ops->set_pio_mode(drive, arg); + spin_unlock_irqrestore(&ide_lock, flags); + } else + port_ops->set_pio_mode(drive, arg); + } else { + int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); - drive->tune_req = (u8) arg; - drive->special.b.set_tune = 1; + ide_set_pio(drive, arg); - blk_execute_rq(drive->queue, NULL, rq, 0); - blk_put_request(rq); + if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { + if (keep_dma) + ide_dma_on(drive); + } + } return 0; } -ide_devset_get(unmaskirq, unmask); +ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK); static int set_unmaskirq(ide_drive_t *drive, int arg) { - if (drive->no_unmask) + if (drive->dev_flags & IDE_DFLAG_NO_UNMASK) return -EPERM; if (arg < 0 || arg > 1) return -EINVAL; - drive->unmask = arg; + if (arg) + drive->dev_flags |= IDE_DFLAG_UNMASK; + else + drive->dev_flags &= ~IDE_DFLAG_UNMASK; return 0; } -#define ide_gen_devset_rw(_name, _func) \ -__IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func) - -ide_gen_devset_rw(io_32bit, io_32bit); -ide_gen_devset_rw(keepsettings, ksettings); -ide_gen_devset_rw(unmaskirq, unmaskirq); -ide_gen_devset_rw(using_dma, using_dma); -__IDE_DEVSET(pio_mode, 0, NULL, set_pio_mode); +ide_ext_devset_rw_sync(io_32bit, io_32bit); +ide_ext_devset_rw_sync(keepsettings, ksettings); +ide_ext_devset_rw_sync(unmaskirq, unmaskirq); +ide_ext_devset_rw_sync(using_dma, using_dma); +__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode); static int generic_ide_suspend(struct device *dev, pm_message_t mesg) { - ide_drive_t *drive = dev->driver_data; + ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); ide_hwif_t *hwif = HWIF(drive); struct request *rq; struct request_pm_state rqpm; ide_task_t args; int ret; - /* Call ACPI _GTM only once */ - if (!(drive->dn % 2)) + /* call ACPI _GTM only once */ + if ((drive->dn & 1) == 0 || pair == NULL) ide_acpi_get_timing(hwif); memset(&rqpm, 0, sizeof(rqpm)); @@ -382,33 +416,32 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg) rq->cmd_type = REQ_TYPE_PM_SUSPEND; rq->special = &args; rq->data = &rqpm; - rqpm.pm_step = ide_pm_state_start_suspend; + rqpm.pm_step = IDE_PM_START_SUSPEND; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; rqpm.pm_state = mesg.event; ret = blk_execute_rq(drive->queue, NULL, rq, 0); blk_put_request(rq); - /* only call ACPI _PS3 after both drivers are suspended */ - if (!ret && (((drive->dn % 2) && hwif->drives[0].present - && hwif->drives[1].present) - || !hwif->drives[0].present - || !hwif->drives[1].present)) + + /* call ACPI _PS3 only after both devices are suspended */ + if (ret == 0 && ((drive->dn & 1) || pair == NULL)) ide_acpi_set_state(hwif, 0); + return ret; } static int generic_ide_resume(struct device *dev) { - ide_drive_t *drive = dev->driver_data; + ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); ide_hwif_t *hwif = HWIF(drive); struct request *rq; struct request_pm_state rqpm; ide_task_t args; int err; - /* Call ACPI _STM only once */ - if (!(drive->dn % 2)) { + /* call ACPI _PS0 / _STM only once */ + if ((drive->dn & 1) == 0 || pair == NULL) { ide_acpi_set_state(hwif, 1); ide_acpi_push_timing(hwif); } @@ -422,7 +455,7 @@ static int generic_ide_resume(struct device *dev) rq->cmd_flags |= REQ_PREEMPT; rq->special = &args; rq->data = &rqpm; - rqpm.pm_step = ide_pm_state_start_resume; + rqpm.pm_step = IDE_PM_START_RESUME; rqpm.pm_state = PM_EVENT_ON; err = blk_execute_rq(drive->queue, NULL, rq, 1); @@ -554,6 +587,7 @@ static struct device_attribute ide_dev_attrs[] = { __ATTR_RO(model), __ATTR_RO(firmware), __ATTR(serial, 0400, serial_show, NULL), + __ATTR(unload_heads, 0644, ide_park_show, ide_park_store), __ATTR_NULL }; @@ -708,22 +742,22 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp) module_param_call(chs, ide_set_disk_chs, NULL, NULL, 0); MODULE_PARM_DESC(chs, "force device as a disk (using CHS)"); -static void ide_dev_apply_params(ide_drive_t *drive) +static void ide_dev_apply_params(ide_drive_t *drive, u8 unit) { - int i = drive->hwif->index * MAX_DRIVES + drive->select.b.unit; + int i = drive->hwif->index * MAX_DRIVES + unit; if (ide_nodma & (1 << i)) { printk(KERN_INFO "ide: disallowing DMA for %s\n", drive->name); - drive->nodma = 1; + drive->dev_flags |= IDE_DFLAG_NODMA; } if (ide_noflush & (1 << i)) { printk(KERN_INFO "ide: disabling flush requests for %s\n", drive->name); - drive->noflush = 1; + drive->dev_flags |= IDE_DFLAG_NOFLUSH; } if (ide_noprobe & (1 << i)) { printk(KERN_INFO "ide: skipping probe for %s\n", drive->name); - drive->noprobe = 1; + drive->dev_flags |= IDE_DFLAG_NOPROBE; } if (ide_nowerr & (1 << i)) { printk(KERN_INFO "ide: ignoring the ATA_DF bit for %s\n", @@ -732,7 +766,7 @@ static void ide_dev_apply_params(ide_drive_t *drive) } if (ide_cdroms & (1 << i)) { printk(KERN_INFO "ide: forcing %s as a CD-ROM\n", drive->name); - drive->present = 1; + drive->dev_flags |= IDE_DFLAG_PRESENT; drive->media = ide_cdrom; /* an ATAPI device ignores DRDY */ drive->ready_stat = 0; @@ -741,11 +775,12 @@ static void ide_dev_apply_params(ide_drive_t *drive) drive->cyl = drive->bios_cyl = ide_disks_chs[i].cyl; drive->head = drive->bios_head = ide_disks_chs[i].head; drive->sect = drive->bios_sect = ide_disks_chs[i].sect; - drive->forced_geom = 1; + printk(KERN_INFO "ide: forcing %s as a disk (%d/%d/%d)\n", drive->name, drive->cyl, drive->head, drive->sect); - drive->present = 1; + + drive->dev_flags |= IDE_DFLAG_FORCED_GEOM | IDE_DFLAG_PRESENT; drive->media = ide_disk; drive->ready_stat = ATA_DRDY; } @@ -785,7 +820,7 @@ void ide_port_apply_params(ide_hwif_t *hwif) } for (i = 0; i < MAX_DRIVES; i++) - ide_dev_apply_params(&hwif->drives[i]); + ide_dev_apply_params(&hwif->drives[i], i); } /* diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/ide_arm.c index f728f2927b5..f728f2927b5 100644 --- a/drivers/ide/arm/ide_arm.c +++ b/drivers/ide/ide_arm.c diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/ide_platform.c index 051b4ab0f35..051b4ab0f35 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/ide_platform.c diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/it8213.c index 0954ccd08d6..7c2feeb3c5e 100644 --- a/drivers/ide/pci/it8213.c +++ b/drivers/ide/it8213.c @@ -189,7 +189,7 @@ static const struct pci_device_id it8213_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, it8213_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver it8213_pci_driver = { .name = "ITE8213_IDE", .id_table = it8213_pci_tbl, .probe = it8213_init_one, @@ -200,12 +200,12 @@ static struct pci_driver driver = { static int __init it8213_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&it8213_pci_driver); } static void __exit it8213_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&it8213_pci_driver); } module_init(it8213_ide_init); diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/it821x.c index 46edd083b34..995e18bb313 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/it821x.c @@ -138,8 +138,7 @@ static void it821x_program_udma(ide_drive_t *drive, u16 timing) struct pci_dev *dev = to_pci_dev(hwif->dev); struct it821x_dev *itdev = ide_get_hwifdata(hwif); int channel = hwif->channel; - int unit = drive->select.b.unit; - u8 conf; + u8 unit = drive->dn & 1, conf; /* Program UDMA timing bits */ if(itdev->clock_mode == ATA_66) @@ -168,13 +167,11 @@ static void it821x_clock_strategy(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct it821x_dev *itdev = ide_get_hwifdata(hwif); + ide_drive_t *pair; + int clock, altclock, sel = 0; + u8 unit = drive->dn & 1, v; - u8 unit = drive->select.b.unit; - ide_drive_t *pair = &hwif->drives[1-unit]; - - int clock, altclock; - u8 v; - int sel = 0; + pair = &hwif->drives[1 - unit]; if(itdev->want[0][0] > itdev->want[1][0]) { clock = itdev->want[0][1]; @@ -240,16 +237,17 @@ static void it821x_clock_strategy(ide_drive_t *drive) static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio) { - ide_hwif_t *hwif = drive->hwif; + ide_hwif_t *hwif = drive->hwif; struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int unit = drive->select.b.unit; - ide_drive_t *pair = &hwif->drives[1 - unit]; - u8 set_pio = pio; + ide_drive_t *pair; + u8 unit = drive->dn & 1, set_pio = pio; /* Spec says 89 ref driver uses 88 */ static u16 pio_timings[]= { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY }; + pair = &hwif->drives[1 - unit]; + /* * Compute the best PIO mode we can for a given device. We must * pick a speed that does not cause problems with the other device @@ -286,9 +284,7 @@ static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted) ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct it821x_dev *itdev = (void *)ide_get_hwifdata(hwif); - int unit = drive->select.b.unit; - int channel = hwif->channel; - u8 conf; + u8 unit = drive->dn & 1, channel = hwif->channel, conf; static u16 dma[] = { 0x8866, 0x3222, 0x3121 }; static u8 mwdma_want[] = { ATA_ANY, ATA_66, ATA_ANY }; @@ -325,9 +321,7 @@ static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted) ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int unit = drive->select.b.unit; - int channel = hwif->channel; - u8 conf; + u8 unit = drive->dn & 1, channel = hwif->channel, conf; static u16 udma[] = { 0x4433, 0x4231, 0x3121, 0x2121, 0x1111, 0x2211, 0x1111 }; static u8 udma_want[] = { ATA_ANY, ATA_50, ATA_ANY, ATA_66, ATA_66, ATA_50, ATA_66 }; @@ -369,7 +363,8 @@ static void it821x_dma_start(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int unit = drive->select.b.unit; + u8 unit = drive->dn & 1; + if(itdev->mwdma[unit] != MWDMA_OFF) it821x_program(drive, itdev->mwdma[unit]); else if(itdev->udma[unit] != UDMA_OFF && itdev->timing10) @@ -389,9 +384,10 @@ static void it821x_dma_start(ide_drive_t *drive) static int it821x_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - int unit = drive->select.b.unit; struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int ret = __ide_dma_end(drive); + int ret = ide_dma_end(drive); + u8 unit = drive->dn & 1; + if(itdev->mwdma[unit] != MWDMA_OFF) it821x_program(drive, itdev->pio[unit]); return ret; @@ -454,7 +450,7 @@ static void it821x_quirkproc(ide_drive_t *drive) * IRQ mask as we may well be in PIO (eg rev 0x10) * for now and we know unmasking is safe on this chipset. */ - drive->unmask = 1; + drive->dev_flags |= IDE_DFLAG_UNMASK; } else { /* * Perform fixups on smart mode. We need to "lose" some @@ -680,7 +676,7 @@ static const struct pci_device_id it821x_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, it821x_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver it821x_pci_driver = { .name = "ITE821x IDE", .id_table = it821x_pci_tbl, .probe = it821x_init_one, @@ -691,12 +687,12 @@ static struct pci_driver driver = { static int __init it821x_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&it821x_pci_driver); } static void __exit it821x_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&it821x_pci_driver); } module_init(it821x_ide_init); diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/jmicron.c index acd64711064..9a68433cf46 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/jmicron.c @@ -149,7 +149,7 @@ static struct pci_device_id jmicron_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, jmicron_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver jmicron_pci_driver = { .name = "JMicron IDE", .id_table = jmicron_pci_tbl, .probe = jmicron_init_one, @@ -160,12 +160,12 @@ static struct pci_driver driver = { static int __init jmicron_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&jmicron_pci_driver); } static void __exit jmicron_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&jmicron_pci_driver); } module_init(jmicron_ide_init); diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile deleted file mode 100644 index 6939329f89e..00000000000 --- a/drivers/ide/legacy/Makefile +++ /dev/null @@ -1,25 +0,0 @@ - -# link order is important here - -obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o -obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o -obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o -obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o -obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o -obj-$(CONFIG_BLK_DEV_4DRIVES) += ide-4drives.o - -obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o -obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o -obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o -obj-$(CONFIG_BLK_DEV_Q40IDE) += q40ide.o -obj-$(CONFIG_BLK_DEV_BUDDHA) += buddha.o - -ifeq ($(CONFIG_BLK_DEV_IDECS), m) - obj-m += ide-cs.o -endif - -ifeq ($(CONFIG_BLK_DEV_PLATFORM), m) - obj-m += ide_platform.o -endif - -EXTRA_CFLAGS := -Idrivers/ide diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/macide.c index 43f97cc1d30..43f97cc1d30 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/macide.c diff --git a/drivers/ide/mips/Makefile b/drivers/ide/mips/Makefile deleted file mode 100644 index 5873fa0b876..00000000000 --- a/drivers/ide/mips/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o - -EXTRA_CFLAGS := -Idrivers/ide diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/ns87415.c index 53bd645736d..13789060f40 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/ns87415.c @@ -137,7 +137,7 @@ static void __devinit superio_init_iops(struct hwif_s *hwif) static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; /* - * This routine either enables/disables (according to drive->present) + * This routine either enables/disables (according to IDE_DFLAG_PRESENT) * the IRQ associated with the port (HWIF(drive)), * and selects either PIO or DMA handshaking for the next I/O operation. */ @@ -153,11 +153,15 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma) /* Adjust IRQ enable bit */ bit = 1 << (8 + hwif->channel); - new = drive->present ? (new & ~bit) : (new | bit); + + if (drive->dev_flags & IDE_DFLAG_PRESENT) + new &= ~bit; + else + new |= bit; /* Select PIO or DMA, DMA may only be selected for one drive/channel. */ - bit = 1 << (20 + drive->select.b.unit + (hwif->channel << 1)); - other = 1 << (20 + (1 - drive->select.b.unit) + (hwif->channel << 1)); + bit = 1 << (20 + (drive->dn & 1) + (hwif->channel << 1)); + other = 1 << (20 + (1 - (drive->dn & 1)) + (hwif->channel << 1)); new = use_dma ? ((new & ~other) | bit) : (new & ~bit); if (new != *old) { @@ -187,7 +191,8 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma) static void ns87415_selectproc (ide_drive_t *drive) { - ns87415_prepare_drive (drive, drive->using_dma); + ns87415_prepare_drive(drive, + !!(drive->dev_flags & IDE_DFLAG_USING_DMA)); } static int ns87415_dma_end(ide_drive_t *drive) @@ -334,7 +339,7 @@ static const struct pci_device_id ns87415_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, ns87415_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver ns87415_pci_driver = { .name = "NS87415_IDE", .id_table = ns87415_pci_tbl, .probe = ns87415_init_one, @@ -345,12 +350,12 @@ static struct pci_driver driver = { static int __init ns87415_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&ns87415_pci_driver); } static void __exit ns87415_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&ns87415_pci_driver); } module_init(ns87415_ide_init); diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/opti621.c index 3de11ddcf86..6048eda3cd6 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/opti621.c @@ -179,7 +179,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) misc = addr_timings[clk][addr_pio]; /* select Index-0/1 for Register-A/B */ - write_reg(drive->select.b.unit, MISC_REG); + write_reg(drive->dn & 1, MISC_REG); /* set read cycle timings */ write_reg(tim, READ_REG); /* set write cycle timings */ @@ -220,7 +220,7 @@ static const struct pci_device_id opti621_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, opti621_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver opti621_pci_driver = { .name = "Opti621_IDE", .id_table = opti621_pci_tbl, .probe = opti621_init_one, @@ -231,12 +231,12 @@ static struct pci_driver driver = { static int __init opti621_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&opti621_pci_driver); } static void __exit opti621_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&opti621_pci_driver); } module_init(opti621_ide_init); diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/palm_bk3710.c index 122ed3c072f..122ed3c072f 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/palm_bk3710.c diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile deleted file mode 100644 index 02e6ee7d751..00000000000 --- a/drivers/ide/pci/Makefile +++ /dev/null @@ -1,44 +0,0 @@ - -obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o -obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o -obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o -obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o -obj-$(CONFIG_BLK_DEV_CELLEB) += scc_pata.o -obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o -obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o -obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o -obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o -obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o -obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o -obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o -obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o -obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o -obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o -obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o -obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o -obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o -obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o -obj-$(CONFIG_BLK_DEV_PDC202XX_OLD) += pdc202xx_old.o -obj-$(CONFIG_BLK_DEV_PDC202XX_NEW) += pdc202xx_new.o -obj-$(CONFIG_BLK_DEV_PIIX) += piix.o -obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o -obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o -obj-$(CONFIG_BLK_DEV_SGIIOC4) += sgiioc4.o -obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o -obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o -obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o -obj-$(CONFIG_BLK_DEV_SLC90E66) += slc90e66.o -obj-$(CONFIG_BLK_DEV_TC86C001) += tc86c001.o -obj-$(CONFIG_BLK_DEV_TRIFLEX) += triflex.o -obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o -obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o - -# Must appear at the end of the block -obj-$(CONFIG_BLK_DEV_GENERIC) += ide-pci-generic.o -ide-pci-generic-y += generic.o - -ifeq ($(CONFIG_BLK_DEV_CMD640), m) - obj-m += cmd640.o -endif - -EXTRA_CFLAGS := -Idrivers/ide diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c deleted file mode 100644 index 644de29f8fe..00000000000 --- a/drivers/ide/pci/hpt34x.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> - * - * May be copied or modified under the terms of the GNU General Public License - * - * - * 00:12.0 Unknown mass storage controller: - * Triones Technologies, Inc. - * Unknown device 0003 (rev 01) - * - * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010) - * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030) - * hde: DMA 2 (0x0000 0x0002) (0x0000 0x0010) - * hdf: DMA 2 (0x0002 0x0012) (0x0010 0x0030) - * hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070) - * hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0) - * - * 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/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/ioport.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ide.h> - -#define DRV_NAME "hpt34x" - -#define HPT343_DEBUG_DRIVE_INFO 0 - -static void hpt34x_set_mode(ide_drive_t *drive, const u8 speed) -{ - struct pci_dev *dev = to_pci_dev(drive->hwif->dev); - u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0; - u8 hi_speed, lo_speed; - - hi_speed = speed >> 4; - lo_speed = speed & 0x0f; - - if (hi_speed & 7) { - hi_speed = (hi_speed & 4) ? 0x01 : 0x10; - } else { - lo_speed <<= 5; - lo_speed >>= 5; - } - - pci_read_config_dword(dev, 0x44, ®1); - pci_read_config_dword(dev, 0x48, ®2); - tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); - tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn))); - pci_write_config_dword(dev, 0x44, tmp1); - pci_write_config_dword(dev, 0x48, tmp2); - -#if HPT343_DEBUG_DRIVE_INFO - printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \ - " (0x%02x 0x%02x)\n", - drive->name, ide_xfer_verbose(speed), - drive->dn, reg1, tmp1, reg2, tmp2, - hi_speed, lo_speed); -#endif /* HPT343_DEBUG_DRIVE_INFO */ -} - -static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - hpt34x_set_mode(drive, XFER_PIO_0 + pio); -} - -/* - * If the BIOS does not set the IO base addaress to XX00, 343 will fail. - */ -#define HPT34X_PCI_INIT_REG 0x80 - -static unsigned int init_chipset_hpt34x(struct pci_dev *dev) -{ - int i = 0; - unsigned long hpt34xIoBase = pci_resource_start(dev, 4); - unsigned long hpt_addr[4] = { 0x20, 0x34, 0x28, 0x3c }; - unsigned long hpt_addr_len[4] = { 7, 3, 7, 3 }; - u16 cmd; - unsigned long flags; - - local_irq_save(flags); - - pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00); - pci_read_config_word(dev, PCI_COMMAND, &cmd); - - if (cmd & PCI_COMMAND_MEMORY) - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); - else - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); - - /* - * Since 20-23 can be assigned and are R/W, we correct them. - */ - pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO); - for(i=0; i<4; i++) { - dev->resource[i].start = (hpt34xIoBase + hpt_addr[i]); - dev->resource[i].end = dev->resource[i].start + hpt_addr_len[i]; - dev->resource[i].flags = IORESOURCE_IO; - pci_write_config_dword(dev, - (PCI_BASE_ADDRESS_0 + (i * 4)), - dev->resource[i].start); - } - pci_write_config_word(dev, PCI_COMMAND, cmd); - - local_irq_restore(flags); - - return dev->irq; -} - -static const struct ide_port_ops hpt34x_port_ops = { - .set_pio_mode = hpt34x_set_pio_mode, - .set_dma_mode = hpt34x_set_mode, -}; - -#define IDE_HFLAGS_HPT34X \ - (IDE_HFLAG_NO_ATAPI_DMA | \ - IDE_HFLAG_NO_DSC | \ - IDE_HFLAG_NO_AUTODMA) - -static const struct ide_port_info hpt34x_chipsets[] __devinitdata = { - { /* 0: HPT343 */ - .name = DRV_NAME, - .init_chipset = init_chipset_hpt34x, - .port_ops = &hpt34x_port_ops, - .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_NON_BOOTABLE, - .pio_mask = ATA_PIO5, - }, - { /* 1: HPT345 */ - .name = DRV_NAME, - .init_chipset = init_chipset_hpt34x, - .port_ops = &hpt34x_port_ops, - .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_OFF_BOARD, - .pio_mask = ATA_PIO5, -#ifdef CONFIG_HPT34X_AUTODMA - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA2, -#endif - } -}; - -static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - const struct ide_port_info *d; - u16 pcicmd = 0; - - pci_read_config_word(dev, PCI_COMMAND, &pcicmd); - - d = &hpt34x_chipsets[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0]; - - return ide_pci_init_one(dev, d, NULL); -} - -static const struct pci_device_id hpt34x_pci_tbl[] = { - { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), 0 }, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, hpt34x_pci_tbl); - -static struct pci_driver driver = { - .name = "HPT34x_IDE", - .id_table = hpt34x_pci_tbl, - .probe = hpt34x_init_one, - .remove = ide_pci_remove, - .suspend = ide_pci_suspend, - .resume = ide_pci_resume, -}; - -static int __init hpt34x_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -static void __exit hpt34x_ide_exit(void) -{ - pci_unregister_driver(&driver); -} - -module_init(hpt34x_ide_init); -module_exit(hpt34x_ide_exit); - -MODULE_AUTHOR("Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for Highpoint 34x IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c index 9fc59962553..211ae46e3e0 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pdc202xx_new.c @@ -561,7 +561,7 @@ static const struct pci_device_id pdc202new_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, pdc202new_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver pdc202new_pci_driver = { .name = "Promise_IDE", .id_table = pdc202new_pci_tbl, .probe = pdc202new_init_one, @@ -572,12 +572,12 @@ static struct pci_driver driver = { static int __init pdc202new_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&pdc202new_pci_driver); } static void __exit pdc202new_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&pdc202new_pci_driver); } module_init(pdc202new_ide_init); diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index cb6d2a00c51..799557c25ee 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c @@ -168,7 +168,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive) { if (drive->current_speed > XFER_UDMA_2) pdc_old_enable_66MHz_clock(drive->hwif); - if (drive->media != ide_disk || drive->addressing == 1) { + if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) { struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive); unsigned long high_16 = hwif->extra_base - 16; @@ -188,7 +188,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive) static int pdc202xx_dma_end(ide_drive_t *drive) { - if (drive->media != ide_disk || drive->addressing == 1) { + if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) { ide_hwif_t *hwif = HWIF(drive); unsigned long high_16 = hwif->extra_base - 16; unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); @@ -200,7 +200,7 @@ static int pdc202xx_dma_end(ide_drive_t *drive) } if (drive->current_speed > XFER_UDMA_2) pdc_old_disable_66MHz_clock(drive->hwif); - return __ide_dma_end(drive); + return ide_dma_end(drive); } static int pdc202xx_dma_test_irq(ide_drive_t *drive) @@ -333,7 +333,7 @@ static const struct ide_dma_ops pdc20246_dma_ops = { .dma_setup = ide_dma_setup, .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, - .dma_end = __ide_dma_end, + .dma_end = ide_dma_end, .dma_test_irq = pdc202xx_dma_test_irq, .dma_lost_irq = pdc202xx_dma_lost_irq, .dma_timeout = pdc202xx_dma_timeout, @@ -426,7 +426,7 @@ static const struct pci_device_id pdc202xx_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, pdc202xx_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver pdc202xx_pci_driver = { .name = "Promise_Old_IDE", .id_table = pdc202xx_pci_tbl, .probe = pdc202xx_init_one, @@ -437,12 +437,12 @@ static struct pci_driver driver = { static int __init pdc202xx_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&pdc202xx_pci_driver); } static void __exit pdc202xx_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&pdc202xx_pci_driver); } module_init(pdc202xx_ide_init); diff --git a/drivers/ide/pci/piix.c b/drivers/ide/piix.c index a06c03f8e29..d63f9fdca76 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/piix.c @@ -215,17 +215,26 @@ static unsigned int init_chipset_ich(struct pci_dev *dev) } /** - * piix_dma_clear_irq - clear BMDMA status - * @drive: IDE drive to clear + * ich_clear_irq - clear BMDMA status + * @drive: IDE drive * - * Called from ide_intr() for PIO interrupts - * to clear BMDMA status as needed by ICHx + * ICHx contollers set DMA INTR no matter DMA or PIO. + * BMDMA status might need to be cleared even for + * PIO interrupts to prevent spurious/lost IRQ. */ -static void piix_dma_clear_irq(ide_drive_t *drive) +static void ich_clear_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u8 dma_stat; + /* + * ide_dma_end() needs BMDMA status for error checking. + * So, skip clearing BMDMA status here and leave it + * to ide_dma_end() if this is DMA interrupt. + */ + if (drive->waiting_for_dma || hwif->dma_base == 0) + return; + /* clear the INTR & ERROR bits */ dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); /* Should we force the bit as well ? */ @@ -249,6 +258,7 @@ static const struct ich_laptop ich_laptop[] = { { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ + { 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on Acer Aspire 2023WLMi */ { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ /* end marker */ @@ -293,21 +303,19 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0; } -static void __devinit init_hwif_ich(ide_hwif_t *hwif) -{ - init_hwif_piix(hwif); - - /* ICHx need to clear the BMDMA status for all interrupts */ - if (hwif->dma_base) - hwif->ide_dma_clear_irq = &piix_dma_clear_irq; -} - static const struct ide_port_ops piix_port_ops = { .set_pio_mode = piix_set_pio_mode, .set_dma_mode = piix_set_dma_mode, .cable_detect = piix_cable_detect, }; +static const struct ide_port_ops ich_port_ops = { + .set_pio_mode = piix_set_pio_mode, + .set_dma_mode = piix_set_dma_mode, + .clear_irq = ich_clear_irq, + .cable_detect = piix_cable_detect, +}; + #ifndef CONFIG_IA64 #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS #else @@ -331,9 +339,9 @@ static const struct ide_port_ops piix_port_ops = { { \ .name = DRV_NAME, \ .init_chipset = init_chipset_ich, \ - .init_hwif = init_hwif_ich, \ + .init_hwif = init_hwif_piix, \ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ - .port_ops = &piix_port_ops, \ + .port_ops = &ich_port_ops, \ .host_flags = IDE_HFLAGS_PIIX, \ .pio_mask = ATA_PIO4, \ .swdma_mask = ATA_SWDMA2_ONLY, \ @@ -444,7 +452,7 @@ static const struct pci_device_id piix_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, piix_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver piix_pci_driver = { .name = "PIIX_IDE", .id_table = piix_pci_tbl, .probe = piix_init_one, @@ -456,12 +464,12 @@ static struct pci_driver driver = { static int __init piix_ide_init(void) { piix_check_450nx(); - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&piix_pci_driver); } static void __exit piix_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&piix_pci_driver); } module_init(piix_ide_init); diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/pmac.c index c3432da78d5..2e19d629853 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/pmac.c @@ -430,10 +430,7 @@ pmac_ide_selectproc(ide_drive_t *drive) pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - if (pmif == NULL) - return; - - if (drive->select.b.unit & 0x01) + if (drive->dn & 1) writel(pmif->timings[1], PMAC_IDE_REG(IDE_TIMING_CONFIG)); else writel(pmif->timings[0], PMAC_IDE_REG(IDE_TIMING_CONFIG)); @@ -452,10 +449,7 @@ pmac_ide_kauai_selectproc(ide_drive_t *drive) pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - if (pmif == NULL) - return; - - if (drive->select.b.unit & 0x01) { + if (drive->dn & 1) { writel(pmif->timings[1], PMAC_IDE_REG(IDE_KAUAI_PIO_CONFIG)); writel(pmif->timings[3], PMAC_IDE_REG(IDE_KAUAI_ULTRA_CONFIG)); } else { @@ -475,9 +469,6 @@ pmac_ide_do_update_timings(ide_drive_t *drive) pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - if (pmif == NULL) - return; - if (pmif->kind == controller_sh_ata6 || pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6) @@ -524,11 +515,8 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) unsigned accessTime, recTime; unsigned int cycle_time; - if (pmif == NULL) - return; - /* which drive is it ? */ - timings = &pmif->timings[drive->select.b.unit & 0x01]; + timings = &pmif->timings[drive->dn & 1]; t = *timings; cycle_time = ide_pio_cycle_time(drive, pio); @@ -805,9 +793,9 @@ static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed) ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - int unit = (drive->select.b.unit & 0x01); int ret = 0; u32 *timings, *timings2, tl[2]; + u8 unit = drive->dn & 1; timings = &pmif->timings[unit]; timings2 = &pmif->timings[unit+2]; @@ -966,11 +954,11 @@ static void pmac_ide_init_dev(ide_drive_t *drive) if (pmif->mediabay) { #ifdef CONFIG_PMAC_MEDIABAY if (check_media_bay_by_base(pmif->regbase, MB_CD) == 0) { - drive->noprobe = 0; + drive->dev_flags &= ~IDE_DFLAG_NOPROBE; return; } #endif - drive->noprobe = 1; + drive->dev_flags |= IDE_DFLAG_NOPROBE; } } @@ -1535,18 +1523,6 @@ use_pio_instead: return 0; /* revert to PIO for this request */ } -/* Teardown mappings after DMA has completed. */ -static void -pmac_ide_destroy_dmatable (ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - - if (hwif->sg_nents) { - ide_destroy_dmatable(drive); - hwif->sg_nents = 0; - } -} - /* * Prepare a DMA transfer. We build the DMA table, adjust the timings for * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion @@ -1558,12 +1534,7 @@ pmac_ide_dma_setup(ide_drive_t *drive) pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); struct request *rq = HWGROUP(drive)->rq; - u8 unit = (drive->select.b.unit & 0x01); - u8 ata4; - - if (pmif == NULL) - return 1; - ata4 = (pmif->kind == controller_kl_ata4); + u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4); if (!pmac_ide_build_dmatable(drive, rq)) { ide_map_sg(drive, rq); @@ -1617,17 +1588,15 @@ pmac_ide_dma_end (ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - volatile struct dbdma_regs __iomem *dma; + volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; u32 dstat; - - if (pmif == NULL) - return 0; - dma = pmif->dma_regs; drive->waiting_for_dma = 0; dstat = readl(&dma->status); writel(((RUN|WAKE|DEAD) << 16), &dma->control); - pmac_ide_destroy_dmatable(drive); + + ide_destroy_dmatable(drive); + /* verify good dma status. we don't check for ACTIVE beeing 0. We should... * in theory, but with ATAPI decices doing buffer underruns, that would * cause us to disable DMA, which isn't what we want @@ -1647,13 +1616,9 @@ pmac_ide_dma_test_irq (ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - volatile struct dbdma_regs __iomem *dma; + volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; unsigned long status, timeout; - if (pmif == NULL) - return 0; - dma = pmif->dma_regs; - /* We have to things to deal with here: * * - The dbdma won't stop if the command was started @@ -1672,9 +1637,6 @@ pmac_ide_dma_test_irq (ide_drive_t *drive) status = readl(&dma->status); if (!(status & ACTIVE)) return 1; - if (!drive->waiting_for_dma) - printk(KERN_WARNING "ide%d, ide_dma_test_irq \ - called while not waiting\n", HWIF(drive)->index); /* If dbdma didn't execute the STOP command yet, the * active bit is still set. We consider that we aren't @@ -1709,14 +1671,9 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - volatile struct dbdma_regs __iomem *dma; - unsigned long status; - - if (pmif == NULL) - return; - dma = pmif->dma_regs; + volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; + unsigned long status = readl(&dma->status); - status = readl(&dma->status); printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx\n", status); } diff --git a/drivers/ide/ppc/Makefile b/drivers/ide/ppc/Makefile deleted file mode 100644 index 74e52adcdf4..00000000000 --- a/drivers/ide/ppc/Makefile +++ /dev/null @@ -1,2 +0,0 @@ - -obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/q40ide.c index 4af4a8ce4cd..4af4a8ce4cd 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/q40ide.c diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/qd65xx.c index ec408b3a710..bc27c7aba93 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/qd65xx.c @@ -305,7 +305,7 @@ static void __init qd6580_init_dev(ide_drive_t *drive) } else t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA; - drive->drive_data = drive->select.b.unit ? t2 : t1; + drive->drive_data = (drive->dn & 1) ? t2 : t1; } static const struct ide_port_ops qd6500_port_ops = { diff --git a/drivers/ide/legacy/qd65xx.h b/drivers/ide/qd65xx.h index c83dea85e62..c83dea85e62 100644 --- a/drivers/ide/legacy/qd65xx.h +++ b/drivers/ide/qd65xx.h diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/rapide.c index 78d27d9ae43..78d27d9ae43 100644 --- a/drivers/ide/arm/rapide.c +++ b/drivers/ide/rapide.c diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/rz1000.c index c117a068761..7daf0135cba 100644 --- a/drivers/ide/pci/rz1000.c +++ b/drivers/ide/rz1000.c @@ -59,7 +59,7 @@ static const struct pci_device_id rz1000_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, rz1000_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver rz1000_pci_driver = { .name = "RZ1000_IDE", .id_table = rz1000_pci_tbl, .probe = rz1000_init_one, @@ -68,12 +68,12 @@ static struct pci_driver driver = { static int __init rz1000_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&rz1000_pci_driver); } static void __exit rz1000_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&rz1000_pci_driver); } module_init(rz1000_ide_init); diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/sc1200.c index bdc1fed4126..f1a8758e3a9 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/sc1200.c @@ -126,7 +126,6 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); - int unit = drive->select.b.unit; unsigned int reg, timings; unsigned short pci_clock; unsigned int basereg = hwif->channel ? 0x50 : 0x40; @@ -155,7 +154,7 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode) else timings = mwdma_timing[pci_clock][mode - XFER_MW_DMA_0]; - if (unit == 0) { /* are we configuring drive0? */ + if ((drive->dn & 1) == 0) { pci_read_config_dword(dev, basereg + 4, ®); timings |= reg & 0x80000000; /* preserve PIO format bit */ pci_write_config_dword(dev, basereg + 4, timings); @@ -216,7 +215,8 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) if (mode != -1) { printk("SC1200: %s: changing (U)DMA mode\n", drive->name); ide_dma_off_quietly(drive); - if (ide_set_dma_mode(drive, mode) == 0 && drive->using_dma) + if (ide_set_dma_mode(drive, mode) == 0 && + (drive->dev_flags & IDE_DFLAG_USING_DMA)) hwif->dma_ops->dma_host_set(drive, 1); return; } @@ -328,7 +328,7 @@ static const struct pci_device_id sc1200_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, sc1200_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver sc1200_pci_driver = { .name = "SC1200_IDE", .id_table = sc1200_pci_tbl, .probe = sc1200_init_one, @@ -341,12 +341,12 @@ static struct pci_driver driver = { static int __init sc1200_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&sc1200_pci_driver); } static void __exit sc1200_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&sc1200_pci_driver); } module_init(sc1200_ide_init); diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/scc_pata.c index e92a874b31d..49f163aa51e 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/scc_pata.c @@ -291,7 +291,7 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed) static void scc_dma_host_set(ide_drive_t *drive, int on) { ide_hwif_t *hwif = drive->hwif; - u8 unit = (drive->select.b.unit & 0x01); + u8 unit = drive->dn & 1; u8 dma_stat = scc_ide_inb(hwif->dma_base + 4); if (on) @@ -353,7 +353,6 @@ static void scc_dma_start(ide_drive_t *drive) /* start DMA */ scc_ide_outb(dma_cmd | 1, hwif->dma_base); - hwif->dma = 1; wmb(); } @@ -374,7 +373,6 @@ static int __scc_dma_end(ide_drive_t *drive) /* purge DMA mappings */ ide_destroy_dmatable(drive); /* verify good DMA status */ - hwif->dma = 0; wmb(); return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; } @@ -511,9 +509,6 @@ static int scc_dma_test_irq(ide_drive_t *drive) if (int_stat & INTSTS_IOIRQS) return 1; - if (!drive->waiting_for_dma) - printk(KERN_WARNING "%s: (%s) called while not waiting\n", - drive->name, __func__); return 0; } @@ -622,7 +617,6 @@ static int __devinit init_setup_scc(struct pci_dev *dev, unsigned long intmask_port; unsigned long mode_port; unsigned long ecmode_port; - unsigned long dma_status_port; u32 reg = 0; struct scc_ports *ports; int rc; @@ -642,7 +636,6 @@ static int __devinit init_setup_scc(struct pci_dev *dev, intmask_port = dma_base + 0x010; mode_port = ctl_base + 0x024; ecmode_port = ctl_base + 0xf00; - dma_status_port = dma_base + 0x004; /* controller initialization */ reg = 0; @@ -710,7 +703,7 @@ static void scc_tf_load(ide_drive_t *drive, ide_task_t *task) scc_ide_outb(tf->lbah, io_ports->lbah_addr); if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) - scc_ide_outb((tf->device & HIHI) | drive->select.all, + scc_ide_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } @@ -826,6 +819,12 @@ static void __devinit init_iops_scc(ide_hwif_t *hwif) init_mmio_iops_scc(hwif); } +static int __devinit scc_init_dma(ide_hwif_t *hwif, + const struct ide_port_info *d) +{ + return ide_allocate_dma_engine(hwif); +} + static u8 scc_cable_detect(ide_hwif_t *hwif) { return ATA_CBL_PATA80; @@ -842,8 +841,6 @@ static u8 scc_cable_detect(ide_hwif_t *hwif) static void __devinit init_hwif_scc(ide_hwif_t *hwif) { - struct scc_ports *ports = ide_get_hwifdata(hwif); - /* PTERADD */ out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); @@ -890,6 +887,7 @@ static const struct ide_dma_ops scc_dma_ops = { { \ .name = name_str, \ .init_iops = init_iops_scc, \ + .init_dma = scc_init_dma, \ .init_hwif = init_hwif_scc, \ .tp_ops = &scc_tp_ops, \ .port_ops = &scc_port_ops, \ @@ -927,13 +925,6 @@ static void __devexit scc_remove(struct pci_dev *dev) { struct scc_ports *ports = pci_get_drvdata(dev); struct ide_host *host = ports->host; - ide_hwif_t *hwif = host->ports[0]; - - if (hwif->dmatable_cpu) { - pci_free_consistent(dev, PRD_ENTRIES * PRD_BYTES, - hwif->dmatable_cpu, hwif->dmatable_dma); - hwif->dmatable_cpu = NULL; - } ide_host_remove(host); @@ -949,7 +940,7 @@ static const struct pci_device_id scc_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, scc_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver scc_pci_driver = { .name = "SCC IDE", .id_table = scc_pci_tbl, .probe = scc_init_one, @@ -958,14 +949,14 @@ static struct pci_driver driver = { static int scc_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&scc_pci_driver); } module_init(scc_ide_init); /* -- No exit code? static void scc_ide_exit(void) { - ide_pci_unregister_driver(&driver); + ide_pci_unregister_driver(&scc_pci_driver); } module_exit(scc_ide_exit); */ diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/serverworks.c index 3dff2aea317..437bc919daf 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/serverworks.c @@ -153,7 +153,7 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); - u8 unit = (drive->select.b.unit & 0x01); + u8 unit = drive->dn & 1; u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0; @@ -443,7 +443,7 @@ static const struct pci_device_id svwks_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, svwks_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver svwks_pci_driver = { .name = "Serverworks_IDE", .id_table = svwks_pci_tbl, .probe = svwks_init_one, @@ -454,12 +454,12 @@ static struct pci_driver driver = { static int __init svwks_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&svwks_pci_driver); } static void __exit svwks_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&svwks_pci_driver); } module_init(svwks_ide_init); diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/sgiioc4.c index 1017fb4f631..8af9b23499f 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/sgiioc4.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 2008 MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -100,18 +101,8 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port, for (i = 0; i <= 7; i++) hw->io_ports_array[i] = reg + i * 4; - if (ctrl_port) - hw->io_ports.ctl_addr = ctrl_port; - - if (irq_port) - hw->io_ports.irq_addr = irq_port; -} - -static void -sgiioc4_maskproc(ide_drive_t * drive, int mask) -{ - writeb(ATA_DEVCTL_OBS | (mask ? 2 : 0), - (void __iomem *)drive->hwif->io_ports.ctl_addr); + hw->io_ports.ctl_addr = ctrl_port; + hw->io_ports.irq_addr = irq_port; } static int @@ -150,7 +141,7 @@ sgiioc4_clearirq(ide_drive_t * drive) int count = 0; stat = sgiioc4_read_status(hwif); - while ((stat & 0x80) && (count++ < 100)) { + while ((stat & ATA_BUSY) && (count++ < 100)) { udelay(1); stat = sgiioc4_read_status(hwif); } @@ -309,16 +300,14 @@ static u8 sgiioc4_read_status(ide_hwif_t *hwif) unsigned long port = hwif->io_ports.status_addr; u8 reg = (u8) readb((void __iomem *) port); - if ((port & 0xFFF) == 0x11C) { /* Status register of IOC4 */ - if (reg & 0x51) { /* Not busy...check for interrupt */ - unsigned long other_ir = port - 0x110; - unsigned int intr_reg = (u32) readl((void __iomem *) other_ir); + if (!(reg & ATA_BUSY)) { /* Not busy... check for interrupt */ + unsigned long other_ir = port - 0x110; + unsigned int intr_reg = (u32) readl((void __iomem *) other_ir); - /* Clear the Interrupt, Error bits on the IOC4 */ - if (intr_reg & 0x03) { - writel(0x03, (void __iomem *) other_ir); - intr_reg = (u32) readl((void __iomem *) other_ir); - } + /* Clear the Interrupt, Error bits on the IOC4 */ + if (intr_reg & 0x03) { + writel(0x03, (void __iomem *) other_ir); + intr_reg = (u32) readl((void __iomem *) other_ir); } } @@ -331,42 +320,28 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) { struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; - void __iomem *virt_dma_base; int num_ports = sizeof (ioc4_dma_regs_t); void *pad; - if (dma_base == 0) - return -1; + printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); - printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name, - dma_base, dma_base + num_ports - 1); - - if (!request_mem_region(dma_base, num_ports, hwif->name)) { - printk(KERN_ERR - "%s(%s) -- ERROR, Addresses 0x%p to 0x%p " - "ALREADY in use\n", - __func__, hwif->name, (void *) dma_base, - (void *) dma_base + num_ports - 1); + if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) { + printk(KERN_ERR "%s(%s) -- ERROR: addresses 0x%08lx to 0x%08lx " + "already in use\n", __func__, hwif->name, + dma_base, dma_base + num_ports - 1); return -1; } - virt_dma_base = ioremap(dma_base, num_ports); - if (virt_dma_base == NULL) { - printk(KERN_ERR - "%s(%s) -- ERROR, Unable to map addresses 0x%lx to 0x%lx\n", - __func__, hwif->name, dma_base, dma_base + num_ports - 1); - goto dma_remap_failure; - } - hwif->dma_base = (unsigned long) virt_dma_base; + hwif->dma_base = (unsigned long)hwif->io_ports.irq_addr + + IOC4_DMA_OFFSET; - hwif->dmatable_cpu = pci_alloc_consistent(dev, - IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, - &hwif->dmatable_dma); + hwif->sg_max_nents = IOC4_PRD_ENTRIES; - if (!hwif->dmatable_cpu) - goto dma_pci_alloc_failure; + hwif->prd_max_nents = IOC4_PRD_ENTRIES; + hwif->prd_ent_size = IOC4_PRD_BYTES; - hwif->sg_max_nents = IOC4_PRD_ENTRIES; + if (ide_allocate_dma_engine(hwif)) + goto dma_pci_alloc_failure; pad = pci_alloc_consistent(dev, IOC4_IDE_CACHELINE_SIZE, (dma_addr_t *)&hwif->extra_base); @@ -375,18 +350,13 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) return 0; } - pci_free_consistent(dev, IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, - hwif->dmatable_cpu, hwif->dmatable_dma); - printk(KERN_INFO - "%s() -- Error! Unable to allocate DMA Maps for drive %s\n", + ide_release_dma_engine(hwif); + + printk(KERN_ERR "%s(%s) -- ERROR: Unable to allocate DMA maps\n", __func__, hwif->name); - printk(KERN_INFO - "Changing from DMA to PIO mode for Drive %s\n", hwif->name); + printk(KERN_INFO "%s: changing from DMA to PIO mode", hwif->name); dma_pci_alloc_failure: - iounmap(virt_dma_base); - -dma_remap_failure: release_mem_region(dma_base, num_ports); return -1; @@ -568,8 +538,6 @@ static const struct ide_port_ops sgiioc4_port_ops = { .set_dma_mode = sgiioc4_set_dma_mode, /* reset DMA engine, clear IRQs */ .resetproc = sgiioc4_resetproc, - /* mask on/off NIEN register */ - .maskproc = sgiioc4_maskproc, }; static const struct ide_dma_ops sgiioc4_dma_ops = { @@ -617,14 +585,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET; cmd_phys_base = bar0 + IOC4_CMD_OFFSET; - if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, - DRV_NAME)) { - printk(KERN_ERR - "%s %s: -- ERROR, Addresses " - "0x%p to 0x%p ALREADY in use\n", - DRV_NAME, pci_name(dev), (void *)cmd_phys_base, - (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE); - return -ENOMEM; + if (request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, + DRV_NAME) == NULL) { + printk(KERN_ERR "%s %s -- ERROR: addresses 0x%08lx to 0x%08lx " + "already in use\n", DRV_NAME, pci_name(dev), + cmd_phys_base, cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE); + return -EBUSY; } /* Initialize the IO registers */ diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/siimage.c index 174a873b4c6..eb4faf92c57 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/siimage.c @@ -116,13 +116,14 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) { ide_hwif_t *hwif = HWIF(drive); unsigned long base = (unsigned long)hwif->hwif_data; + u8 unit = drive->dn & 1; base += 0xA0 + r; if (hwif->host_flags & IDE_HFLAG_MMIO) base += hwif->channel << 6; else base += hwif->channel << 4; - base |= drive->select.b.unit << drive->select.b.unit; + base |= unit << unit; return base; } @@ -255,7 +256,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) : (mmio ? 0xB4 : 0x80); u8 mode = 0; - u8 unit = drive->select.b.unit; + u8 unit = drive->dn & 1; /* trim *taskfile* PIO to the slowest of the master/slave */ if (pair) { @@ -301,9 +302,9 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); - u16 ultra = 0, multi = 0; - u8 mode = 0, unit = drive->select.b.unit; unsigned long base = (unsigned long)hwif->hwif_data; + u16 ultra = 0, multi = 0; + u8 mode = 0, unit = drive->dn & 1; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; u8 scsc = 0, addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) : (mmio ? 0xB4 : 0x80); @@ -712,7 +713,7 @@ static const struct ide_dma_ops sil_dma_ops = { .dma_setup = ide_dma_setup, .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, - .dma_end = __ide_dma_end, + .dma_end = ide_dma_end, .dma_test_irq = siimage_dma_test_irq, .dma_timeout = ide_dma_timeout, .dma_lost_irq = ide_dma_lost_irq, @@ -829,7 +830,7 @@ static const struct pci_device_id siimage_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, siimage_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver siimage_pci_driver = { .name = "SiI_IDE", .id_table = siimage_pci_tbl, .probe = siimage_init_one, @@ -840,12 +841,12 @@ static struct pci_driver driver = { static int __init siimage_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&siimage_pci_driver); } static void __exit siimage_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&siimage_pci_driver); } module_init(siimage_ide_init); diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/sis5513.c index 734dd41f1f6..ad32e18c5ba 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/sis5513.c @@ -605,7 +605,7 @@ static const struct pci_device_id sis5513_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, sis5513_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver sis5513_pci_driver = { .name = "SIS_IDE", .id_table = sis5513_pci_tbl, .probe = sis5513_init_one, @@ -616,12 +616,12 @@ static struct pci_driver driver = { static int __init sis5513_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&sis5513_pci_driver); } static void __exit sis5513_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&sis5513_pci_driver); } module_init(sis5513_ide_init); diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/sl82c105.c index 37a6b7bdc04..84dc33602ff 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/sl82c105.c @@ -207,7 +207,7 @@ static int sl82c105_dma_end(ide_drive_t *drive) DBG(("%s(drive:%s)\n", __func__, drive->name)); - ret = __ide_dma_end(drive); + ret = ide_dma_end(drive); pci_write_config_word(dev, reg, drive->drive_data); @@ -345,7 +345,7 @@ static const struct pci_device_id sl82c105_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, sl82c105_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver sl82c105_pci_driver = { .name = "W82C105_IDE", .id_table = sl82c105_pci_tbl, .probe = sl82c105_init_one, @@ -356,12 +356,12 @@ static struct pci_driver driver = { static int __init sl82c105_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&sl82c105_pci_driver); } static void __exit sl82c105_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&sl82c105_pci_driver); } module_init(sl82c105_ide_init); diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/slc90e66.c index a9551a13ac5..0f759e4ed77 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/slc90e66.c @@ -154,7 +154,7 @@ static const struct pci_device_id slc90e66_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, slc90e66_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver slc90e66_pci_driver = { .name = "SLC90e66_IDE", .id_table = slc90e66_pci_tbl, .probe = slc90e66_init_one, @@ -165,12 +165,12 @@ static struct pci_driver driver = { static int __init slc90e66_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&slc90e66_pci_driver); } static void __exit slc90e66_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&slc90e66_pci_driver); } module_init(slc90e66_ide_init); diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/tc86c001.c index 927277c54ec..93e2cce4b29 100644 --- a/drivers/ide/pci/tc86c001.c +++ b/drivers/ide/tc86c001.c @@ -186,7 +186,7 @@ static const struct ide_dma_ops tc86c001_dma_ops = { .dma_setup = ide_dma_setup, .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = tc86c001_dma_start, - .dma_end = __ide_dma_end, + .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, .dma_timeout = ide_dma_timeout, @@ -245,7 +245,7 @@ static const struct pci_device_id tc86c001_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, tc86c001_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver tc86c001_pci_driver = { .name = "TC86C001", .id_table = tc86c001_pci_tbl, .probe = tc86c001_init_one, @@ -254,12 +254,12 @@ static struct pci_driver driver = { static int __init tc86c001_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&tc86c001_pci_driver); } static void __exit tc86c001_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&tc86c001_pci_driver); } module_init(tc86c001_ide_init); diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/triflex.c index be8715dcee0..b6ff40336aa 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/triflex.c @@ -38,13 +38,12 @@ static void triflex_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); - u8 channel_offset = hwif->channel ? 0x74 : 0x70; - u16 timing = 0; u32 triflex_timings = 0; - u8 unit = (drive->select.b.unit & 0x01); - + u16 timing = 0; + u8 channel_offset = hwif->channel ? 0x74 : 0x70, unit = drive->dn & 1; + pci_read_config_dword(dev, channel_offset, &triflex_timings); - + switch(speed) { case XFER_MW_DMA_2: timing = 0x0103; @@ -114,7 +113,7 @@ static const struct pci_device_id triflex_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, triflex_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver triflex_pci_driver = { .name = "TRIFLEX_IDE", .id_table = triflex_pci_tbl, .probe = triflex_init_one, @@ -125,12 +124,12 @@ static struct pci_driver driver = { static int __init triflex_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&triflex_pci_driver); } static void __exit triflex_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&triflex_pci_driver); } module_init(triflex_ide_init); diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/trm290.c index 4dfbc6a68b5..75ea6152656 100644 --- a/drivers/ide/pci/trm290.c +++ b/drivers/ide/trm290.c @@ -161,7 +161,7 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) } /* enable IRQ if not probing */ - if (drive->present) { + if (drive->dev_flags & IDE_DFLAG_PRESENT) { reg = inw(hwif->config_data + 3); reg &= 0x13; reg &= ~(1 << hwif->channel); @@ -173,7 +173,7 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) static void trm290_selectproc (ide_drive_t *drive) { - trm290_prepare_drive(drive, drive->using_dma); + trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA)); } static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command) @@ -350,7 +350,7 @@ static const struct pci_device_id trm290_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, trm290_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver trm290_pci_driver = { .name = "TRM290_IDE", .id_table = trm290_pci_tbl, .probe = trm290_init_one, @@ -359,12 +359,12 @@ static struct pci_driver driver = { static int __init trm290_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&trm290_pci_driver); } static void __exit trm290_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&trm290_pci_driver); } module_init(trm290_ide_init); diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/umc8672.c index 1da076e0c91..1da076e0c91 100644 --- a/drivers/ide/legacy/umc8672.c +++ b/drivers/ide/umc8672.c diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/via82cxxx.c index acacdaab69c..2a812d3207e 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -487,7 +487,7 @@ static const struct pci_device_id via_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, via_pci_tbl); -static struct pci_driver driver = { +static struct pci_driver via_pci_driver = { .name = "VIA_IDE", .id_table = via_pci_tbl, .probe = via_init_one, @@ -498,12 +498,12 @@ static struct pci_driver driver = { static int __init via_ide_init(void) { - return ide_pci_register_driver(&driver); + return ide_pci_register_driver(&via_pci_driver); } static void __exit via_ide_exit(void) { - pci_unregister_driver(&driver); + pci_unregister_driver(&via_pci_driver); } module_init(via_ide_init); |