diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/Kconfig | 98 | ||||
-rw-r--r-- | drivers/ide/Makefile | 103 | ||||
-rw-r--r-- | drivers/ide/aec62xx.c (renamed from drivers/ide/pci/aec62xx.c) | 0 | ||||
-rw-r--r-- | drivers/ide/ali14xx.c (renamed from drivers/ide/legacy/ali14xx.c) | 0 | ||||
-rw-r--r-- | drivers/ide/alim15x3.c (renamed from drivers/ide/pci/alim15x3.c) | 2 | ||||
-rw-r--r-- | drivers/ide/amd74xx.c (renamed from drivers/ide/pci/amd74xx.c) | 0 | ||||
-rw-r--r-- | drivers/ide/arm/Makefile | 10 | ||||
-rw-r--r-- | drivers/ide/atiixp.c (renamed from drivers/ide/pci/atiixp.c) | 0 | ||||
-rw-r--r-- | drivers/ide/au1xxx-ide.c (renamed from drivers/ide/mips/au1xxx-ide.c) | 0 | ||||
-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) | 0 | ||||
-rw-r--r-- | drivers/ide/cmd64x.c (renamed from drivers/ide/pci/cmd64x.c) | 0 | ||||
-rw-r--r-- | drivers/ide/cs5520.c (renamed from drivers/ide/pci/cs5520.c) | 0 | ||||
-rw-r--r-- | drivers/ide/cs5530.c (renamed from drivers/ide/pci/cs5530.c) | 0 | ||||
-rw-r--r-- | drivers/ide/cs5535.c (renamed from drivers/ide/pci/cs5535.c) | 0 | ||||
-rw-r--r-- | drivers/ide/cy82c693.c (renamed from drivers/ide/pci/cy82c693.c) | 0 | ||||
-rw-r--r-- | drivers/ide/delkin_cb.c (renamed from drivers/ide/pci/delkin_cb.c) | 63 | ||||
-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/h8300/Makefile | 2 | ||||
-rw-r--r-- | drivers/ide/hpt366.c (renamed from drivers/ide/pci/hpt366.c) | 37 | ||||
-rw-r--r-- | drivers/ide/ht6560b.c (renamed from drivers/ide/legacy/ht6560b.c) | 0 | ||||
-rw-r--r-- | drivers/ide/icside.c (renamed from drivers/ide/arm/icside.c) | 4 | ||||
-rw-r--r-- | drivers/ide/ide-4drives.c (renamed from drivers/ide/legacy/ide-4drives.c) | 0 | ||||
-rw-r--r-- | drivers/ide/ide-atapi.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-cd.c | 87 | ||||
-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) | 0 | ||||
-rw-r--r-- | drivers/ide/ide-disk.c | 392 | ||||
-rw-r--r-- | drivers/ide/ide-disk.h | 21 | ||||
-rw-r--r-- | drivers/ide/ide-disk_ioctl.c | 7 | ||||
-rw-r--r-- | drivers/ide/ide-disk_proc.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-dma-sff.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-floppy.c | 357 | ||||
-rw-r--r-- | drivers/ide/ide-floppy.h | 41 | ||||
-rw-r--r-- | drivers/ide/ide-floppy_ioctl.c | 36 | ||||
-rw-r--r-- | drivers/ide/ide-floppy_proc.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-gd.c | 401 | ||||
-rw-r--r-- | drivers/ide/ide-gd.h | 44 | ||||
-rw-r--r-- | drivers/ide/ide-h8300.c (renamed from drivers/ide/h8300/ide-h8300.c) | 0 | ||||
-rw-r--r-- | drivers/ide/ide-ioctls.c | 3 | ||||
-rw-r--r-- | drivers/ide/ide-iops.c | 4 | ||||
-rw-r--r-- | drivers/ide/ide-pci-generic.c (renamed from drivers/ide/pci/generic.c) | 2 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 1 | ||||
-rw-r--r-- | drivers/ide/ide-proc.c | 8 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 33 | ||||
-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) | 0 | ||||
-rw-r--r-- | drivers/ide/it821x.c (renamed from drivers/ide/pci/it821x.c) | 2 | ||||
-rw-r--r-- | drivers/ide/jmicron.c (renamed from drivers/ide/pci/jmicron.c) | 2 | ||||
-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) | 0 | ||||
-rw-r--r-- | drivers/ide/opti621.c (renamed from drivers/ide/pci/opti621.c) | 0 | ||||
-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) | 0 | ||||
-rw-r--r-- | drivers/ide/pdc202xx_old.c (renamed from drivers/ide/pci/pdc202xx_old.c) | 0 | ||||
-rw-r--r-- | drivers/ide/piix.c (renamed from drivers/ide/pci/piix.c) | 2 | ||||
-rw-r--r-- | drivers/ide/pmac.c (renamed from drivers/ide/ppc/pmac.c) | 0 | ||||
-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) | 0 | ||||
-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) | 4 | ||||
-rw-r--r-- | drivers/ide/rz1000.c (renamed from drivers/ide/pci/rz1000.c) | 0 | ||||
-rw-r--r-- | drivers/ide/sc1200.c (renamed from drivers/ide/pci/sc1200.c) | 0 | ||||
-rw-r--r-- | drivers/ide/scc_pata.c (renamed from drivers/ide/pci/scc_pata.c) | 16 | ||||
-rw-r--r-- | drivers/ide/serverworks.c (renamed from drivers/ide/pci/serverworks.c) | 0 | ||||
-rw-r--r-- | drivers/ide/sgiioc4.c (renamed from drivers/ide/pci/sgiioc4.c) | 73 | ||||
-rw-r--r-- | drivers/ide/siimage.c (renamed from drivers/ide/pci/siimage.c) | 4 | ||||
-rw-r--r-- | drivers/ide/sis5513.c (renamed from drivers/ide/pci/sis5513.c) | 0 | ||||
-rw-r--r-- | drivers/ide/sl82c105.c (renamed from drivers/ide/pci/sl82c105.c) | 0 | ||||
-rw-r--r-- | drivers/ide/slc90e66.c (renamed from drivers/ide/pci/slc90e66.c) | 0 | ||||
-rw-r--r-- | drivers/ide/tc86c001.c (renamed from drivers/ide/pci/tc86c001.c) | 0 | ||||
-rw-r--r-- | drivers/ide/triflex.c (renamed from drivers/ide/pci/triflex.c) | 0 | ||||
-rw-r--r-- | drivers/ide/trm290.c (renamed from drivers/ide/pci/trm290.c) | 0 | ||||
-rw-r--r-- | drivers/ide/tx4938ide.c | 323 | ||||
-rw-r--r-- | drivers/ide/tx4939ide.c | 754 | ||||
-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) | 0 |
85 files changed, 1983 insertions, 1236 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 74a369a6116f..6d7401772a8f 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -84,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 @@ -163,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 @@ -332,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 @@ -482,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 @@ -746,6 +720,16 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ default "128" depends on BLK_DEV_IDE_AU1XXX +config BLK_DEV_IDE_TX4938 + tristate "TX4938 internal IDE support" + depends on SOC_TX4938 + select IDE_TIMINGS + +config BLK_DEV_IDE_TX4939 + tristate "TX4939 internal IDE support" + depends on SOC_TX4939 + select BLK_DEV_IDEDMA_SFF + config IDE_ARM tristate "ARM IDE support" depends on ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index ceaf779054ea..7818d402b188 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -18,47 +18,98 @@ ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.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_IDE) += legacy/ pci/ +# Must appear at the end of the block +obj-$(CONFIG_BLK_DEV_GENERIC) += ide-pci-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_IDE) += ppc/ -obj-$(CONFIG_IDE_H8300) += h8300/ obj-$(CONFIG_IDE_GENERIC) += ide-generic.o obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o -ide-disk_mod-y += ide-disk.o ide-disk_ioctl.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 +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-disk_mod-y += ide-disk_proc.o - ide-floppy_mod-y += ide-floppy_proc.o + ide-gd_mod-y += ide-floppy_proc.o +endif endif -obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk_mod.o +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_AU1XXX) += au1xxx-ide.o -obj-$(CONFIG_IDE) += arm/ mips/ +obj-$(CONFIG_BLK_DEV_IDE_TX4938) += tx4938ide.o +obj-$(CONFIG_BLK_DEV_IDE_TX4939) += tx4939ide.o diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/aec62xx.c index 4142c698e0d3..4142c698e0d3 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/aec62xx.c diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/ali14xx.c index 90da1f953ed0..90da1f953ed0 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/ali14xx.c diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/alim15x3.c index daf9dce39e52..e56c7b72f9e2 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -5,7 +5,7 @@ * * Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org) * May be copied or modified under the terms of the GNU General Public License - * Copyright (C) 2002 Alan Cox <alan@redhat.com> + * Copyright (C) 2002 Alan Cox * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> * Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/amd74xx.c index 81ec73134eda..81ec73134eda 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/amd74xx.c diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile deleted file mode 100644 index 5bc26053afa6..000000000000 --- 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 b2735d28f5cc..b2735d28f5cc 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/atiixp.c diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c index 0ec8fd1e4dcb..0ec8fd1e4dcb 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/au1xxx-ide.c diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/buddha.c index c5a3c9ef6a5d..c5a3c9ef6a5d 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 e4306647d00d..e4306647d00d 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/cmd640.c diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/cmd64x.c index 935385c77e06..935385c77e06 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/cmd64x.c diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/cs5520.c index 5efb467f8fa0..5efb467f8fa0 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/cs5520.c diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/cs5530.c index 53f079cc00af..53f079cc00af 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/cs5530.c diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/cs5535.c index 983d957a0189..983d957a0189 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/cs5535.c diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/cy82c693.c index 5297f07d2933..5297f07d2933 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/cy82c693.c diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/delkin_cb.c index 8689a706f537..8f1b2d9f0513 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}, @@ -122,6 +169,8 @@ static struct pci_driver delkin_cb_pci_driver = { .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) diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/dtc2278.c index 689b2e493413..689b2e493413 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 39d500d84b07..39d500d84b07 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 691506886561..691506886561 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/gayle.c diff --git a/drivers/ide/h8300/Makefile b/drivers/ide/h8300/Makefile deleted file mode 100644 index 5eba16f423f4..000000000000 --- 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 9cf171cb9376..f5afd46ed51c 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 @@ -52,7 +52,7 @@ * different clocks on read/write. This requires overloading rw_disk and * other deeply crazy things. Thanks to <http://www.hoerstreich.de> for * keeping me sane. - * Alan Cox <alan@redhat.com> + * Alan Cox <alan@lxorguk.ukuu.org.uk> * * - fix the clock turnaround code: it was writing to the wrong ports when * called for the secondary channel, caching the current clock mode per- @@ -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); } /* @@ -1289,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; diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/ht6560b.c index c7e5c2246b79..c7e5c2246b79 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/ht6560b.c diff --git a/drivers/ide/arm/icside.c b/drivers/ide/icside.c index 76bdc9a27f6f..2d848010499d 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/icside.c @@ -690,9 +690,9 @@ static int __init icside_init(void) return ecard_register_driver(&icside_driver); } -static void __exit icside_exit(void); +static void __exit icside_exit(void) { - ecard_unregister_driver(&icside_driver); + ecard_remove_driver(&icside_driver); } MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/ide-4drives.c index 9e85b1ec9607..9e85b1ec9607 100644 --- a/drivers/ide/legacy/ide-4drives.c +++ b/drivers/ide/ide-4drives.c diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 2e305714c209..4e58b9e7a58a 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -191,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); diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3308b1cd3a33..42ab6d8715f2 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -99,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; } @@ -340,8 +340,8 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) } ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " - "rq->cmd_type: 0x%x, err: 0x%x\n", __func__, stat, - good_stat, rq->cmd_type, err); + "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)) { /* @@ -843,13 +843,10 @@ static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) rq->q->prep_rq_fn(rq->q, rq); } -/* - * All other packet commands. - */ static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) { - - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + 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, @@ -876,7 +873,7 @@ 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, rq->cmd[0]: 0x%x, write: 0x%x, " + 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); @@ -1177,8 +1174,9 @@ 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, write: 0x%x, secs_per_frame: %u\n", - __func__, write, sectors_per_frame); + 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 */ @@ -1221,7 +1219,8 @@ 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) { - ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd_type: 0x%x\n", __func__, + 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)) @@ -1251,15 +1250,13 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) * separate masks. */ alignment = queue_dma_alignment(q) | q->dma_pad_mask; - if ((unsigned long)buf & alignment || rq->data_len & alignment + if ((unsigned long)buf & alignment + || rq->data_len & q->dma_pad_mask || object_is_on_stack(buf)) 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) { @@ -1267,8 +1264,10 @@ 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_type: 0x%x, block: %llu\n", - __func__, rq->cmd_type, (unsigned long long)block); + 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) { @@ -1412,6 +1411,10 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, *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; } @@ -1643,6 +1646,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; } @@ -1732,7 +1738,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) @@ -1777,7 +1783,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", @@ -1908,6 +1914,16 @@ 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[] = { @@ -1951,6 +1967,7 @@ static const struct cd_list_entry ide_cd_quirks_list[] = { { "Optiarc DVD RW AD-5200A", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, { "Optiarc DVD RW AD-7200A", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, { "Optiarc DVD RW AD-7543A", NULL, IDE_AFLAG_NO_AUTOCLOSE }, + { "TEAC CD-ROM CD-224E", NULL, IDE_AFLAG_NO_AUTOCLOSE }, { NULL, NULL, 0 } }; @@ -1986,8 +2003,8 @@ static int ide_cdrom_setup(ide_drive_t *drive) if (!drive->queue->unplug_delay) drive->queue->unplug_delay = 1; - drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT | - ide_cd_flags(id); + 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') @@ -2069,22 +2086,20 @@ static ide_driver_t ide_cdrom_driver = { .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 }; -static int idecd_open(struct inode *inode, struct file *file) +static int idecd_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct cdrom_info *info; + struct cdrom_info *info = ide_cd_get(bdev->bd_disk); int rc = -ENOMEM; - info = ide_cd_get(disk); if (!info) return -ENXIO; - rc = cdrom_open(&info->devinfo, inode, file); + rc = cdrom_open(&info->devinfo, bdev, mode); if (rc < 0) ide_cd_put(info); @@ -2092,12 +2107,11 @@ static int idecd_open(struct inode *inode, struct file *file) return rc; } -static int idecd_release(struct inode *inode, struct file *file) +static int idecd_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct cdrom_info *info = ide_drv_g(disk, cdrom_info); - cdrom_release(&info->devinfo, file); + cdrom_release(&info->devinfo, mode); ide_cd_put(info); @@ -2143,10 +2157,9 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg) return 0; } -static int idecd_ioctl(struct inode *inode, struct file *file, +static int idecd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); int err; @@ -2159,9 +2172,9 @@ static int idecd_ioctl(struct inode *inode, struct file *file, break; } - err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg); + err = generic_ide_ioctl(info->drive, bdev, cmd, arg); if (err == -EINVAL) - err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg); + err = cdrom_ioctl(&info->devinfo, bdev, mode, cmd, arg); return err; } @@ -2186,7 +2199,7 @@ static struct block_device_operations idecd_ops = { .owner = THIS_MODULE, .open = idecd_open, .release = idecd_release, - .ioctl = idecd_ioctl, + .locked_ioctl = idecd_ioctl, .media_changed = idecd_media_changed, .revalidate_disk = idecd_revalidate_disk }; diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index 74231b41f611..df3df0041eb6 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 cb199c815b53..cb199c815b53 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/ide-cs.c diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 3853bde8eedc..eb9fac4d0f0c 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -2,7 +2,7 @@ * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) * Copyright (C) 1998-2002 Linux ATA Development * Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat <alan@redhat.com> + * Copyright (C) 2003 Red Hat * Copyright (C) 2003-2005, 2007 Bartlomiej Zolnierkiewicz */ @@ -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,46 +36,8 @@ #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 - #include "ide-disk.h" -static DEFINE_MUTEX(idedisk_ref_mutex); - -#define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref) - -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); -} - static const u8 ide_rw_cmds[] = { ATA_CMD_READ_MULTI, ATA_CMD_WRITE_MULTI, @@ -374,7 +333,7 @@ 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; int lba; @@ -403,11 +362,28 @@ static void init_idedisk_capacity(ide_drive_t *drive) if (ata_id_hpa_enabled(id)) idedisk_check_hpa(drive); } -} -sector_t ide_disk_capacity(ide_drive_t *drive) -{ - return drive->capacity64; + /* 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; + } + + 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; + } + + return 0; } static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) @@ -508,7 +484,7 @@ 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 = ide_disk_capacity(drive); + 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 || @@ -616,9 +592,15 @@ 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; + struct request_queue *q = drive->queue; ide_hwif_t *hwif = drive->hwif; u16 *id = drive->id; char *m = (char *)&id[ATA_ID_PROD]; @@ -645,40 +627,23 @@ static void idedisk_setup(ide_drive_t *drive) if (max_s > hwif->rqsize) max_s = hwif->rqsize; - blk_queue_max_sectors(drive->queue, max_s); + blk_queue_max_sectors(q, max_s); } printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name, - drive->queue->max_sectors / 2); + q->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->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; - } + if (ata_id_is_ssd(id) || ata_id_is_cfa(id)) + queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q); - if ((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; - } + /* calculate drive capacity, and select LBA if possible */ + ide_disk_get_capacity(drive); /* * if possible, give fdisk access to more of the drive, * by correcting bios_cyls: */ - capacity = ide_disk_capacity(drive); + capacity = ide_gd_capacity(drive); if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) { if (ata_id_lba48_enabled(drive->id)) { @@ -718,9 +683,17 @@ static void idedisk_setup(ide_drive_t *drive) 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 (ata_id_flush_enabled(drive->id) == 0 || (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) @@ -730,267 +703,40 @@ static void ide_cacheflush_p(ide_drive_t *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, - .do_request = ide_do_rw_disk, - .end_request = ide_end_request, - .error = __ide_error, -#ifdef CONFIG_IDE_PROC_FS - .proc = ide_disk_proc, - .settings = ide_disk_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->dev_flags & IDE_DFLAG_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->dev_flags & IDE_DFLAG_DOORLOCKING) && - idedisk_set_doorlock(drive, 1)) - drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; - } - 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->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { - if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) && - idedisk_set_doorlock(drive, 0)) - drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; - } - - idkp->openers--; - - ide_disk_put(idkp); - - 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 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->dev_flags & IDE_DFLAG_ATTACH) { - drive->dev_flags &= ~IDE_DFLAG_ATTACH; - return 0; - } + ret = ide_no_data_taskfile(drive, &task); - /* if removable, always assume it was changed */ - return !!(drive->dev_flags & IDE_DFLAG_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, ide_disk_capacity(idkp->drive)); - return 0; + return ret; } -static struct block_device_operations idedisk_ops = { - .owner = THIS_MODULE, - .open = idedisk_open, - .release = idedisk_release, - .ioctl = ide_disk_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->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; - - 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; - set_capacity(g, ide_disk_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_ALIAS("ide-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 index a82fa4355665..d511dab7c4aa 100644 --- a/drivers/ide/ide-disk.h +++ b/drivers/ide/ide-disk.h @@ -1,19 +1,11 @@ #ifndef __IDE_DISK_H #define __IDE_DISK_H -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 */ -}; - -#define ide_disk_g(disk) \ - container_of((disk)->private_data, struct ide_disk_obj, driver) +#include "ide-gd.h" +#ifdef CONFIG_IDE_GD_ATA /* ide-disk.c */ -sector_t ide_disk_capacity(ide_drive_t *); +extern const struct ide_disk_ops ide_ata_disk_ops; ide_decl_devset(address); ide_decl_devset(multcount); ide_decl_devset(nowerr); @@ -21,12 +13,17 @@ ide_decl_devset(wcache); ide_decl_devset(acoustic); /* ide-disk_ioctl.c */ -int ide_disk_ioctl(struct inode *, struct file *, unsigned int, unsigned long); +int ide_disk_ioctl(ide_drive_t *, struct block_device *, fmode_t, 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 index a6cf1a03a806..7b783dd7c0be 100644 --- a/drivers/ide/ide-disk_ioctl.c +++ b/drivers/ide/ide-disk_ioctl.c @@ -13,17 +13,14 @@ static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { { 0 } }; -int ide_disk_ioctl(struct inode *inode, struct file *file, +int ide_disk_ioctl(ide_drive_t *drive, struct block_device *bdev, fmode_t mode, 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); + return generic_ide_ioctl(drive, bdev, cmd, arg); } diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c index 4724976afe71..1146f4204c6e 100644 --- a/drivers/ide/ide-disk_proc.c +++ b/drivers/ide/ide-disk_proc.c @@ -56,7 +56,7 @@ static int proc_idedisk_read_capacity ide_drive_t*drive = (ide_drive_t *)data; int len; - len = sprintf(page, "%llu\n", (long long)ide_disk_capacity(drive)); + len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive)); PROC_IDE_READ_RETURN(page, start, off, count, eof, len); } diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c index 0903782689e9..cac431f0df17 100644 --- a/drivers/ide/ide-dma-sff.c +++ b/drivers/ide/ide-dma-sff.c @@ -130,7 +130,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq) xcount = bcount & 0xffff; if (is_trm290) xcount = ((xcount >> 2) - 1) << 16; - if (xcount == 0x0000) { + else if (xcount == 0x0000) { if (count++ >= PRD_ENTRIES) goto use_pio_instead; *table++ = cpu_to_le32(0x8000); diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index cf0aa25470ee..aeb1ad782f54 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -15,12 +15,6 @@ * Documentation/ide/ChangeLog.ide-floppy.1996-2002 */ -#define DRV_NAME "ide-floppy" -#define PFX DRV_NAME ": " - -#define IDEFLOPPY_VERSION "1.00" - -#include <linux/module.h> #include <linux/types.h> #include <linux/string.h> #include <linux/kernel.h> @@ -49,19 +43,6 @@ #include "ide-floppy.h" -/* module parameters */ -static unsigned long debug_mask; -module_param(debug_mask, ulong, 0644); - -/* define to see debug info */ -#define IDEFLOPPY_DEBUG_LOG 0 - -#if IDEFLOPPY_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 - /* * After each failed packet command we issue a request sense command and retry * the packet command IDEFLOPPY_MAX_PC_RETRIES times. @@ -83,43 +64,13 @@ module_param(debug_mask, ulong, 0644); /* Error code returned in rq->errors to the higher part of the driver. */ #define IDEFLOPPY_ERROR_GENERAL 101 -static DEFINE_MUTEX(idefloppy_ref_mutex); - -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_drv_g(disk, ide_floppy_obj); - 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; @@ -161,12 +112,12 @@ 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, int dsc) { - idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_disk_obj *floppy = drive->driver_data; struct ide_atapi_pc *pc = drive->pc; int uptodate = pc->error ? 0 : 1; @@ -200,10 +151,10 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc) "Aborting request!\n"); } - idefloppy_end_request(drive, uptodate, 0); + 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 */ @@ -222,7 +173,7 @@ 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) @@ -286,7 +237,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc, struct request *rq, unsigned long sector) { - idefloppy_floppy_t *floppy = drive->driver_data; + 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); @@ -310,7 +261,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, 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); @@ -329,13 +280,12 @@ 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; ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " "errors: %d\n", @@ -353,7 +303,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, else printk(KERN_ERR PFX "%s: I/O error\n", drive->name); - idefloppy_end_request(drive, 0, 0); + ide_floppy_end_request(drive, 0, 0); return ide_stopped; } if (blk_fs_request(rq)) { @@ -361,11 +311,11 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, (rq->nr_sectors % floppy->bs_factor)) { printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", drive->name); - idefloppy_end_request(drive, 0, 0); + ide_floppy_end_request(drive, 0, 0); return ide_stopped; } pc = &floppy->queued_pc; - idefloppy_create_rw_cmd(drive, 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)) { @@ -373,7 +323,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, idefloppy_blockpc_cmd(floppy, pc, rq); } else { blk_dump_rq_flags(rq, PFX "unsupported command in queue"); - idefloppy_end_request(drive, 0, 0); + ide_floppy_end_request(drive, 0, 0); return ide_stopped; } @@ -394,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; @@ -410,11 +360,11 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) } 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]; @@ -445,7 +395,9 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) drive->name, lba_capacity, capacity); floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0; + drive->capacity64 = floppy->blocks * floppy->bs_factor; } + return 0; } @@ -455,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; @@ -466,7 +418,7 @@ 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)) { @@ -523,6 +475,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) "non 512 bytes block size not " "fully supported\n", drive->name); + drive->capacity64 = + floppy->blocks * floppy->bs_factor; rc = 0; } break; @@ -547,21 +501,12 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) 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; } -sector_t ide_floppy_capacity(ide_drive_t *drive) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - unsigned long capacity = floppy->blocks * floppy->bs_factor; - - return capacity; -} - -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; drive->pc_callback = ide_floppy_callback; @@ -592,252 +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_drv(kref, ide_floppy_obj); - ide_drive_t *drive = floppy->drive; - struct gendisk *g = floppy->disk; - - drive->driver_data = NULL; - g->private_data = NULL; - put_disk(g); - kfree(floppy); } -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, - .do_request = idefloppy_do_request, - .end_request = idefloppy_end_request, - .error = __ide_error, -#ifdef CONFIG_IDE_PROC_FS - .proc = ide_floppy_proc, - .settings = ide_floppy_settings, -#endif -}; - -static int idefloppy_open(struct inode *inode, struct file *filp) +static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_floppy_obj *floppy; - ide_drive_t *drive; int ret = 0; - floppy = ide_floppy_get(disk); - if (!floppy) - return -ENXIO; - - drive = floppy->drive; - - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - - 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 ((drive->atapi_flags & IDE_AFLAG_WP) && (filp->f_mode & 2)) { - ret = -EROFS; - goto out_put_floppy; - } - - 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; - -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_drv_g(disk, ide_floppy_obj); - ide_drive_t *drive = floppy->drive; - - ide_debug_log(IDE_DBG_FUNC, "Call %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_drv_g(bdev->bd_disk, - ide_floppy_obj); - ide_drive_t *drive = floppy->drive; + if (ide_do_test_unit_ready(drive, disk)) + ide_do_start_stop(drive, disk, 1); - geo->heads = drive->bios_head; - geo->sectors = drive->bios_sect; - geo->cylinders = (u16)drive->bios_cyl; /* truncate */ - return 0; -} + ret = ide_floppy_get_capacity(drive); -static int idefloppy_media_changed(struct gendisk *disk) -{ - struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); - ide_drive_t *drive = floppy->drive; - int ret; + set_capacity(disk, ide_gd_capacity(drive)); - /* 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->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_drv_g(disk, ide_floppy_obj); - set_capacity(disk, ide_floppy_capacity(floppy->drive)); - return 0; -} - -static struct block_device_operations idefloppy_ops = { - .owner = THIS_MODULE, - .open = idefloppy_open, - .release = idefloppy_release, - .ioctl = ide_floppy_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 PFX "%s: not supported by this version of " - DRV_NAME "\n", drive->name); - goto failed; - } - floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); - if (!floppy) { - printk(KERN_ERR PFX "%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; - - drive->debug_mask = debug_mask; - - idefloppy_setup(drive, floppy); - drive->dev_flags |= IDE_DFLAG_ATTACH; - - g->minors = 1 << PARTN_BITS; - g->driverfs_dev = &drive->gendev; - if (drive->dev_flags & IDE_DFLAG_REMOVABLE) - g->flags = GENHD_FL_REMOVABLE; - g->fops = &idefloppy_ops; - 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(KERN_INFO DRV_NAME " 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 17cf865e583d..6dd2beb48434 100644 --- a/drivers/ide/ide-floppy.h +++ b/drivers/ide/ide-floppy.h @@ -1,37 +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 */ - - /* 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]; -} 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. @@ -46,17 +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 *); -sector_t ide_floppy_capacity(ide_drive_t *); /* ide-floppy_ioctl.c */ -int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long); +int ide_floppy_ioctl(ide_drive_t *, struct block_device *, fmode_t, + 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 a3a7a0809e2b..2bc51ff73fee 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,7 +190,7 @@ 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; @@ -226,7 +226,7 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) 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 ide_disk_obj *floppy = drive->driver_data; struct gendisk *disk = floppy->disk; int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; @@ -241,7 +241,7 @@ static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, return 0; } -static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, +static int ide_floppy_format_ioctl(ide_drive_t *drive, fmode_t mode, unsigned int cmd, void __user *argp) { switch (cmd) { @@ -250,7 +250,7 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY: return ide_floppy_get_format_capacities(drive, argp); case IDEFLOPPY_IOCTL_FORMAT_START: - if (!(file->f_mode & 2)) + if (!(mode & FMODE_WRITE)) return -EPERM; return ide_floppy_format_unit(drive, (int __user *)argp); case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: @@ -260,13 +260,9 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, } } -int ide_floppy_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev, + fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; - struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk, - ide_floppy_obj); - ide_drive_t *drive = floppy->drive; struct ide_atapi_pc pc; void __user *argp = (void __user *)arg; int err; @@ -274,7 +270,7 @@ int ide_floppy_ioctl(struct inode *inode, struct file *file, if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) return ide_floppy_lockdoor(drive, &pc, arg, cmd); - err = ide_floppy_format_ioctl(drive, file, cmd, argp); + err = ide_floppy_format_ioctl(drive, mode, cmd, argp); if (err != -ENOTTY) return err; @@ -283,11 +279,11 @@ int ide_floppy_ioctl(struct inode *inode, struct file *file, * 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); + err = scsi_cmd_ioctl(bdev->bd_disk->queue, bdev->bd_disk, + mode, cmd, argp); if (err == -ENOTTY) - err = generic_ide_ioctl(drive, file, bdev, cmd, arg); + err = generic_ide_ioctl(drive, bdev, cmd, arg); return err; } diff --git a/drivers/ide/ide-floppy_proc.c b/drivers/ide/ide-floppy_proc.c index 76f0c6c4eca3..3ec762cb60ab 100644 --- a/drivers/ide/ide-floppy_proc.c +++ b/drivers/ide/ide-floppy_proc.c @@ -9,7 +9,7 @@ static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, ide_drive_t*drive = (ide_drive_t *)data; int len; - len = sprintf(page, "%llu\n", (long long)ide_floppy_capacity(drive)); + len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive)); PROC_IDE_READ_RETURN(page, start, off, count, eof, len); } diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c new file mode 100644 index 000000000000..b8078b3231f7 --- /dev/null +++ b/drivers/ide/ide-gd.c @@ -0,0 +1,401 @@ +#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 block_device *bdev, fmode_t mode) +{ + struct gendisk *disk = 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 && (mode & FMODE_NDELAY) == 0) { + ret = -EIO; + goto out_put_idkp; + } + + if ((drive->dev_flags & IDE_DFLAG_WP) && (mode & FMODE_WRITE)) { + 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(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 gendisk *disk, fmode_t mode) +{ + 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); + ide_drive_t *drive = idkp->drive; + + if (ide_gd_media_changed(disk)) + drive->disk_ops->get_capacity(drive); + + set_capacity(disk, ide_gd_capacity(drive)); + return 0; +} + +static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) +{ + 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, bdev, mode, cmd, arg); +} + +static struct block_device_operations ide_gd_ops = { + .owner = THIS_MODULE, + .open = ide_gd_open, + .release = ide_gd_release, + .locked_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 000000000000..7d3d101713e0 --- /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/h8300/ide-h8300.c b/drivers/ide/ide-h8300.c index e2cdd2e9cdec..e2cdd2e9cdec 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/ide-h8300.c diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index a90945f49792..fcde16bb53a7 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -240,8 +240,7 @@ static int generic_drive_reset(ide_drive_t *drive) return ret; } -int generic_ide_ioctl(ide_drive_t *drive, struct file *file, - struct block_device *bdev, +int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev, unsigned int cmd, unsigned long arg) { int err; diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index b762deb2dacb..5d6ba14e211d 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat <alan@redhat.com> + * Copyright (C) 2003 Red Hat * */ @@ -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); diff --git a/drivers/ide/pci/generic.c b/drivers/ide/ide-pci-generic.c index 474f96a7c076..bddae2b329a0 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/ide-pci-generic.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> - * Portions (C) Copyright 2002 Red Hat Inc <alan@redhat.com> + * Portions (C) Copyright 2002 Red Hat Inc * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 19f8c7770a25..1649ea54f76c 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -208,6 +208,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) 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; diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index b26926487cc0..f3cddd1b2f8f 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1997-1998 Mark Lord - * Copyright (C) 2003 Red Hat <alan@redhat.com> + * Copyright (C) 2003 Red Hat * * Some code was moved here from ide.c, see it for original copyrights. */ @@ -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); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d879c7797cde..a2d470eb2b55 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -2108,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; @@ -2298,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 *); @@ -2315,8 +2325,8 @@ static ide_driver_t idetape_driver = { .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 }; @@ -2330,35 +2340,30 @@ static const struct file_operations idetape_fops = { .release = idetape_chrdev_release, }; -static int idetape_open(struct inode *inode, struct file *filp) +static int idetape_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_tape_obj *tape; + struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk); - tape = ide_tape_get(disk); if (!tape) return -ENXIO; return 0; } -static int idetape_release(struct inode *inode, struct file *filp) +static int idetape_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj); ide_tape_put(tape); - return 0; } -static int idetape_ioctl(struct inode *inode, struct file *file, +static int idetape_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; 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); + int err = generic_ide_ioctl(drive, bdev, cmd, arg); if (err == -EINVAL) err = idetape_blkdev_ioctl(drive, cmd, arg); return err; @@ -2368,7 +2373,7 @@ static struct block_device_operations idetape_block_ops = { .owner = THIS_MODULE, .open = idetape_open, .release = idetape_release, - .ioctl = idetape_ioctl, + .locked_ioctl = idetape_ioctl, }; static int ide_tape_probe(ide_drive_t *drive) diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/ide_arm.c index f728f2927b5a..f728f2927b5a 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 051b4ab0f359..051b4ab0f359 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 7c2feeb3c5ec..7c2feeb3c5ec 100644 --- a/drivers/ide/pci/it8213.c +++ b/drivers/ide/it8213.c diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/it821x.c index 995e18bb3139..ef004089761b 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/it821x.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Red Hat <alan@redhat.com> + * Copyright (C) 2004 Red Hat * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public License diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/jmicron.c index 9a68433cf46d..bf2be6431b20 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/jmicron.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2006 Red Hat <alan@redhat.com> + * Copyright (C) 2006 Red Hat * * May be copied or modified under the terms of the GNU General Public License */ diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile deleted file mode 100644 index 6939329f89e8..000000000000 --- 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 43f97cc1d30e..43f97cc1d30e 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 5873fa0b8769..000000000000 --- 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 13789060f407..13789060f407 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/ns87415.c diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/opti621.c index 6048eda3cd61..6048eda3cd61 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/opti621.c diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/palm_bk3710.c index 122ed3c072fd..122ed3c072fd 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 02e6ee7d751d..000000000000 --- 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 fb1a3aa57f07..000000000000 --- 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 hpt34x_pci_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(&hpt34x_pci_driver); -} - -static void __exit hpt34x_ide_exit(void) -{ - pci_unregister_driver(&hpt34x_pci_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 211ae46e3e0c..211ae46e3e0c 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pdc202xx_new.c diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index 799557c25eef..799557c25eef 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c diff --git a/drivers/ide/pci/piix.c b/drivers/ide/piix.c index d63f9fdca76b..61d2d920a5cd 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/piix.c @@ -1,7 +1,7 @@ /* * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> + * Copyright (C) 2003 Red Hat * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> * * May be copied or modified under the terms of the GNU General Public License diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/pmac.c index 2e19d6298536..2e19d6298536 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/pmac.c diff --git a/drivers/ide/ppc/Makefile b/drivers/ide/ppc/Makefile deleted file mode 100644 index 74e52adcdf4b..000000000000 --- 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 4af4a8ce4cdf..4af4a8ce4cdf 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 bc27c7aba936..bc27c7aba936 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/qd65xx.c diff --git a/drivers/ide/legacy/qd65xx.h b/drivers/ide/qd65xx.h index c83dea85e621..c83dea85e621 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 78d27d9ae430..d5003ca69801 100644 --- a/drivers/ide/arm/rapide.c +++ b/drivers/ide/rapide.c @@ -11,7 +11,7 @@ #include <asm/ecard.h> -static struct const ide_port_info rapide_port_info = { +static const struct ide_port_info rapide_port_info = { .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, }; @@ -97,7 +97,7 @@ static int __init rapide_init(void) static void __exit rapide_exit(void) { - ecard_unregister_driver(&rapide_driver); + ecard_remove_driver(&rapide_driver); } MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/rz1000.c index 7daf0135cbac..7daf0135cbac 100644 --- a/drivers/ide/pci/rz1000.c +++ b/drivers/ide/rz1000.c diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/sc1200.c index f1a8758e3a99..f1a8758e3a99 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/sc1200.c diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/scc_pata.c index 9ce1d8059921..0f48f9dacfa5 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/scc_pata.c @@ -5,7 +5,7 @@ * * This code is based on drivers/ide/pci/siimage.c: * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat <alan@redhat.com> + * Copyright (C) 2003 Red Hat * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -536,10 +536,6 @@ static u8 scc_udma_filter(ide_drive_t *drive) static int setup_mmio_scc (struct pci_dev *dev, const char *name) { - unsigned long ctl_base = pci_resource_start(dev, 0); - unsigned long dma_base = pci_resource_start(dev, 1); - unsigned long ctl_size = pci_resource_len(dev, 0); - unsigned long dma_size = pci_resource_len(dev, 1); void __iomem *ctl_addr; void __iomem *dma_addr; int i, ret; @@ -557,10 +553,12 @@ static int setup_mmio_scc (struct pci_dev *dev, const char *name) return ret; } - if ((ctl_addr = ioremap(ctl_base, ctl_size)) == NULL) + ctl_addr = pci_ioremap_bar(dev, 0); + if (!ctl_addr) goto fail_0; - if ((dma_addr = ioremap(dma_base, dma_size)) == NULL) + dma_addr = pci_ioremap_bar(dev, 1); + if (!dma_addr) goto fail_1; pci_set_master(dev); @@ -617,7 +615,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; @@ -637,7 +634,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; @@ -843,8 +839,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); diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/serverworks.c index 437bc919dafd..437bc919dafd 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/serverworks.c diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/sgiioc4.c index dd634541ce36..7defa0ae2014 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/sgiioc4.c @@ -101,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 @@ -310,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 & ATA_BUSY)) { /* 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); } } @@ -332,13 +320,9 @@ 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); if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) { @@ -348,14 +332,8 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) 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->sg_max_nents = IOC4_PRD_ENTRIES; @@ -379,9 +357,6 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) 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; @@ -563,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 = { @@ -594,14 +567,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) unsigned long cmd_base, irqport; unsigned long bar0, cmd_phys_base, ctl; void __iomem *virt_base; - struct ide_host *host; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - struct ide_port_info d = sgiioc4_port_info; int rc; /* Get the CmdBlk and CtrlBlk Base Registers */ bar0 = pci_resource_start(dev, 0); - virt_base = ioremap(bar0, pci_resource_len(dev, 0)); + virt_base = pci_ioremap_bar(dev, 0); if (virt_base == NULL) { printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n", DRV_NAME, bar0); @@ -617,7 +588,8 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) 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; + rc = -EBUSY; + goto req_mem_rgn_err; } /* Initialize the IO registers */ @@ -630,21 +602,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) /* Initializing chipset IRQ Registers */ writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); - host = ide_host_alloc(&d, hws); - if (host == NULL) { - rc = -ENOMEM; - goto err; - } - - rc = ide_host_register(host, &d, hws); - if (rc) - goto err_free; + rc = ide_host_add(&sgiioc4_port_info, hws, NULL); + if (!rc) + return 0; - return 0; -err_free: - ide_host_free(host); -err: release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE); +req_mem_rgn_err: iounmap(virt_base); return rc; } diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/siimage.c index eb4faf92c571..7d622d20bc4c 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/siimage.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat <alan@redhat.com> + * Copyright (C) 2003 Red Hat * Copyright (C) 2007-2008 MontaVista Software, Inc. * Copyright (C) 2007-2008 Bartlomiej Zolnierkiewicz * @@ -784,7 +784,7 @@ static int __devinit siimage_init_one(struct pci_dev *dev, printk(KERN_WARNING DRV_NAME " %s: MMIO ports not " "available\n", pci_name(dev)); } else { - ioaddr = ioremap(bar5, barsize); + ioaddr = pci_ioremap_bar(dev, 5); if (ioaddr == NULL) release_mem_region(bar5, barsize); } diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/sis5513.c index ad32e18c5ba3..ad32e18c5ba3 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/sis5513.c diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/sl82c105.c index 84dc33602ff8..84dc33602ff8 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/sl82c105.c diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/slc90e66.c index 0f759e4ed779..0f759e4ed779 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/slc90e66.c diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/tc86c001.c index 93e2cce4b296..93e2cce4b296 100644 --- a/drivers/ide/pci/tc86c001.c +++ b/drivers/ide/tc86c001.c diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/triflex.c index b6ff40336aa9..b6ff40336aa9 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/triflex.c diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/trm290.c index 75ea61526566..75ea61526566 100644 --- a/drivers/ide/pci/trm290.c +++ b/drivers/ide/trm290.c diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c new file mode 100644 index 000000000000..9120063e8f87 --- /dev/null +++ b/drivers/ide/tx4938ide.c @@ -0,0 +1,323 @@ +/* + * TX4938 internal IDE driver + * Based on tx4939ide.c. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * (C) Copyright TOSHIBA CORPORATION 2005-2007 + */ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/ide.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <asm/txx9/tx4938.h> + +static void tx4938ide_tune_ebusc(unsigned int ebus_ch, + unsigned int gbus_clock, + u8 pio) +{ + struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); + u64 cr = __raw_readq(&tx4938_ebuscptr->cr[ebus_ch]); + unsigned int sp = (cr >> 4) & 3; + unsigned int clock = gbus_clock / (4 - sp); + unsigned int cycle = 1000000000 / clock; + unsigned int shwt; + int wt; + + /* Minimum DIOx- active time */ + wt = DIV_ROUND_UP(t->act8b, cycle) - 2; + /* IORDY setup time: 35ns */ + wt = max_t(int, wt, DIV_ROUND_UP(35, cycle)); + /* actual wait-cycle is max(wt & ~1, 1) */ + if (wt > 2 && (wt & 1)) + wt++; + wt &= ~1; + /* Address-valid to DIOR/DIOW setup */ + shwt = DIV_ROUND_UP(t->setup, cycle); + + /* -DIOx recovery time (SHWT * 4) and cycle time requirement */ + while ((shwt * 4 + wt + (wt ? 2 : 3)) * cycle < t->cycle) + shwt++; + if (shwt > 7) { + pr_warning("tx4938ide: SHWT violation (%d)\n", shwt); + shwt = 7; + } + pr_debug("tx4938ide: ebus %d, bus cycle %dns, WT %d, SHWT %d\n", + ebus_ch, cycle, wt, shwt); + + __raw_writeq((cr & ~0x3f007ull) | (wt << 12) | shwt, + &tx4938_ebuscptr->cr[ebus_ch]); +} + +static void tx4938ide_set_pio_mode(ide_drive_t *drive, const u8 pio) +{ + ide_hwif_t *hwif = drive->hwif; + struct tx4938ide_platform_info *pdata = hwif->dev->platform_data; + u8 safe = pio; + ide_drive_t *pair; + + pair = ide_get_pair_dev(drive); + if (pair) + safe = min(safe, ide_get_best_pio_mode(pair, 255, 5)); + tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, safe); +} + +#ifdef __BIG_ENDIAN + +/* custom iops (independent from SWAP_IO_SPACE) */ +static u8 tx4938ide_inb(unsigned long port) +{ + return __raw_readb((void __iomem *)port); +} + +static void tx4938ide_outb(u8 value, unsigned long port) +{ + __raw_writeb(value, (void __iomem *)port); +} + +static void tx4938ide_tf_load(ide_drive_t *drive, ide_task_t *task) +{ + ide_hwif_t *hwif = drive->hwif; + struct ide_io_ports *io_ports = &hwif->io_ports; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; + + if (task->tf_flags & IDE_TFLAG_FLAGGED) + HIHI = 0xFF; + + if (task->tf_flags & IDE_TFLAG_OUT_DATA) { + u16 data = (tf->hob_data << 8) | tf->data; + + /* no endian swap */ + __raw_writew(data, (void __iomem *)io_ports->data_addr); + } + + if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + tx4938ide_outb(tf->hob_feature, io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) + tx4938ide_outb(tf->hob_nsect, io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + tx4938ide_outb(tf->hob_lbal, io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + tx4938ide_outb(tf->hob_lbam, io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + tx4938ide_outb(tf->hob_lbah, io_ports->lbah_addr); + + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) + tx4938ide_outb(tf->feature, io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) + tx4938ide_outb(tf->nsect, io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) + tx4938ide_outb(tf->lbal, io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) + tx4938ide_outb(tf->lbam, io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) + tx4938ide_outb(tf->lbah, io_ports->lbah_addr); + + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) + tx4938ide_outb((tf->device & HIHI) | drive->select, + io_ports->device_addr); +} + +static void tx4938ide_tf_read(ide_drive_t *drive, ide_task_t *task) +{ + ide_hwif_t *hwif = drive->hwif; + struct ide_io_ports *io_ports = &hwif->io_ports; + struct ide_taskfile *tf = &task->tf; + + if (task->tf_flags & IDE_TFLAG_IN_DATA) { + u16 data; + + /* no endian swap */ + data = __raw_readw((void __iomem *)io_ports->data_addr); + tf->data = data & 0xff; + tf->hob_data = (data >> 8) & 0xff; + } + + /* be sure we're looking at the low order bits */ + tx4938ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) + tf->feature = tx4938ide_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_NSECT) + tf->nsect = tx4938ide_inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_LBAL) + tf->lbal = tx4938ide_inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_LBAM) + tf->lbam = tx4938ide_inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_LBAH) + tf->lbah = tx4938ide_inb(io_ports->lbah_addr); + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) + tf->device = tx4938ide_inb(io_ports->device_addr); + + if (task->tf_flags & IDE_TFLAG_LBA48) { + tx4938ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + tf->hob_feature = + tx4938ide_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr); + } +} + +static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq, + void *buf, unsigned int len) +{ + unsigned long port = drive->hwif->io_ports.data_addr; + unsigned short *ptr = buf; + unsigned int count = (len + 1) / 2; + + while (count--) + *ptr++ = cpu_to_le16(__raw_readw((void __iomem *)port)); + __ide_flush_dcache_range((unsigned long)buf, count * 2); +} + +static void tx4938ide_output_data_swap(ide_drive_t *drive, struct request *rq, + void *buf, unsigned int len) +{ + unsigned long port = drive->hwif->io_ports.data_addr; + unsigned short *ptr = buf; + unsigned int count = (len + 1) / 2; + + while (count--) { + __raw_writew(le16_to_cpu(*ptr), (void __iomem *)port); + ptr++; + } + __ide_flush_dcache_range((unsigned long)buf, count * 2); +} + +static const struct ide_tp_ops tx4938ide_tp_ops = { + .exec_command = ide_exec_command, + .read_status = ide_read_status, + .read_altstatus = ide_read_altstatus, + .read_sff_dma_status = ide_read_sff_dma_status, + + .set_irq = ide_set_irq, + + .tf_load = tx4938ide_tf_load, + .tf_read = tx4938ide_tf_read, + + .input_data = tx4938ide_input_data_swap, + .output_data = tx4938ide_output_data_swap, +}; + +#endif /* __BIG_ENDIAN */ + +static const struct ide_port_ops tx4938ide_port_ops = { + .set_pio_mode = tx4938ide_set_pio_mode, +}; + +static const struct ide_port_info tx4938ide_port_info __initdata = { + .port_ops = &tx4938ide_port_ops, +#ifdef __BIG_ENDIAN + .tp_ops = &tx4938ide_tp_ops, +#endif + .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, + .pio_mask = ATA_PIO5, +}; + +static int __init tx4938ide_probe(struct platform_device *pdev) +{ + hw_regs_t hw; + hw_regs_t *hws[] = { &hw, NULL, NULL, NULL }; + struct ide_host *host; + struct resource *res; + struct tx4938ide_platform_info *pdata = pdev->dev.platform_data; + int irq, ret, i; + unsigned long mapbase, mapctl; + struct ide_port_info d = tx4938ide_port_info; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -ENODEV; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + if (!devm_request_mem_region(&pdev->dev, res->start, + res->end - res->start + 1, "tx4938ide")) + return -EBUSY; + mapbase = (unsigned long)devm_ioremap(&pdev->dev, res->start, + 8 << pdata->ioport_shift); + mapctl = (unsigned long)devm_ioremap(&pdev->dev, + res->start + 0x10000 + + (6 << pdata->ioport_shift), + 1 << pdata->ioport_shift); + if (!mapbase || !mapctl) + return -EBUSY; + + memset(&hw, 0, sizeof(hw)); + if (pdata->ioport_shift) { + unsigned long port = mapbase; + unsigned long ctl = mapctl; + + hw.io_ports_array[0] = port; +#ifdef __BIG_ENDIAN + port++; + ctl++; +#endif + for (i = 1; i <= 7; i++) + hw.io_ports_array[i] = + port + (i << pdata->ioport_shift); + hw.io_ports.ctl_addr = ctl; + } else + ide_std_init_ports(&hw, mapbase, mapctl); + hw.irq = irq; + hw.dev = &pdev->dev; + + pr_info("TX4938 IDE interface (base %#lx, ctl %#lx, irq %d)\n", + mapbase, mapctl, hw.irq); + if (pdata->gbus_clock) + tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, 0); + else + d.port_ops = NULL; + ret = ide_host_add(&d, hws, &host); + if (!ret) + platform_set_drvdata(pdev, host); + return ret; +} + +static int __exit tx4938ide_remove(struct platform_device *pdev) +{ + struct ide_host *host = platform_get_drvdata(pdev); + + ide_host_remove(host); + return 0; +} + +static struct platform_driver tx4938ide_driver = { + .driver = { + .name = "tx4938ide", + .owner = THIS_MODULE, + }, + .remove = __exit_p(tx4938ide_remove), +}; + +static int __init tx4938ide_init(void) +{ + return platform_driver_probe(&tx4938ide_driver, tx4938ide_probe); +} + +static void __exit tx4938ide_exit(void) +{ + platform_driver_unregister(&tx4938ide_driver); +} + +module_init(tx4938ide_init); +module_exit(tx4938ide_exit); + +MODULE_DESCRIPTION("TX4938 internal IDE driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:tx4938ide"); diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c new file mode 100644 index 000000000000..bafb7d1a22e2 --- /dev/null +++ b/drivers/ide/tx4939ide.c @@ -0,0 +1,754 @@ +/* + * TX4939 internal IDE driver + * Based on RBTX49xx patch from CELF patch archive. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * (C) Copyright TOSHIBA CORPORATION 2005-2007 + */ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/ide.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/scatterlist.h> + +#define MODNAME "tx4939ide" + +/* ATA Shadow Registers (8-bit except for Data which is 16-bit) */ +#define TX4939IDE_Data 0x000 +#define TX4939IDE_Error_Feature 0x001 +#define TX4939IDE_Sec 0x002 +#define TX4939IDE_LBA0 0x003 +#define TX4939IDE_LBA1 0x004 +#define TX4939IDE_LBA2 0x005 +#define TX4939IDE_DevHead 0x006 +#define TX4939IDE_Stat_Cmd 0x007 +#define TX4939IDE_AltStat_DevCtl 0x402 +/* H/W DMA Registers */ +#define TX4939IDE_DMA_Cmd 0x800 /* 8-bit */ +#define TX4939IDE_DMA_Stat 0x802 /* 8-bit */ +#define TX4939IDE_PRD_Ptr 0x804 /* 32-bit */ +/* ATA100 CORE Registers (16-bit) */ +#define TX4939IDE_Sys_Ctl 0xc00 +#define TX4939IDE_Xfer_Cnt_1 0xc08 +#define TX4939IDE_Xfer_Cnt_2 0xc0a +#define TX4939IDE_Sec_Cnt 0xc10 +#define TX4939IDE_Start_Lo_Addr 0xc18 +#define TX4939IDE_Start_Up_Addr 0xc20 +#define TX4939IDE_Add_Ctl 0xc28 +#define TX4939IDE_Lo_Burst_Cnt 0xc30 +#define TX4939IDE_Up_Burst_Cnt 0xc38 +#define TX4939IDE_PIO_Addr 0xc88 +#define TX4939IDE_H_Rst_Tim 0xc90 +#define TX4939IDE_Int_Ctl 0xc98 +#define TX4939IDE_Pkt_Cmd 0xcb8 +#define TX4939IDE_Bxfer_Cnt_Hi 0xcc0 +#define TX4939IDE_Bxfer_Cnt_Lo 0xcc8 +#define TX4939IDE_Dev_TErr 0xcd0 +#define TX4939IDE_Pkt_Xfer_Ctl 0xcd8 +#define TX4939IDE_Start_TAddr 0xce0 + +/* bits for Int_Ctl */ +#define TX4939IDE_INT_ADDRERR 0x80 +#define TX4939IDE_INT_REACHMUL 0x40 +#define TX4939IDE_INT_DEVTIMING 0x20 +#define TX4939IDE_INT_UDMATERM 0x10 +#define TX4939IDE_INT_TIMER 0x08 +#define TX4939IDE_INT_BUSERR 0x04 +#define TX4939IDE_INT_XFEREND 0x02 +#define TX4939IDE_INT_HOST 0x01 + +#define TX4939IDE_IGNORE_INTS \ + (TX4939IDE_INT_ADDRERR | TX4939IDE_INT_REACHMUL | \ + TX4939IDE_INT_DEVTIMING | TX4939IDE_INT_UDMATERM | \ + TX4939IDE_INT_TIMER | TX4939IDE_INT_XFEREND) + +#ifdef __BIG_ENDIAN +#define tx4939ide_swizzlel(a) ((a) ^ 4) +#define tx4939ide_swizzlew(a) ((a) ^ 6) +#define tx4939ide_swizzleb(a) ((a) ^ 7) +#else +#define tx4939ide_swizzlel(a) (a) +#define tx4939ide_swizzlew(a) (a) +#define tx4939ide_swizzleb(a) (a) +#endif + +static u16 tx4939ide_readw(void __iomem *base, u32 reg) +{ + return __raw_readw(base + tx4939ide_swizzlew(reg)); +} +static u8 tx4939ide_readb(void __iomem *base, u32 reg) +{ + return __raw_readb(base + tx4939ide_swizzleb(reg)); +} +static void tx4939ide_writel(u32 val, void __iomem *base, u32 reg) +{ + __raw_writel(val, base + tx4939ide_swizzlel(reg)); +} +static void tx4939ide_writew(u16 val, void __iomem *base, u32 reg) +{ + __raw_writew(val, base + tx4939ide_swizzlew(reg)); +} +static void tx4939ide_writeb(u8 val, void __iomem *base, u32 reg) +{ + __raw_writeb(val, base + tx4939ide_swizzleb(reg)); +} + +#define TX4939IDE_BASE(hwif) ((void __iomem *)(hwif)->extra_base) + +static void tx4939ide_set_pio_mode(ide_drive_t *drive, const u8 pio) +{ + ide_hwif_t *hwif = drive->hwif; + int is_slave = drive->dn; + u32 mask, val; + u8 safe = pio; + ide_drive_t *pair; + + pair = ide_get_pair_dev(drive); + if (pair) + safe = min(safe, ide_get_best_pio_mode(pair, 255, 4)); + /* + * Update Command Transfer Mode for master/slave and Data + * Transfer Mode for this drive. + */ + mask = is_slave ? 0x07f00000 : 0x000007f0; + val = ((safe << 8) | (pio << 4)) << (is_slave ? 16 : 0); + hwif->select_data = (hwif->select_data & ~mask) | val; + /* tx4939ide_tf_load_fixup() will set the Sys_Ctl register */ +} + +static void tx4939ide_set_dma_mode(ide_drive_t *drive, const u8 mode) +{ + ide_hwif_t *hwif = drive->hwif; + u32 mask, val; + + /* Update Data Transfer Mode for this drive. */ + if (mode >= XFER_UDMA_0) + val = mode - XFER_UDMA_0 + 8; + else + val = mode - XFER_MW_DMA_0 + 5; + if (drive->dn) { + mask = 0x00f00000; + val <<= 20; + } else { + mask = 0x000000f0; + val <<= 4; + } + hwif->select_data = (hwif->select_data & ~mask) | val; + /* tx4939ide_tf_load_fixup() will set the Sys_Ctl register */ +} + +static u16 tx4939ide_check_error_ints(ide_hwif_t *hwif) +{ + void __iomem *base = TX4939IDE_BASE(hwif); + u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl); + + if (ctl & TX4939IDE_INT_BUSERR) { + /* reset FIFO */ + u16 sysctl = tx4939ide_readw(base, TX4939IDE_Sys_Ctl); + + tx4939ide_writew(sysctl | 0x4000, base, TX4939IDE_Sys_Ctl); + mmiowb(); + /* wait 12GBUSCLK (typ. 60ns @ GBUS200MHz, max 270ns) */ + ndelay(270); + tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl); + } + if (ctl & (TX4939IDE_INT_ADDRERR | + TX4939IDE_INT_DEVTIMING | TX4939IDE_INT_BUSERR)) + pr_err("%s: Error interrupt %#x (%s%s%s )\n", + hwif->name, ctl, + ctl & TX4939IDE_INT_ADDRERR ? " Address-Error" : "", + ctl & TX4939IDE_INT_DEVTIMING ? " DEV-Timing" : "", + ctl & TX4939IDE_INT_BUSERR ? " Bus-Error" : ""); + return ctl; +} + +static void tx4939ide_clear_irq(ide_drive_t *drive) +{ + ide_hwif_t *hwif; + void __iomem *base; + u16 ctl; + + /* + * tx4939ide_dma_test_irq() and tx4939ide_dma_end() do all job + * for DMA case. + */ + if (drive->waiting_for_dma) + return; + hwif = drive->hwif; + base = TX4939IDE_BASE(hwif); + ctl = tx4939ide_check_error_ints(hwif); + tx4939ide_writew(ctl, base, TX4939IDE_Int_Ctl); +} + +static u8 tx4939ide_cable_detect(ide_hwif_t *hwif) +{ + void __iomem *base = TX4939IDE_BASE(hwif); + + return tx4939ide_readw(base, TX4939IDE_Sys_Ctl) & 0x2000 ? + ATA_CBL_PATA40 : ATA_CBL_PATA80; +} + +#ifdef __BIG_ENDIAN +static void tx4939ide_dma_host_set(ide_drive_t *drive, int on) +{ + ide_hwif_t *hwif = drive->hwif; + u8 unit = drive->dn; + void __iomem *base = TX4939IDE_BASE(hwif); + u8 dma_stat = tx4939ide_readb(base, TX4939IDE_DMA_Stat); + + if (on) + dma_stat |= (1 << (5 + unit)); + else + dma_stat &= ~(1 << (5 + unit)); + + tx4939ide_writeb(dma_stat, base, TX4939IDE_DMA_Stat); +} +#else +#define tx4939ide_dma_host_set ide_dma_host_set +#endif + +static u8 tx4939ide_clear_dma_status(void __iomem *base) +{ + u8 dma_stat; + + /* read DMA status for INTR & ERROR flags */ + dma_stat = tx4939ide_readb(base, TX4939IDE_DMA_Stat); + /* clear INTR & ERROR flags */ + tx4939ide_writeb(dma_stat | ATA_DMA_INTR | ATA_DMA_ERR, base, + TX4939IDE_DMA_Stat); + /* recover intmask cleared by writing to bit2 of DMA_Stat */ + tx4939ide_writew(TX4939IDE_IGNORE_INTS << 8, base, TX4939IDE_Int_Ctl); + return dma_stat; +} + +#ifdef __BIG_ENDIAN +/* custom ide_build_dmatable to handle swapped layout */ +static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq) +{ + ide_hwif_t *hwif = drive->hwif; + u32 *table = (u32 *)hwif->dmatable_cpu; + 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, bcount; + + cur_addr = sg_dma_address(sg); + cur_len = sg_dma_len(sg); + + /* + * Fill in the DMA table, without crossing any 64kB boundaries. + */ + + while (cur_len) { + if (count++ >= PRD_ENTRIES) + goto use_pio_instead; + + bcount = 0x10000 - (cur_addr & 0xffff); + if (bcount > cur_len) + bcount = cur_len; + *table++ = bcount & 0xffff; + *table++ = cur_addr; + cur_addr += bcount; + cur_len -= bcount; + } + } + + if (count) { + *(table - 2) |= 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 */ +} +#else +#define tx4939ide_build_dmatable ide_build_dmatable +#endif + +static int tx4939ide_dma_setup(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + void __iomem *base = TX4939IDE_BASE(hwif); + struct request *rq = hwif->hwgroup->rq; + u8 reading; + int nent; + + if (rq_data_dir(rq)) + reading = 0; + else + reading = ATA_DMA_WR; + + /* fall back to PIO! */ + nent = tx4939ide_build_dmatable(drive, rq); + if (!nent) { + ide_map_sg(drive, rq); + return 1; + } + + /* PRD table */ + tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr); + + /* specify r/w */ + tx4939ide_writeb(reading, base, TX4939IDE_DMA_Cmd); + + /* clear INTR & ERROR flags */ + tx4939ide_clear_dma_status(base); + + drive->waiting_for_dma = 1; + + tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ? + TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1); + tx4939ide_writew(rq->nr_sectors, base, TX4939IDE_Sec_Cnt); + return 0; +} + +static int tx4939ide_dma_end(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u8 dma_stat, dma_cmd; + void __iomem *base = TX4939IDE_BASE(hwif); + u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl); + + drive->waiting_for_dma = 0; + + /* get DMA command mode */ + dma_cmd = tx4939ide_readb(base, TX4939IDE_DMA_Cmd); + /* stop DMA */ + tx4939ide_writeb(dma_cmd & ~ATA_DMA_START, base, TX4939IDE_DMA_Cmd); + + /* read and clear the INTR & ERROR bits */ + dma_stat = tx4939ide_clear_dma_status(base); + + /* purge DMA mappings */ + ide_destroy_dmatable(drive); + /* verify good DMA status */ + wmb(); + + if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 && + (ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) == + (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) + /* INT_IDE lost... bug? */ + return 0; + return ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) != + ATA_DMA_INTR) ? 0x10 | dma_stat : 0; +} + +/* returns 1 if DMA IRQ issued, 0 otherwise */ +static int tx4939ide_dma_test_irq(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + void __iomem *base = TX4939IDE_BASE(hwif); + u16 ctl, ide_int; + u8 dma_stat, stat; + int found = 0; + + ctl = tx4939ide_check_error_ints(hwif); + ide_int = ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST); + switch (ide_int) { + case TX4939IDE_INT_HOST: + /* On error, XFEREND might not be asserted. */ + stat = tx4939ide_readb(base, TX4939IDE_AltStat_DevCtl); + if ((stat & (ATA_BUSY | ATA_DRQ | ATA_ERR)) == ATA_ERR) + found = 1; + else + /* Wait for XFEREND (Mask HOST and unmask XFEREND) */ + ctl &= ~TX4939IDE_INT_XFEREND << 8; + ctl |= ide_int << 8; + break; + case TX4939IDE_INT_HOST | TX4939IDE_INT_XFEREND: + dma_stat = tx4939ide_readb(base, TX4939IDE_DMA_Stat); + if (!(dma_stat & ATA_DMA_INTR)) + pr_warning("%s: weird interrupt status. " + "DMA_Stat %#02x int_ctl %#04x\n", + hwif->name, dma_stat, ctl); + found = 1; + break; + } + /* + * Do not clear XFEREND, HOST now. They will be cleared by + * clearing bit2 of DMA_Stat. + */ + ctl &= ~ide_int; + tx4939ide_writew(ctl, base, TX4939IDE_Int_Ctl); + return found; +} + +static void tx4939ide_init_hwif(ide_hwif_t *hwif) +{ + void __iomem *base = TX4939IDE_BASE(hwif); + + /* Soft Reset */ + tx4939ide_writew(0x8000, base, TX4939IDE_Sys_Ctl); + mmiowb(); + /* at least 20 GBUSCLK (typ. 100ns @ GBUS200MHz, max 450ns) */ + ndelay(450); + tx4939ide_writew(0x0000, base, TX4939IDE_Sys_Ctl); + /* mask some interrupts and clear all interrupts */ + tx4939ide_writew((TX4939IDE_IGNORE_INTS << 8) | 0xff, base, + TX4939IDE_Int_Ctl); + + tx4939ide_writew(0x0008, base, TX4939IDE_Lo_Burst_Cnt); + tx4939ide_writew(0, base, TX4939IDE_Up_Burst_Cnt); +} + +static int tx4939ide_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d) +{ + hwif->dma_base = + hwif->extra_base + tx4939ide_swizzleb(TX4939IDE_DMA_Cmd); + /* + * Note that we cannot use ATA_DMA_TABLE_OFS, ATA_DMA_STATUS + * for big endian. + */ + return ide_allocate_dma_engine(hwif); +} + +static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task) +{ + ide_hwif_t *hwif = drive->hwif; + void __iomem *base = TX4939IDE_BASE(hwif); + u16 sysctl = hwif->select_data >> (drive->dn ? 16 : 0); + + /* + * Fix ATA100 CORE System Control Register. (The write to the + * Device/Head register may write wrong data to the System + * Control Register) + * While Sys_Ctl is written here, selectproc is not needed. + */ + tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl); +} + +#ifdef __BIG_ENDIAN + +static u8 tx4939ide_read_sff_dma_status(ide_hwif_t *hwif) +{ + void __iomem *base = TX4939IDE_BASE(hwif); + + return tx4939ide_readb(base, TX4939IDE_DMA_Stat); +} + +/* custom iops (independent from SWAP_IO_SPACE) */ +static u8 tx4939ide_inb(unsigned long port) +{ + return __raw_readb((void __iomem *)port); +} + +static void tx4939ide_outb(u8 value, unsigned long port) +{ + __raw_writeb(value, (void __iomem *)port); +} + +static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task) +{ + ide_hwif_t *hwif = drive->hwif; + struct ide_io_ports *io_ports = &hwif->io_ports; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; + + if (task->tf_flags & IDE_TFLAG_FLAGGED) + HIHI = 0xFF; + + if (task->tf_flags & IDE_TFLAG_OUT_DATA) { + u16 data = (tf->hob_data << 8) | tf->data; + + /* no endian swap */ + __raw_writew(data, (void __iomem *)io_ports->data_addr); + } + + if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + tx4939ide_outb(tf->hob_feature, io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) + tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr); + + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) + tx4939ide_outb(tf->feature, io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) + tx4939ide_outb(tf->nsect, io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) + tx4939ide_outb(tf->lbal, io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) + tx4939ide_outb(tf->lbam, io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) + tx4939ide_outb(tf->lbah, io_ports->lbah_addr); + + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) { + tx4939ide_outb((tf->device & HIHI) | drive->select, + io_ports->device_addr); + tx4939ide_tf_load_fixup(drive, task); + } +} + +static void tx4939ide_tf_read(ide_drive_t *drive, ide_task_t *task) +{ + ide_hwif_t *hwif = drive->hwif; + struct ide_io_ports *io_ports = &hwif->io_ports; + struct ide_taskfile *tf = &task->tf; + + if (task->tf_flags & IDE_TFLAG_IN_DATA) { + u16 data; + + /* no endian swap */ + data = __raw_readw((void __iomem *)io_ports->data_addr); + tf->data = data & 0xff; + tf->hob_data = (data >> 8) & 0xff; + } + + /* be sure we're looking at the low order bits */ + tx4939ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) + tf->feature = tx4939ide_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_NSECT) + tf->nsect = tx4939ide_inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_LBAL) + tf->lbal = tx4939ide_inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_LBAM) + tf->lbam = tx4939ide_inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_LBAH) + tf->lbah = tx4939ide_inb(io_ports->lbah_addr); + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) + tf->device = tx4939ide_inb(io_ports->device_addr); + + if (task->tf_flags & IDE_TFLAG_LBA48) { + tx4939ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + tf->hob_feature = + tx4939ide_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr); + } +} + +static void tx4939ide_input_data_swap(ide_drive_t *drive, struct request *rq, + void *buf, unsigned int len) +{ + unsigned long port = drive->hwif->io_ports.data_addr; + unsigned short *ptr = buf; + unsigned int count = (len + 1) / 2; + + while (count--) + *ptr++ = cpu_to_le16(__raw_readw((void __iomem *)port)); + __ide_flush_dcache_range((unsigned long)buf, count * 2); +} + +static void tx4939ide_output_data_swap(ide_drive_t *drive, struct request *rq, + void *buf, unsigned int len) +{ + unsigned long port = drive->hwif->io_ports.data_addr; + unsigned short *ptr = buf; + unsigned int count = (len + 1) / 2; + + while (count--) { + __raw_writew(le16_to_cpu(*ptr), (void __iomem *)port); + ptr++; + } + __ide_flush_dcache_range((unsigned long)buf, count * 2); +} + +static const struct ide_tp_ops tx4939ide_tp_ops = { + .exec_command = ide_exec_command, + .read_status = ide_read_status, + .read_altstatus = ide_read_altstatus, + .read_sff_dma_status = tx4939ide_read_sff_dma_status, + + .set_irq = ide_set_irq, + + .tf_load = tx4939ide_tf_load, + .tf_read = tx4939ide_tf_read, + + .input_data = tx4939ide_input_data_swap, + .output_data = tx4939ide_output_data_swap, +}; + +#else /* __LITTLE_ENDIAN */ + +static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task) +{ + ide_tf_load(drive, task); + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) + tx4939ide_tf_load_fixup(drive, task); +} + +static const struct ide_tp_ops tx4939ide_tp_ops = { + .exec_command = ide_exec_command, + .read_status = ide_read_status, + .read_altstatus = ide_read_altstatus, + .read_sff_dma_status = ide_read_sff_dma_status, + + .set_irq = ide_set_irq, + + .tf_load = tx4939ide_tf_load, + .tf_read = ide_tf_read, + + .input_data = ide_input_data, + .output_data = ide_output_data, +}; + +#endif /* __LITTLE_ENDIAN */ + +static const struct ide_port_ops tx4939ide_port_ops = { + .set_pio_mode = tx4939ide_set_pio_mode, + .set_dma_mode = tx4939ide_set_dma_mode, + .clear_irq = tx4939ide_clear_irq, + .cable_detect = tx4939ide_cable_detect, +}; + +static const struct ide_dma_ops tx4939ide_dma_ops = { + .dma_host_set = tx4939ide_dma_host_set, + .dma_setup = tx4939ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, + .dma_start = ide_dma_start, + .dma_end = tx4939ide_dma_end, + .dma_test_irq = tx4939ide_dma_test_irq, + .dma_lost_irq = ide_dma_lost_irq, + .dma_timeout = ide_dma_timeout, +}; + +static const struct ide_port_info tx4939ide_port_info __initdata = { + .init_hwif = tx4939ide_init_hwif, + .init_dma = tx4939ide_init_dma, + .port_ops = &tx4939ide_port_ops, + .dma_ops = &tx4939ide_dma_ops, + .tp_ops = &tx4939ide_tp_ops, + .host_flags = IDE_HFLAG_MMIO, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA5, +}; + +static int __init tx4939ide_probe(struct platform_device *pdev) +{ + hw_regs_t hw; + hw_regs_t *hws[] = { &hw, NULL, NULL, NULL }; + struct ide_host *host; + struct resource *res; + int irq, ret; + unsigned long mapbase; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -ENODEV; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + if (!devm_request_mem_region(&pdev->dev, res->start, + res->end - res->start + 1, "tx4938ide")) + return -EBUSY; + mapbase = (unsigned long)devm_ioremap(&pdev->dev, res->start, + res->end - res->start + 1); + if (!mapbase) + return -EBUSY; + memset(&hw, 0, sizeof(hw)); + hw.io_ports.data_addr = + mapbase + tx4939ide_swizzlew(TX4939IDE_Data); + hw.io_ports.error_addr = + mapbase + tx4939ide_swizzleb(TX4939IDE_Error_Feature); + hw.io_ports.nsect_addr = + mapbase + tx4939ide_swizzleb(TX4939IDE_Sec); + hw.io_ports.lbal_addr = + mapbase + tx4939ide_swizzleb(TX4939IDE_LBA0); + hw.io_ports.lbam_addr = + mapbase + tx4939ide_swizzleb(TX4939IDE_LBA1); + hw.io_ports.lbah_addr = + mapbase + tx4939ide_swizzleb(TX4939IDE_LBA2); + hw.io_ports.device_addr = + mapbase + tx4939ide_swizzleb(TX4939IDE_DevHead); + hw.io_ports.command_addr = + mapbase + tx4939ide_swizzleb(TX4939IDE_Stat_Cmd); + hw.io_ports.ctl_addr = + mapbase + tx4939ide_swizzleb(TX4939IDE_AltStat_DevCtl); + hw.irq = irq; + hw.dev = &pdev->dev; + + pr_info("TX4939 IDE interface (base %#lx, irq %d)\n", mapbase, irq); + host = ide_host_alloc(&tx4939ide_port_info, hws); + if (!host) + return -ENOMEM; + /* use extra_base for base address of the all registers */ + host->ports[0]->extra_base = mapbase; + ret = ide_host_register(host, &tx4939ide_port_info, hws); + if (ret) { + ide_host_free(host); + return ret; + } + platform_set_drvdata(pdev, host); + return 0; +} + +static int __exit tx4939ide_remove(struct platform_device *pdev) +{ + struct ide_host *host = platform_get_drvdata(pdev); + + ide_host_remove(host); + return 0; +} + +#ifdef CONFIG_PM +static int tx4939ide_resume(struct platform_device *dev) +{ + struct ide_host *host = platform_get_drvdata(dev); + ide_hwif_t *hwif = host->ports[0]; + + tx4939ide_init_hwif(hwif); + return 0; +} +#else +#define tx4939ide_resume NULL +#endif + +static struct platform_driver tx4939ide_driver = { + .driver = { + .name = MODNAME, + .owner = THIS_MODULE, + }, + .remove = __exit_p(tx4939ide_remove), + .resume = tx4939ide_resume, +}; + +static int __init tx4939ide_init(void) +{ + return platform_driver_probe(&tx4939ide_driver, tx4939ide_probe); +} + +static void __exit tx4939ide_exit(void) +{ + platform_driver_unregister(&tx4939ide_driver); +} + +module_init(tx4939ide_init); +module_exit(tx4939ide_exit); + +MODULE_DESCRIPTION("TX4939 internal IDE driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:tx4939ide"); diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/umc8672.c index 1da076e0c917..1da076e0c917 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 2a812d3207e9..2a812d3207e9 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/via82cxxx.c |