summaryrefslogtreecommitdiff
path: root/drivers/ata/ata_piix.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 09:20:19 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 09:20:19 -0700
commit132a4edb2b69924742f62dc06ace42ad2a9f57f3 (patch)
tree53b73abd91273d2cad021fb9b5218f3d18d90c86 /drivers/ata/ata_piix.c
parente6da54d84f9286edbe4c92ff5023ff481ce2a5c9 (diff)
parent752e386c247664152f2cce37915d1f50631d7f42 (diff)
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: sata_fsl,mv,nv: prepare for NCQ command completion update ata: Convert pci_table entries to PCI_VDEVICE (if PCI_ANY_ID is used) libata: more PCI IDs for jmicron controllers ata_piix: fix locking around SIDPR access [libata] update blacklist for new hyphenated pattern ranges (v2) libata: allow hyphenated pattern ranges ata_generic: drop hard coded DMA force logic for CENATEK [libata] ahci: Fix warning: comparison between 'enum <anonymous>' and 'enum <anonymous>' [libata] add ATA_CMD_DSM to ata_get_cmd_descript [libata] Add Samsung PATA controller driver, pata_samsung_cf [libata] Add 460EX on-chip SATA driver, sata_dwc_460ex libata: reduce blacklist size even more (v2) libata: reduce blacklist size (v2) libata: glob_match for ata_device_blacklist (v2) ahci_platform: Remove unneeded ahci_driver.probe assignment ahci_platform: Provide for vendor specific init
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r--drivers/ata/ata_piix.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 7409f98d2ae6..3971bc0a4838 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -158,6 +158,7 @@ struct piix_map_db {
struct piix_host_priv {
const int *map;
u32 saved_iocfg;
+ spinlock_t sidpr_lock; /* FIXME: remove once locking in EH is fixed */
void __iomem *sidpr;
};
@@ -951,12 +952,15 @@ static int piix_sidpr_scr_read(struct ata_link *link,
unsigned int reg, u32 *val)
{
struct piix_host_priv *hpriv = link->ap->host->private_data;
+ unsigned long flags;
if (reg >= ARRAY_SIZE(piix_sidx_map))
return -EINVAL;
+ spin_lock_irqsave(&hpriv->sidpr_lock, flags);
piix_sidpr_sel(link, reg);
*val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
+ spin_unlock_irqrestore(&hpriv->sidpr_lock, flags);
return 0;
}
@@ -964,12 +968,15 @@ static int piix_sidpr_scr_write(struct ata_link *link,
unsigned int reg, u32 val)
{
struct piix_host_priv *hpriv = link->ap->host->private_data;
+ unsigned long flags;
if (reg >= ARRAY_SIZE(piix_sidx_map))
return -EINVAL;
+ spin_lock_irqsave(&hpriv->sidpr_lock, flags);
piix_sidpr_sel(link, reg);
iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
+ spin_unlock_irqrestore(&hpriv->sidpr_lock, flags);
return 0;
}
@@ -1566,6 +1573,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;
+ spin_lock_init(&hpriv->sidpr_lock);
/* Save IOCFG, this will be used for cable detection, quirk
* detection and restoration on detach. This is necessary