linux/drivers/ata
Bartlomiej Zolnierkiewicz 60c3be387b ata_piix: parallel scanning on PATA needs an extra locking
Commit log for commit 517d3cc15b
("[libata] ata_piix: Enable parallel scan") says:

    This patch turns on parallel scanning for the ata_piix driver.
    This driver is used on most netbooks (no AHCI for cheap storage it seems).
    The scan is the dominating time factor in the kernel boot for these
    devices; with this flag it gets cut in half for the device I used
    for testing (eeepc).
    Alan took a look at the driver source and concluded that it ought to be safe
    to do for this driver.  Alan has also checked with the hardware team.

and it is all true but once we put all things together additional
constraints for PATA controllers show up (some hardware registers
have per-host not per-port atomicity) and we risk misprogramming
the controller.

I used the following test to check whether the issue is real:

  @@ -736,8 +736,20 @@ static void piix_set_piomode(struct ata_
   			(timings[pio][1] << 8);
   	}
   	pci_write_config_word(dev, master_port, master_data);
  -	if (is_slave)
  +	if (is_slave) {
  +		if (ap->port_no == 0) {
  +			u8 tmp = slave_data;
  +
  +			while (slave_data == tmp) {
  +				pci_read_config_byte(dev, slave_port, &tmp);
  +				msleep(50);
  +			}
  +
  +			dev_printk(KERN_ERR, &dev->dev, "PATA parallel scan "
  +				   "race detected\n");
  +		}
   		pci_write_config_byte(dev, slave_port, slave_data);
  +	}

   	/* Ensure the UDMA bit is off - it will be turned back on if
   	   UDMA is selected */

and it indeed triggered the error message.

Lets fix all such races by adding an extra locking to ->set_piomode
and ->set_dmamode methods for PATA controllers.

