aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hpsa.c
diff options
context:
space:
mode:
authorRobert Elliott <elliott@hp.com>2015-01-23 17:45:01 -0500
committerJames Bottomley <JBottomley@Parallels.com>2015-02-02 12:57:44 -0500
commitc706a7954a160ddc1a29e1dfe4dc1f58e2b95023 (patch)
tree2a99497688d8427753f6fcf76a4e5a946adeb9b6 /drivers/scsi/hpsa.c
parent007e7aa9b37d570fc5917522a6f6bcca14264632 (diff)
hpsa: detect and report failures changing controller transport modes
Detect failues when attempting to change controller to use simple or performant transport modes (mode change ack) rather than just proceeding ahead after timeouts. Return values are added to: hpsa_put_ctlr_into_performant_mode hpsa_wait_for_mode_change_ack and all their callers check/propagate the result. More consistency in printing errors and whether dev_err is used. Reviewed-by: Scott Teel <scott.teel@pmcs.com> Signed-off-by: Robert Elliott <elliott@hp.com> Signed-off-by: Don Brace <don.brace@pmcs.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-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)