From 82a0e70e795ee605e1a34a874dd3a3a43b745fb9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 20 Aug 2007 22:42:53 +0200 Subject: [PATCH 01/13] ide: make CONFIG_IDE_GENERIC default to N These days, CONFIG_IDE_GENERIC causes more confusion and misconfiguration than it helps. Especially so because libata is linked after the generic driver. Default to N. Signed-off-by: Tejun Heo Acked-by: Jeff Garzik Cc: "P.C.Chan" Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e049f65bc3a2..e7fcdd2580fb 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -304,9 +304,8 @@ comment "IDE chipset support/bugfixes" config IDE_GENERIC tristate "generic/default IDE chipset support" - default y help - If unsure, say Y. + If unsure, say N. config BLK_DEV_CMD640 bool "CMD640 chipset bugfix/support" From 2195dadf853bb32262bd2e5a64f517ae45698c55 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:54 +0200 Subject: [PATCH 02/13] ide: fix hidden dependencies on CONFIG_IDE_GENERIC Some host drivers depend on CONFIG_IDE_GENERIC to do the probing but their config options lack explicit dependencies on IDE_GENERIC. In the long-term these host drivers should be fixed to do the probing themselves but for now fix them by making their config options select CONFIG_IDE_GENERIC. Signed-off-by: Bartlomiej Zolnierkiewicz --- arch/cris/arch-v10/drivers/Kconfig | 1 + arch/cris/arch-v32/drivers/Kconfig | 1 + drivers/ide/Kconfig | 9 +++++++++ 3 files changed, 11 insertions(+) diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index e7e724bc0ba6..03e2e68f947d 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig @@ -548,6 +548,7 @@ config ETRAX_IDE select BLK_DEV_IDEDISK select BLK_DEV_IDECD select BLK_DEV_IDEDMA + select IDE_GENERIC help Enable this to get support for ATA/IDE. You can't use parallel ports or SCSI ports diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index 1d859c16931e..cc6ba5423754 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig @@ -592,6 +592,7 @@ config ETRAX_IDE select BLK_DEV_IDEDISK select BLK_DEV_IDECD select BLK_DEV_IDEDMA + select IDE_GENERIC help Enables the ETRAX IDE driver. diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e7fcdd2580fb..7adb61bad6ad 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -304,6 +304,7 @@ comment "IDE chipset support/bugfixes" config IDE_GENERIC tristate "generic/default IDE chipset support" + default H8300 help If unsure, say N. @@ -344,6 +345,7 @@ config BLK_DEV_CMD640_ENHANCED config BLK_DEV_IDEPNP bool "PNP EIDE support" depends on PNP + select IDE_GENERIC help If you have a PnP (Plug and Play) compatible EIDE card and would like the kernel to automatically detect and activate @@ -833,6 +835,7 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ config IDE_ARM def_bool ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) + select IDE_GENERIC config BLK_DEV_IDE_ICSIDE tristate "ICS IDE interface support" @@ -866,6 +869,7 @@ config BLK_DEV_IDE_BAST config BLK_DEV_GAYLE bool "Amiga Gayle IDE interface support" depends on AMIGA + select IDE_GENERIC help This is the IDE driver for the Amiga Gayle IDE interface. It supports both the `A1200 style' and `A4000 style' of the Gayle IDE interface, @@ -897,6 +901,7 @@ config BLK_DEV_IDEDOUBLER config BLK_DEV_BUDDHA bool "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)" depends on ZORRO && EXPERIMENTAL + select IDE_GENERIC help This is the IDE driver for the IDE interfaces on the Buddha, Catweasel and X-Surf expansion boards. It supports up to two interfaces @@ -909,6 +914,7 @@ config BLK_DEV_BUDDHA config BLK_DEV_FALCON_IDE bool "Falcon IDE interface support" depends on ATARI + select IDE_GENERIC help This is the IDE driver for the builtin IDE interface on the Atari Falcon. Say Y if you have a Falcon and want to use IDE devices (hard @@ -918,6 +924,7 @@ config BLK_DEV_FALCON_IDE config BLK_DEV_MAC_IDE bool "Macintosh Quadra/Powerbook IDE interface support" depends on MAC + select IDE_GENERIC help This is the IDE driver for the builtin IDE interface on some m68k Macintosh models. It supports both the `Quadra style' (used in @@ -931,6 +938,7 @@ config BLK_DEV_MAC_IDE config BLK_DEV_Q40IDE bool "Q40/Q60 IDE interface support" depends on Q40 + select IDE_GENERIC help Enable the on-board IDE controller in the Q40/Q60. This should normally be on; disable it only if you are running a custom hard @@ -939,6 +947,7 @@ config BLK_DEV_Q40IDE config BLK_DEV_MPC8xx_IDE bool "MPC8xx IDE support" depends on 8xx && IDE=y && BLK_DEV_IDE=y + select IDE_GENERIC help This option provides support for IDE on Motorola MPC8xx Systems. Please see 'Type of MPC8xx IDE interface' for details. From 8292e8c7e4c2b99f22120f677858487de43c484b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:54 +0200 Subject: [PATCH 03/13] ide-cris: fix ->set_pio_mode method to set transfer mode on the device Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/cris/ide-cris.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index fbfea46a34f2..04636f7eaae7 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -718,6 +718,8 @@ static void tune_cris_ide(ide_drive_t *drive, u8 pio) } cris_ide_set_speed(TYPE_PIO, setup, strobe, hold); + + (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); } static int speed_cris_ide(ide_drive_t *drive, u8 speed) From 1116fae5fdfa80c6744a9b5d75fb3ef687a69b19 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:55 +0200 Subject: [PATCH 04/13] ide: config_drive_for_dma() fixes * Add DMA blacklist checking (->ide_dma_on check probably can go now). * Add ->atapi_dma flag checking and remove no longer needed ns87415_ide_dma_check() from ns87415 host driver. * Remove now needless __ide_dma_check() wrapper and symbol export. * Check drive->autodma instead of hwif->autodma (there should be no changes in behavior as all users of config_drive_for_dma() set both ->autodma flags). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 26 ++++++++++---------------- drivers/ide/pci/ns87415.c | 9 --------- include/linux/ide.h | 1 - 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 5fe1d72ab451..865a2740a6e3 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -349,9 +349,17 @@ EXPORT_SYMBOL_GPL(ide_destroy_dmatable); static int config_drive_for_dma (ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; - if ((id->capability & 1) && drive->hwif->autodma) { + /* consult the list of known "bad" drives */ + if (__ide_dma_bad_drive(drive)) + return -1; + + if (drive->media != ide_disk && hwif->atapi_dma == 0) + return -1; + + if ((id->capability & 1) && drive->autodma) { /* * Enable DMA on any drive that has * UltraDMA (mode 0/1/2/3/4/5/6) enabled @@ -513,20 +521,6 @@ int __ide_dma_on (ide_drive_t *drive) EXPORT_SYMBOL(__ide_dma_on); -/** - * __ide_dma_check - check DMA setup - * @drive: drive to check - * - * Don't use - due for extermination - */ - -int __ide_dma_check (ide_drive_t *drive) -{ - return config_drive_for_dma(drive); -} - -EXPORT_SYMBOL(__ide_dma_check); - /** * ide_dma_setup - begin a DMA phase * @drive: target device @@ -1021,7 +1015,7 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p if (!hwif->dma_host_on) hwif->dma_host_on = &ide_dma_host_on; if (!hwif->ide_dma_check) - hwif->ide_dma_check = &__ide_dma_check; + hwif->ide_dma_check = &config_drive_for_dma; if (!hwif->dma_setup) hwif->dma_setup = &ide_dma_setup; if (!hwif->dma_exec_cmd) diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 09941f37d635..465c935fdf25 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -187,14 +187,6 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive) return 1; } -static int ns87415_ide_dma_check (ide_drive_t *drive) -{ - if (drive->media != ide_disk) - return -1; - - return __ide_dma_check(drive); -} - static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; @@ -266,7 +258,6 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) outb(0x60, hwif->dma_status); hwif->dma_setup = &ns87415_ide_dma_setup; - hwif->ide_dma_check = &ns87415_ide_dma_check; hwif->ide_dma_end = &ns87415_ide_dma_end; if (!noautodma) diff --git a/include/linux/ide.h b/include/linux/ide.h index d71d0121b7f9..7e15e0870290 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1312,7 +1312,6 @@ void ide_dma_host_off(ide_drive_t *); void ide_dma_off_quietly(ide_drive_t *); void ide_dma_host_on(ide_drive_t *); extern int __ide_dma_on(ide_drive_t *); -extern int __ide_dma_check(ide_drive_t *); extern int ide_dma_setup(ide_drive_t *); extern void ide_dma_start(ide_drive_t *); extern int __ide_dma_end(ide_drive_t *); From 59785c8fe23ca2f432bc41ef473a8933ab435812 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:55 +0200 Subject: [PATCH 05/13] ide-pmac: fix drive->init_speed reporting pmac_ide_tune_chipset() don't set drive->init_speed. Fix it by setting drive->{current,init}_speed in pmac_ide_do_setfeature() and clean up pmac_ide_{tune_chipset,mdma_enable,udma_enable}(). Acked-by: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 33630ad3e794..4b13cd9a027d 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -604,6 +604,9 @@ pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) drive->id->dma_1word |= 0x0101; break; default: break; } + if (!drive->init_speed) + drive->init_speed = command; + drive->current_speed = command; } enable_irq(hwif->irq); return result; @@ -986,7 +989,6 @@ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed) return ret; pmac_ide_do_update_timings(drive); - drive->current_speed = speed; return 0; } @@ -1737,11 +1739,6 @@ pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) /* Apply timings to controller */ *timings = timing_local[0]; *timings2 = timing_local[1]; - - /* Set speed info in drive */ - drive->current_speed = mode; - if (!drive->init_speed) - drive->init_speed = mode; return 1; } @@ -1793,11 +1790,6 @@ pmac_ide_udma_enable(ide_drive_t *drive, u16 mode) *timings = timing_local[0]; *timings2 = timing_local[1]; - /* Set speed info in drive */ - drive->current_speed = mode; - if (!drive->init_speed) - drive->init_speed = mode; - return 1; } From a5b7e70d787f528386eda025d3e38f545017f241 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: [PATCH 06/13] ide: add cable detection for early UDMA66 devices (take 3) * Move ide_in_drive_list() from ide-dma.c to ide-iops.c. * Add ivb_list[] table for listening early UDMA66 devices which don't conform to ATA4 standard wrt cable detection (bit14 is zero, only bit13 is valid) and use only device side cable detection for them since host side cable detection may be unreliable. * Add model "QUANTUM FIREBALLlct10 05" with firwmare "A03.0900" to the list (from Craig's bugreport). v2: * Improve kernel message basing on suggestion from Sergei. v3: * Don't print kernel message when no device side cable detection is done, plus some minor fixes. (Noticed by Sergei) Thanks to Craig for testing this patch. Cc: Craig Block Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 19 ------------------- drivers/ide/ide-iops.c | 39 ++++++++++++++++++++++++++++++++++++--- include/linux/ide.h | 3 ++- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 865a2740a6e3..ff644a5e12cd 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -134,25 +134,6 @@ static const struct drive_list_entry drive_blacklist [] = { }; -/** - * ide_in_drive_list - look for drive in black/white list - * @id: drive identifier - * @drive_table: list to inspect - * - * Look for a drive in the blacklist and the whitelist tables - * Returns 1 if the drive is found in the table. - */ - -int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) -{ - for ( ; drive_table->id_model ; drive_table++) - if ((!strcmp(drive_table->id_model, id->model)) && - (!drive_table->id_firmware || - strstr(id->fw_rev, drive_table->id_firmware))) - return 1; - return 0; -} - /** * ide_dma_intr - IDE DMA interrupt handler * @drive: the drive the interrupt is for diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 92578b6832e9..fe2a69fed72b 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -565,6 +565,34 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b EXPORT_SYMBOL(ide_wait_stat); +/** + * ide_in_drive_list - look for drive in black/white list + * @id: drive identifier + * @drive_table: list to inspect + * + * Look for a drive in the blacklist and the whitelist tables + * Returns 1 if the drive is found in the table. + */ + +int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) +{ + for ( ; drive_table->id_model; drive_table++) + if ((!strcmp(drive_table->id_model, id->model)) && + (!drive_table->id_firmware || + strstr(id->fw_rev, drive_table->id_firmware))) + return 1; + return 0; +} + +/* + * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. + * We list them here and depend on the device side cable detection for them. + */ +static const struct drive_list_entry ivb_list[] = { + { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, + { NULL , NULL } +}; + /* * All hosts that use the 80c ribbon must use! * The name is derived from upper byte of word 93 and the 80c ribbon. @@ -573,11 +601,16 @@ u8 eighty_ninty_three (ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; + int ivb = ide_in_drive_list(id, ivb_list); if (hwif->cbl == ATA_CBL_PATA40_SHORT) return 1; - if (hwif->cbl != ATA_CBL_PATA80) + if (ivb) + printk(KERN_DEBUG "%s: skipping word 93 validity check\n", + drive->name); + + if (hwif->cbl != ATA_CBL_PATA80 && !ivb) goto no_80w; /* Check for SATA but only if we are ATA5 or higher */ @@ -587,11 +620,11 @@ u8 eighty_ninty_three (ide_drive_t *drive) /* * FIXME: * - change master/slave IDENTIFY order - * - force bit13 (80c cable present) check + * - force bit13 (80c cable present) check also for !ivb devices * (unless the slave device is pre-ATA3) */ #ifndef CONFIG_IDEDMA_IVB - if (id->hw_config & 0x4000) + if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000))) #else if (id->hw_config & 0x6000) #endif diff --git a/include/linux/ide.h b/include/linux/ide.h index 7e15e0870290..c792b4fd1588 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1285,13 +1285,14 @@ void ide_init_sg_cmd(ide_drive_t *, struct request *); #define BAD_DMA_DRIVE 0 #define GOOD_DMA_DRIVE 1 -#ifdef CONFIG_BLK_DEV_IDEDMA struct drive_list_entry { const char *id_model; const char *id_firmware; }; int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *); + +#ifdef CONFIG_BLK_DEV_IDEDMA int __ide_dma_bad_drive(ide_drive_t *); int __ide_dma_good_drive(ide_drive_t *); u8 ide_max_dma_mode(ide_drive_t *); From adcd33d41bfea8fb6870cf1f7e7ed2e5f7323fc1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: [PATCH 07/13] ide: ide_config_drive_speed() bugfixes * Use ->OUTBSYNC instead of ->OUTB when writing command register (needed for scc_pata and pmac host drivers). * Don't check DRDY bit of the status register on ATAPI devices (ATAPI devices are free to ignore DRDY bit). Cc: Benjamin Herrenschmidt Cc: Kou Ishizaki Cc: Akira Iguchi Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-iops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index fe2a69fed72b..18cf3a66a1a3 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -828,7 +828,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); hwif->OUTB(speed, IDE_NSECTOR_REG); hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); - hwif->OUTB(WIN_SETFEATURES, IDE_COMMAND_REG); + hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) hwif->OUTB(drive->ctl, IDE_CONTROL_REG); udelay(1); @@ -855,7 +855,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) */ for (i = 0; i < 10; i++) { udelay(1); - if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) { + if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), drive->ready_stat, BUSY_STAT|DRQ_STAT|ERR_STAT)) { error = 0; break; } From f7b0d2df2f6fd9abdf47b4a1965dcaa2870e35df Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: [PATCH 08/13] cs5530: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Also this host driver requires valid PCI BAR4 for normal operation so check it in ->init_chipset and fail initialization if not set. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cs5530.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index acaf71fd4c09..e5949b1d3fb0 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/cs5530.c Version 0.73 Mar 10 2007 + * linux/drivers/ide/pci/cs5530.c Version 0.74 Jul 28 2007 * * Copyright (C) 2000 Andre Hedrick * Copyright (C) 2000 Mark Lord @@ -207,6 +207,9 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; unsigned long flags; + if (pci_resource_start(dev, 4) == 0) + return -EFAULT; + dev = NULL; while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { switch (dev->device) { @@ -325,6 +328,9 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) /* needs autotuning later */ } + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; From 01cc643ae3c7de35b63989b7b65e3ef3132e48e4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: [PATCH 09/13] pdc202xx_new: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Also this host driver requires valid PCI BAR4 for normal operation so check it in ->init_chipset and fail initialization if not set. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/pdc202xx_new.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 8a66a2871b3a..f6db2f37efad 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -378,6 +378,9 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha int f, r; u8 pll_ctl0, pll_ctl1; + if (dma_base == 0) + return -EFAULT; + #ifdef CONFIG_PPC_PMAC apple_kiwi_init(dev); #endif @@ -494,15 +497,18 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->speedproc = &pdcnew_tune_chipset; hwif->resetproc = &pdcnew_reset; + hwif->err_stops_fifo = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; if (hwif->cbl != ATA_CBL_PATA40_SHORT) From e98d6e50be87c1ad2df81f73c7442cf631d6f931 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: [PATCH 10/13] pdc202xx_old: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/pdc202xx_old.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index fbcb0bb9c956..e19a891171cb 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/pdc202xx_old.c Version 0.50 Mar 3, 2007 + * linux/drivers/ide/pci/pdc202xx_old.c Version 0.51 Jul 27, 2007 * * Copyright (C) 1998-2002 Andre Hedrick * Copyright (C) 2006-2007 MontaVista Software, Inc. @@ -337,15 +337,18 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->speedproc = &pdc202xx_tune_chipset; + hwif->err_stops_fifo = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) + return; + hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; hwif->atapi_dma = 1; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; hwif->dma_lost_irq = &pdc202xx_dma_lost_irq; hwif->dma_timeout = &pdc202xx_dma_timeout; From 88b47040f8365ad56ecfd4103e964ba9b695987e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: [PATCH 11/13] triflex: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/triflex.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index 024bbfae0429..098692a6d615 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -115,6 +115,9 @@ static void __devinit init_hwif_triflex(ide_hwif_t *hwif) hwif->tuneproc = &triflex_tune_drive; hwif->speedproc = &triflex_tune_chipset; + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; From 76e1faa7cfd464fa06a9c2cafd633d643daafeae Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:57 +0200 Subject: [PATCH 12/13] hpt34x: fix CONFIG_HPT34X_AUTODMA=n handling Programming DMA mode may destroy current PIO mode setting so if CONFIG_HPT34X_AUTODMA=n (the default case) make ide_tune_dma() fail early by disabling all host DMA masks and re-tune PIO mode. This fix doesn't help with the driver being broken but is needed for some other changes. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/hpt34x.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index 19778c5fe711..cb8fe5643d3b 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c @@ -89,11 +89,7 @@ static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive) drive->init_speed = 0; if (ide_tune_dma(drive)) -#ifndef CONFIG_HPT34X_AUTODMA return -1; -#else - return 0; -#endif if (ide_use_fast_pio(drive)) hpt34x_tune_drive(drive, 255); @@ -160,9 +156,11 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) if (!hwif->dma_base) return; +#ifdef CONFIG_HPT34X_AUTODMA hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; +#endif hwif->ide_dma_check = &hpt34x_config_drive_xfer_rate; if (!noautodma) From b0244a00451c1ad64bf0a51f50679f7146786780 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:57 +0200 Subject: [PATCH 13/13] ide-disk: workaround for buggy HPA support on ST340823A (take 3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This disk reports total number of sectors instead of maximum sector address in response to READ_NATIVE_MAX_ADDRESS command and also happily accepts SET_MAX_ADDRESS command with the bogus value. This results in +1 sector capacity being used and errors on attempts to use the last sector. ... hdd: Host Protected Area detected.         current capacity is 78165360 sectors (40020 MB)         native  capacity is 78165361 sectors (40020 MB) hdd: Host Protected Area disabled. ... hdd: reading: block=78165360, sectors=1, buffer=0xc1e63000 hdd: dma_intr: status=0x51 { DriveReady SeekComplete Error } hdd: dma_intr: error=0x10 { SectorIdNotFound }, LBAsect=78165360, sector=78165360 ... Add hpa_list[] table and workaround the issue in idedisk_check_hpa(). v2: * Add missing export and improve patch description a bit. v3: * Add list termination. (From Mikko) Fixes kernel bugzilla bug #8816. Thanks to Mikko for investigating the issue and helping with this patch. Cc: Mikko Rapeli Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-disk.c | 18 ++++++++++++++++++ drivers/ide/ide-iops.c | 2 ++ 2 files changed, 20 insertions(+) diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 5ce4216f72a2..eba1adbc1b6a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -481,6 +481,15 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id) && id->lba_capacity_2; } +/* + * Some disks report total number of sectors instead of + * maximum sector address. We list them here. + */ +static const struct drive_list_entry hpa_list[] = { + { "ST340823A", NULL }, + { NULL, NULL } +}; + static void idedisk_check_hpa(ide_drive_t *drive) { unsigned long long capacity, set_max; @@ -492,6 +501,15 @@ static void idedisk_check_hpa(ide_drive_t *drive) else set_max = idedisk_read_native_max_address(drive); + if (ide_in_drive_list(drive->id, hpa_list)) { + /* + * Since we are inclusive wrt to firmware revisions do this + * extra check and apply the workaround only when needed. + */ + if (set_max == capacity + 1) + set_max--; + } + if (set_max <= capacity) return; diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 18cf3a66a1a3..f4cd2700cae5 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -584,6 +584,8 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv return 0; } +EXPORT_SYMBOL_GPL(ide_in_drive_list); + /* * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. * We list them here and depend on the device side cable detection for them.