diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2010-02-17 08:17:31 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-03-01 15:06:28 -0500 |
commit | e99846f18f03badd1bbd4fda79e6ec325e3b9058 (patch) | |
tree | c5e8e1d36c495fd003f648eea2e2c582efd61177 | |
parent | 303f1a76ae792885af8a4a0e784e22e31e850e9a (diff) |
[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>
-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 @@ | |||
1 | /* | 1 | /* |
2 | * pata_atiixp.c - ATI PATA for new ATA layer | 2 | * pata_atiixp.c - ATI PATA for new ATA layer |
3 | * (C) 2005 Red Hat Inc | 3 | * (C) 2005 Red Hat Inc |
4 | * (C) 2009 Bartlomiej Zolnierkiewicz | 4 | * (C) 2009-2010 Bartlomiej Zolnierkiewicz |
5 | * | 5 | * |
6 | * Based on | 6 | * Based on |
7 | * | 7 | * |
@@ -46,6 +46,8 @@ static int atiixp_cable_detect(struct ata_port *ap) | |||
46 | return ATA_CBL_PATA40; | 46 | return ATA_CBL_PATA40; |
47 | } | 47 | } |
48 | 48 | ||
49 | static DEFINE_SPINLOCK(atiixp_lock); | ||
50 | |||
49 | /** | 51 | /** |
50 | * atiixp_set_pio_timing - set initial PIO mode data | 52 | * atiixp_set_pio_timing - set initial PIO mode data |
51 | * @ap: ATA interface | 53 | * @ap: ATA interface |
@@ -88,7 +90,10 @@ static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, | |||
88 | 90 | ||
89 | static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev) | 91 | static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev) |
90 | { | 92 | { |
93 | unsigned long flags; | ||
94 | spin_lock_irqsave(&atiixp_lock, flags); | ||
91 | atiixp_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0); | 95 | atiixp_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0); |
96 | spin_unlock_irqrestore(&atiixp_lock, flags); | ||
92 | } | 97 | } |
93 | 98 | ||
94 | /** | 99 | /** |
@@ -108,6 +113,9 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
108 | int dma = adev->dma_mode; | 113 | int dma = adev->dma_mode; |
109 | int dn = 2 * ap->port_no + adev->devno; | 114 | int dn = 2 * ap->port_no + adev->devno; |
110 | int wanted_pio; | 115 | int wanted_pio; |
116 | unsigned long flags; | ||
117 | |||
118 | spin_lock_irqsave(&atiixp_lock, flags); | ||
111 | 119 | ||
112 | if (adev->dma_mode >= XFER_UDMA_0) { | 120 | if (adev->dma_mode >= XFER_UDMA_0) { |
113 | u16 udma_mode_data; | 121 | u16 udma_mode_data; |
@@ -145,6 +153,7 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
145 | 153 | ||
146 | if (adev->pio_mode != wanted_pio) | 154 | if (adev->pio_mode != wanted_pio) |
147 | atiixp_set_pio_timing(ap, adev, wanted_pio); | 155 | atiixp_set_pio_timing(ap, adev, wanted_pio); |
156 | spin_unlock_irqrestore(&atiixp_lock, flags); | ||
148 | } | 157 | } |
149 | 158 | ||
150 | /** | 159 | /** |