[ Alan: would be better to take the host lock in libata-core for these
  cases so that we fix all the adapters in one swoop.  "Looks fine as a
  temproary quickfix tho" ]

Cc: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Alan Cox <alan@linux.intel.com>
Cc: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-08-31 17:25:00 -10:00
..
Kconfig [libata] PATA driver for CF interface on AT91SAM9260 SoC 2009-06-23 01:54:24 -04:00
Makefile [libata] PATA driver for CF interface on AT91SAM9260 SoC 2009-06-23 01:54:24 -04:00
ahci.c ahci: add workaround for on-board 5723s on some gigabyte boards 2009-08-12 06:21:32 -04:00
ata_generic.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
ata_piix.c ata_piix: parallel scanning on PATA needs an extra locking 2009-08-31 17:25:00 -10:00
libata-acpi.c trivial: fix typos s/paramter/parameter/ and s/excute/execute/ in documentation and source comments. 2009-06-12 18:01:46 +02:00
libata-core.c libata: OCZ Vertex can't do HPA 2009-08-12 06:17:33 -04:00
libata-eh.c libata: add missing NULL pointer check to ata_eh_reset() 2009-07-28 21:05:41 -04:00
libata-pmp.c libata: add @spd_limit to sata_down_spd_limit() 2009-02-02 23:03:22 -05:00
libata-scsi.c Merge branch 'master' into for-2.6.31 2009-05-22 20:25:34 +02:00
libata-sff.c libata-sff: avoid byte swapping in ata_sff_data_xfer() 2009-06-10 07:50:16 -04:00
libata.h [libata] Export ata_pio_queue_task() so that it can be used from sata_mv. 2009-03-24 22:02:41 -04:00
pata_acpi.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_ali.c [libata] pata_ali: Use IGN_SIMPLEX 2009-06-05 17:10:54 -04:00
pata_amd.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_artop.c pata_artop: Serializing support 2009-03-24 22:45:05 -04:00
pata_at32.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_at91.c pata_at91: fix resource release 2009-08-12 06:16:47 -04:00
pata_atiixp.c pata_atiixp: fix second channel support 2009-08-12 06:17:29 -04:00
pata_bf54x.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_cmd64x.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_cmd640.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_cs5520.c dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
pata_cs5530.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_cs5535.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_cs5536.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_cypress.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_efar.c pata_efar: fix PIO2 underclocking 2009-06-05 14:40:52 -04:00
pata_hpt3x2n.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_hpt3x3.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_hpt37x.c pata_hpt37x: fix HPT370 DMA timeouts 2009-04-16 15:21:15 -04:00
pata_hpt366.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_icside.c Merge branch 'origin' into devel 2009-03-28 20:29:51 +00:00
pata_isapnp.c [libata] Improve timeout handling 2009-03-24 22:52:39 -04:00
pata_it821x.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_it8213.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_ixp4xx_cf.c dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
pata_jmicron.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_legacy.c pata_legacy: wait for async probing 2009-06-05 14:40:46 -04:00
pata_marvell.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_mpc52xx.c powerpc/5xxx: Add common mpc5xxx_get_bus_frequency() function 2009-06-17 00:30:22 -06:00
pata_mpiix.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_netcell.c pata_netcell: Fix typo 2009-06-08 09:12:28 -07:00
pata_ninja32.c ata: Report 16/32bit PIO as best we can 2009-04-16 15:28:23 -04:00
pata_ns87410.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_ns87415.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_octeon_cf.c libata: remove superfluous NULL pointer checks 2009-07-28 21:06:13 -04:00
pata_of_platform.c powerpc: Fix no interrupt handling in pata_of_platform 2008-10-10 15:55:17 +11:00
pata_oldpiix.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_opti.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_optidma.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_palmld.c [ARM] 5522/1: PalmLD: IDE support 2009-05-31 14:50:40 +01:00
pata_pcmcia.c pata_pcmcia: add CNF-CDROM-ID 2009-07-28 21:05:18 -04:00
pata_pdc202xx_old.c pata_pdc202xx_old: fix UDMA33 handling 2009-05-11 14:30:07 -04:00
pata_pdc2027x.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_platform.c pata_platform: __pata_platform_remove() shouldn't be in discard section 2009-01-08 16:10:29 -05:00
pata_qdi.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_radisys.c pata_radisys: fix mwdma_mask to exclude mwdma0 2009-03-24 22:13:32 -04:00
pata_rb532_cf.c pata-rb532-cf: platform_get_irq() fix ignored failure 2009-03-24 22:16:34 -04:00
pata_rz1000.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_sc1200.c pata_sc1200: Activate secondary channel 2009-03-24 22:45:37 -04:00
pata_scc.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_sch.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_serverworks.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_sil680.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_sis.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_sl82c105.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_triflex.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_via.c pata_via: Cache and rewrite the device bit 2009-04-17 19:04:30 -04:00
pata_winbond.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pdc_adma.c dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
sata_fsl.c sata_fsl: Add power mgmt support 2009-06-23 01:54:27 -04:00
sata_inic162x.c dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
sata_mv.c libata: remove superfluous NULL pointer checks 2009-07-28 21:06:13 -04:00
sata_nv.c sata_nv: MSI support, disabled by default 2009-08-12 06:20:29 -04:00
sata_promise.c [libata] Improve timeout handling 2009-03-24 22:52:39 -04:00
sata_promise.h libata annotations and fixes 2008-01-23 05:24:15 -05:00
sata_qstor.c dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
sata_sil.c libata: remove superfluous NULL pointer checks 2009-07-28 21:06:13 -04:00
sata_sil24.c dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
sata_sis.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
sata_svw.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
sata_sx4.c sata_sx4: speed up ECC initialization 2009-06-10 07:50:17 -04:00
sata_uli.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
sata_via.c [libata] sata_via: kill uninit'd var warning 2009-04-13 04:09:34 -04:00
sata_vsc.c dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
sis.h libata: PATA-mode fixes for sis_sata 2007-07-02 10:17:42 -04:00