diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2011-10-13 10:06:04 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2011-10-14 13:25:10 -0400 |
commit | bb612cba3a591eca80ea581223e26f6e917391a9 (patch) | |
tree | e7ddec5d5bd7a3fdd199f4818431d7325e135688 /drivers/ata/pata_rdc.c | |
parent | d9d579842e9e10a49e1ba6a16be5ce2757d38cc0 (diff) |
pata_rdc: parallel scanning needs an extra locking
This is similar change as commit 60c3be3 ("ata_piix: parallel scanning
on PATA needs an extra locking") for ata_piix host driver.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/pata_rdc.c')
-rw-r--r-- | drivers/ata/pata_rdc.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/ata/pata_rdc.c b/drivers/ata/pata_rdc.c index 4d318f86ae86..f52831f904cf 100644 --- a/drivers/ata/pata_rdc.c +++ b/drivers/ata/pata_rdc.c | |||
@@ -86,6 +86,8 @@ static int rdc_pata_prereset(struct ata_link *link, unsigned long deadline) | |||
86 | return ata_sff_prereset(link, deadline); | 86 | return ata_sff_prereset(link, deadline); |
87 | } | 87 | } |
88 | 88 | ||
89 | static DEFINE_SPINLOCK(rdc_lock); | ||
90 | |||
89 | /** | 91 | /** |
90 | * rdc_set_piomode - Initialize host controller PATA PIO timings | 92 | * rdc_set_piomode - Initialize host controller PATA PIO timings |
91 | * @ap: Port whose timings we are configuring | 93 | * @ap: Port whose timings we are configuring |
@@ -101,6 +103,7 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
101 | { | 103 | { |
102 | unsigned int pio = adev->pio_mode - XFER_PIO_0; | 104 | unsigned int pio = adev->pio_mode - XFER_PIO_0; |
103 | struct pci_dev *dev = to_pci_dev(ap->host->dev); | 105 | struct pci_dev *dev = to_pci_dev(ap->host->dev); |
106 | unsigned long flags; | ||
104 | unsigned int is_slave = (adev->devno != 0); | 107 | unsigned int is_slave = (adev->devno != 0); |
105 | unsigned int master_port= ap->port_no ? 0x42 : 0x40; | 108 | unsigned int master_port= ap->port_no ? 0x42 : 0x40; |
106 | unsigned int slave_port = 0x44; | 109 | unsigned int slave_port = 0x44; |
@@ -124,6 +127,8 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
124 | if (adev->class == ATA_DEV_ATA) | 127 | if (adev->class == ATA_DEV_ATA) |
125 | control |= 4; /* PPE enable */ | 128 | control |= 4; /* PPE enable */ |
126 | 129 | ||
130 | spin_lock_irqsave(&rdc_lock, flags); | ||
131 | |||
127 | /* PIO configuration clears DTE unconditionally. It will be | 132 | /* PIO configuration clears DTE unconditionally. It will be |
128 | * programmed in set_dmamode which is guaranteed to be called | 133 | * programmed in set_dmamode which is guaranteed to be called |
129 | * after set_piomode if any DMA mode is available. | 134 | * after set_piomode if any DMA mode is available. |
@@ -161,6 +166,8 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
161 | pci_read_config_byte(dev, 0x48, &udma_enable); | 166 | pci_read_config_byte(dev, 0x48, &udma_enable); |
162 | udma_enable &= ~(1 << (2 * ap->port_no + adev->devno)); | 167 | udma_enable &= ~(1 << (2 * ap->port_no + adev->devno)); |
163 | pci_write_config_byte(dev, 0x48, udma_enable); | 168 | pci_write_config_byte(dev, 0x48, udma_enable); |
169 | |||
170 | spin_unlock_irqrestore(&rdc_lock, flags); | ||
164 | } | 171 | } |
165 | 172 | ||
166 | /** | 173 | /** |
@@ -177,6 +184,7 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
177 | static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev) | 184 | static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev) |
178 | { | 185 | { |
179 | struct pci_dev *dev = to_pci_dev(ap->host->dev); | 186 | struct pci_dev *dev = to_pci_dev(ap->host->dev); |
187 | unsigned long flags; | ||
180 | u8 master_port = ap->port_no ? 0x42 : 0x40; | 188 | u8 master_port = ap->port_no ? 0x42 : 0x40; |
181 | u16 master_data; | 189 | u16 master_data; |
182 | u8 speed = adev->dma_mode; | 190 | u8 speed = adev->dma_mode; |
@@ -190,6 +198,8 @@ static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
190 | { 2, 1 }, | 198 | { 2, 1 }, |
191 | { 2, 3 }, }; | 199 | { 2, 3 }, }; |
192 | 200 | ||
201 | spin_lock_irqsave(&rdc_lock, flags); | ||
202 | |||
193 | pci_read_config_word(dev, master_port, &master_data); | 203 | pci_read_config_word(dev, master_port, &master_data); |
194 | pci_read_config_byte(dev, 0x48, &udma_enable); | 204 | pci_read_config_byte(dev, 0x48, &udma_enable); |
195 | 205 | ||
@@ -271,6 +281,8 @@ static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
271 | pci_write_config_word(dev, master_port, master_data); | 281 | pci_write_config_word(dev, master_port, master_data); |
272 | } | 282 | } |
273 | pci_write_config_byte(dev, 0x48, udma_enable); | 283 | pci_write_config_byte(dev, 0x48, udma_enable); |
284 | |||
285 | spin_unlock_irqrestore(&rdc_lock, flags); | ||
274 | } | 286 | } |
275 | 287 | ||
276 | static struct ata_port_operations rdc_pata_ops = { | 288 | static struct ata_port_operations rdc_pata_ops = { |