diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2011-01-06 14:48:24 -0600 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-01-24 11:30:26 -0600 |
commit | 6eaf46fdc719991a3ccda1e14b274e9adb515978 (patch) | |
tree | 00d372c09bdf41e513e2b7fcf3259386df0e27c9 /drivers/scsi/hpsa.c | |
parent | 25c1e56a04e60af2414f8d81eda0fd10b8e7b961 (diff) |
[SCSI] hpsa: take the adapter lock in hpsa_wait_for_mode_change_ack
Need to take the lock while accessing the register to check to
see if config table changes have taken effect.
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 5b9cd41d9320..4fb62c2aac05 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -3553,13 +3553,18 @@ static inline void hpsa_p600_dma_prefetch_quirk(struct ctlr_info *h) static void __devinit hpsa_wait_for_mode_change_ack(struct ctlr_info *h) { int i; + u32 doorbell_value; + unsigned long flags; /* under certain very rare conditions, this can take awhile. * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right * as we enter this code.) */ for (i = 0; i < MAX_CONFIG_WAIT; i++) { - if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) + spin_lock_irqsave(&h->lock, flags); + doorbell_value = readl(h->vaddr + SA5_DOORBELL); + spin_unlock_irqrestore(&h->lock, flags); + if (!doorbell_value & CFGTBL_ChangeReq) break; /* delay and try again */ msleep(10); @@ -3731,6 +3736,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, h->busy_initializing = 1; INIT_HLIST_HEAD(&h->cmpQ); INIT_HLIST_HEAD(&h->reqQ); + spin_lock_init(&h->lock); + spin_lock_init(&h->scan_lock); rc = hpsa_pci_init(h); if (rc != 0) goto clean1; @@ -3790,8 +3797,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, } if (hpsa_allocate_sg_chain_blocks(h)) goto clean4; - spin_lock_init(&h->lock); - spin_lock_init(&h->scan_lock); init_waitqueue_head(&h->scan_wait_queue); h->scan_finished = 1; /* no scan currently in progress */ |