aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/hpsa.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 89744a152427..c1f4a95d5d5d 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -243,7 +243,7 @@ static int hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id);
243static int hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr, 243static int hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr,
244 int wait_for_ready); 244 int wait_for_ready);
245static inline void finish_cmd(struct CommandList *c); 245static inline void finish_cmd(struct CommandList *c);
246static void hpsa_wait_for_mode_change_ack(struct ctlr_info *h); 246static int hpsa_wait_for_mode_change_ack(struct ctlr_info *h);
247#define BOARD_NOT_READY 0 247#define BOARD_NOT_READY 0
248#define BOARD_READY 1 248#define BOARD_READY 1
249static void hpsa_drain_accel_commands(struct ctlr_info *h); 249static void hpsa_drain_accel_commands(struct ctlr_info *h);
@@ -6191,7 +6191,7 @@ static inline void hpsa_p600_dma_prefetch_quirk(struct ctlr_info *h)
6191 writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG); 6191 writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG);
6192} 6192}
6193 6193
6194static void hpsa_wait_for_clear_event_notify_ack(struct ctlr_info *h) 6194static int hpsa_wait_for_clear_event_notify_ack(struct ctlr_info *h)
6195{ 6195{
6196 int i; 6196 int i;
6197 u32 doorbell_value; 6197 u32 doorbell_value;
@@ -6202,13 +6202,16 @@ static void hpsa_wait_for_clear_event_notify_ack(struct ctlr_info *h)
6202 doorbell_value = readl(h->vaddr + SA5_DOORBELL); 6202 doorbell_value = readl(h->vaddr + SA5_DOORBELL);
6203 spin_unlock_irqrestore(&h->lock, flags); 6203 spin_unlock_irqrestore(&h->lock, flags);
6204 if (!(doorbell_value & DOORBELL_CLEAR_EVENTS)) 6204 if (!(doorbell_value & DOORBELL_CLEAR_EVENTS))
6205 break; 6205 goto done;
6206 /* delay and try again */ 6206 /* delay and try again */
6207 msleep(CLEAR_EVENT_WAIT_INTERVAL); 6207 msleep(CLEAR_EVENT_WAIT_INTERVAL);
6208 } 6208 }
6209 return -ENODEV;
6210done:
6211 return 0;
6209} 6212}
6210 6213
6211static void hpsa_wait_for_mode_change_ack(struct ctlr_info *h) 6214static int hpsa_wait_for_mode_change_ack(struct ctlr_info *h)
6212{ 6215{
6213 int i; 6216 int i;
6214 u32 doorbell_value; 6217 u32 doorbell_value;
@@ -6223,12 +6226,16 @@ static void hpsa_wait_for_mode_change_ack(struct ctlr_info *h)
6223 doorbell_value = readl(h->vaddr + SA5_DOORBELL); 6226 doorbell_value = readl(h->vaddr + SA5_DOORBELL);
6224 spin_unlock_irqrestore(&h->lock, flags); 6227 spin_unlock_irqrestore(&h->lock, flags);
6225 if (!(doorbell_value & CFGTBL_ChangeReq)) 6228 if (!(doorbell_value & CFGTBL_ChangeReq))
6226 break; 6229 goto done;
6227 /* delay and try again */ 6230 /* delay and try again */
6228 msleep(MODE_CHANGE_WAIT_INTERVAL); 6231 msleep(MODE_CHANGE_WAIT_INTERVAL);
6229 } 6232 }
6233 return -ENODEV;
6234done:
6235 return 0;
6230} 6236}
6231 6237
6238/* return -ENODEV or other reason on error, 0 on success */
6232static int hpsa_enter_simple_mode(struct ctlr_info *h) 6239static int hpsa_enter_simple_mode(struct ctlr_info *h)
6233{ 6240{
6234 u32 trans_support; 6241 u32 trans_support;
@@ -6243,7 +6250,8 @@ static int hpsa_enter_simple_mode(struct ctlr_info *h)
6243 writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest)); 6250 writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest));
6244 writel(0, &h->cfgtable->HostWrite.command_pool_addr_hi); 6251 writel(0, &h->cfgtable->HostWrite.command_pool_addr_hi);
6245 writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); 6252 writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
6246 hpsa_wait_for_mode_change_ack(h); 6253 if (hpsa_wait_for_mode_change_ack(h))
6254 goto error;
6247 print_cfg_table(&h->pdev->dev, h->cfgtable); 6255 print_cfg_table(&h->pdev->dev, h->cfgtable);
6248 if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) 6256 if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple))
6249 goto error; 6257 goto error;
@@ -7144,7 +7152,8 @@ static void calc_bucket_map(int bucket[], int num_buckets,
7144 } 7152 }
7145} 7153}
7146 7154
7147static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support) 7155/* return -ENODEV or other reason on error, 0 on success */
7156static int hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
7148{ 7157{
7149 int i; 7158 int i;
7150 unsigned long register_value; 7159 unsigned long register_value;
@@ -7236,12 +7245,16 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
7236 } 7245 }
7237 } 7246 }
7238 writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); 7247 writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
7239 hpsa_wait_for_mode_change_ack(h); 7248 if (hpsa_wait_for_mode_change_ack(h)) {
7249 dev_err(&h->pdev->dev,
7250 "performant mode problem - doorbell timeout\n");
7251 return -ENODEV;
7252 }
7240 register_value = readl(&(h->cfgtable->TransportActive)); 7253 register_value = readl(&(h->cfgtable->TransportActive));
7241 if (!(register_value & CFGTBL_Trans_Performant)) { 7254 if (!(register_value & CFGTBL_Trans_Performant)) {
7242 dev_err(&h->pdev->dev, 7255 dev_err(&h->pdev->dev,
7243 "performant mode problem - transport not active\n"); 7256 "performant mode problem - transport not active\n");
7244 return; 7257 return -ENODEV;
7245 } 7258 }
7246 /* Change the access methods to the performant access methods */ 7259 /* Change the access methods to the performant access methods */
7247 h->access = access; 7260 h->access = access;
@@ -7249,7 +7262,7 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
7249 7262
7250 if (!((trans_support & CFGTBL_Trans_io_accel1) || 7263 if (!((trans_support & CFGTBL_Trans_io_accel1) ||
7251 (trans_support & CFGTBL_Trans_io_accel2))) 7264 (trans_support & CFGTBL_Trans_io_accel2)))
7252 return; 7265 return 0;
7253 7266
7254 if (trans_support & CFGTBL_Trans_io_accel1) { 7267 if (trans_support & CFGTBL_Trans_io_accel1) {
7255 /* Set up I/O accelerator mode */ 7268 /* Set up I/O accelerator mode */
@@ -7313,7 +7326,12 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
7313 writel(bft2[i], &h->ioaccel2_bft2_regs[i]); 7326 writel(bft2[i], &h->ioaccel2_bft2_regs[i]);
7314 } 7327 }
7315 writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); 7328 writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
7316 hpsa_wait_for_mode_change_ack(h); 7329 if (hpsa_wait_for_mode_change_ack(h)) {
7330 dev_err(&h->pdev->dev,
7331 "performant mode problem - enabling ioaccel mode\n");
7332 return -ENODEV;
7333 }
7334 return 0;
7317} 7335}
7318 7336
7319static int hpsa_alloc_ioaccel_cmd_and_bft(struct ctlr_info *h) 7337static int hpsa_alloc_ioaccel_cmd_and_bft(struct ctlr_info *h)