diff options
| author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2010-02-17 13:17:31 +0000 | 
|---|---|---|
| committer | Jeff Garzik <jgarzik@redhat.com> | 2010-03-01 15:06:28 -0500 | 
| commit | e99846f18f03badd1bbd4fda79e6ec325e3b9058 (patch) | |
| tree | c5e8e1d36c495fd003f648eea2e2c582efd61177 /drivers/ata | |
| parent | 303f1a76ae792885af8a4a0e784e22e31e850e9a (diff) | |
| download | linux-e99846f18f03badd1bbd4fda79e6ec325e3b9058.tar.bz2 | |
[libata] pata_atiixp: add locking for parallel scanning
This is similar change as commit 60c3be3 for ata_piix host driver
and while pata_atiixp doesn't enable parallel scan yet the race
could probably also be triggered by requesting re-scanning of both
ports at the same time using SCSI sysfs interface.
[Ported to current tree without other patch dependancies by Alan Cox]
Original is
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This one is
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
| -rw-r--r-- | drivers/ata/pata_atiixp.c | 11 | 
1 files changed, 10 insertions, 1 deletions
| diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index f697b5b880d3..9ad3b4ce1ca5 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -1,7 +1,7 @@  /*   * pata_atiixp.c 	- ATI PATA for new ATA layer   *			  (C) 2005 Red Hat Inc - *			  (C) 2009 Bartlomiej Zolnierkiewicz + *			  (C) 2009-2010 Bartlomiej Zolnierkiewicz   *   * Based on   * @@ -46,6 +46,8 @@ static int atiixp_cable_detect(struct ata_port *ap)  	return ATA_CBL_PATA40;  } +static DEFINE_SPINLOCK(atiixp_lock); +  /**   *	atiixp_set_pio_timing	-	set initial PIO mode data   *	@ap: ATA interface @@ -88,7 +90,10 @@ static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev,  static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev)  { +	unsigned long flags; +	spin_lock_irqsave(&atiixp_lock, flags);  	atiixp_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0); +	spin_unlock_irqrestore(&atiixp_lock, flags);  }  /** @@ -108,6 +113,9 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)  	int dma = adev->dma_mode;  	int dn = 2 * ap->port_no + adev->devno;  	int wanted_pio; +	unsigned long flags; + +	spin_lock_irqsave(&atiixp_lock, flags);  	if (adev->dma_mode >= XFER_UDMA_0) {  		u16 udma_mode_data; @@ -145,6 +153,7 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)  	if (adev->pio_mode != wanted_pio)  		atiixp_set_pio_timing(ap, adev, wanted_pio); +	spin_unlock_irqrestore(&atiixp_lock, flags);  }  /** |