aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2010-02-17 08:17:31 -0500
committerJeff Garzik <jgarzik@redhat.com>2010-03-01 15:06:28 -0500
commite99846f18f03badd1bbd4fda79e6ec325e3b9058 (patch)
treec5e8e1d36c495fd003f648eea2e2c582efd61177
parent303f1a76ae792885af8a4a0e784e22e31e850e9a (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.c11
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
49static 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
89static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev) 91static 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/**