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>
This commit is contained in:
parent
007e7aa9b3
commit
c706a7954a
|
@ -243,7 +243,7 @@ static int hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id);
|
||||||
static int hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr,
|
static int hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr,
|
||||||
int wait_for_ready);
|
int wait_for_ready);
|
||||||
static inline void finish_cmd(struct CommandList *c);
|
static inline void finish_cmd(struct CommandList *c);
|
||||||
static void hpsa_wait_for_mode_change_ack(struct ctlr_info *h);
|
static int hpsa_wait_for_mode_change_ack(struct ctlr_info *h);
|
||||||
#define BOARD_NOT_READY 0
|
#define BOARD_NOT_READY 0
|
||||||
#define BOARD_READY 1
|
#define BOARD_READY 1
|
||||||
static void hpsa_drain_accel_commands(struct ctlr_info *h);
|
static 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)
|
||||||
writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG);
|
writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hpsa_wait_for_clear_event_notify_ack(struct ctlr_info *h)
|
static int hpsa_wait_for_clear_event_notify_ack(struct ctlr_info *h)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u32 doorbell_value;
|
u32 doorbell_value;
|
||||||
|
@ -6202,13 +6202,16 @@ static void hpsa_wait_for_clear_event_notify_ack(struct ctlr_info *h)
|
||||||
doorbell_value = readl(h->vaddr + SA5_DOORBELL);
|
doorbell_value = readl(h->vaddr + SA5_DOORBELL);
|
||||||
spin_unlock_irqrestore(&h->lock, flags);
|
spin_unlock_irqrestore(&h->lock, flags);
|
||||||
if (!(doorbell_value & DOORBELL_CLEAR_EVENTS))
|
if (!(doorbell_value & DOORBELL_CLEAR_EVENTS))
|
||||||
break;
|
goto done;
|
||||||
/* delay and try again */
|
/* delay and try again */
|
||||||
msleep(CLEAR_EVENT_WAIT_INTERVAL);
|
msleep(CLEAR_EVENT_WAIT_INTERVAL);
|
||||||
}
|
}
|
||||||
|
return -ENODEV;
|
||||||
|
done:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hpsa_wait_for_mode_change_ack(struct ctlr_info *h)
|
static int hpsa_wait_for_mode_change_ack(struct ctlr_info *h)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u32 doorbell_value;
|
u32 doorbell_value;
|
||||||
|
@ -6223,12 +6226,16 @@ static void hpsa_wait_for_mode_change_ack(struct ctlr_info *h)
|
||||||
doorbell_value = readl(h->vaddr + SA5_DOORBELL);
|
doorbell_value = readl(h->vaddr + SA5_DOORBELL);
|
||||||
spin_unlock_irqrestore(&h->lock, flags);
|
spin_unlock_irqrestore(&h->lock, flags);
|
||||||
if (!(doorbell_value & CFGTBL_ChangeReq))
|
if (!(doorbell_value & CFGTBL_ChangeReq))
|
||||||
break;
|
goto done;
|
||||||
/* delay and try again */
|
/* delay and try again */
|
||||||
msleep(MODE_CHANGE_WAIT_INTERVAL);
|
msleep(MODE_CHANGE_WAIT_INTERVAL);
|
||||||
}
|
}
|
||||||
|
return -ENODEV;
|
||||||
|
done:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return -ENODEV or other reason on error, 0 on success */
|
||||||
static int hpsa_enter_simple_mode(struct ctlr_info *h)
|
static int hpsa_enter_simple_mode(struct ctlr_info *h)
|
||||||
{
|
{
|
||||||
u32 trans_support;
|
u32 trans_support;
|
||||||
|
@ -6243,7 +6250,8 @@ static int hpsa_enter_simple_mode(struct ctlr_info *h)
|
||||||
writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest));
|
writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest));
|
||||||
writel(0, &h->cfgtable->HostWrite.command_pool_addr_hi);
|
writel(0, &h->cfgtable->HostWrite.command_pool_addr_hi);
|
||||||
writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
|
writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
|
||||||
hpsa_wait_for_mode_change_ack(h);
|
if (hpsa_wait_for_mode_change_ack(h))
|
||||||
|
goto error;
|
||||||
print_cfg_table(&h->pdev->dev, h->cfgtable);
|
print_cfg_table(&h->pdev->dev, h->cfgtable);
|
||||||
if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple))
|
if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple))
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -7144,7 +7152,8 @@ static void calc_bucket_map(int bucket[], int num_buckets,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
|
/* return -ENODEV or other reason on error, 0 on success */
|
||||||
|
static int hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned long register_value;
|
unsigned long register_value;
|
||||||
|
@ -7236,12 +7245,16 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
|
writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
|
||||||
hpsa_wait_for_mode_change_ack(h);
|
if (hpsa_wait_for_mode_change_ack(h)) {
|
||||||
|
dev_err(&h->pdev->dev,
|
||||||
|
"performant mode problem - doorbell timeout\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
register_value = readl(&(h->cfgtable->TransportActive));
|
register_value = readl(&(h->cfgtable->TransportActive));
|
||||||
if (!(register_value & CFGTBL_Trans_Performant)) {
|
if (!(register_value & CFGTBL_Trans_Performant)) {
|
||||||
dev_err(&h->pdev->dev,
|
dev_err(&h->pdev->dev,
|
||||||
"performant mode problem - transport not active\n");
|
"performant mode problem - transport not active\n");
|
||||||
return;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
/* Change the access methods to the performant access methods */
|
/* Change the access methods to the performant access methods */
|
||||||
h->access = access;
|
h->access = access;
|
||||||
|
@ -7249,7 +7262,7 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
|
||||||
|
|
||||||
if (!((trans_support & CFGTBL_Trans_io_accel1) ||
|
if (!((trans_support & CFGTBL_Trans_io_accel1) ||
|
||||||
(trans_support & CFGTBL_Trans_io_accel2)))
|
(trans_support & CFGTBL_Trans_io_accel2)))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if (trans_support & CFGTBL_Trans_io_accel1) {
|
if (trans_support & CFGTBL_Trans_io_accel1) {
|
||||||
/* Set up I/O accelerator mode */
|
/* Set up I/O accelerator mode */
|
||||||
|
@ -7313,7 +7326,12 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
|
||||||
writel(bft2[i], &h->ioaccel2_bft2_regs[i]);
|
writel(bft2[i], &h->ioaccel2_bft2_regs[i]);
|
||||||
}
|
}
|
||||||
writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
|
writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
|
||||||
hpsa_wait_for_mode_change_ack(h);
|
if (hpsa_wait_for_mode_change_ack(h)) {
|
||||||
|
dev_err(&h->pdev->dev,
|
||||||
|
"performant mode problem - enabling ioaccel mode\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hpsa_alloc_ioaccel_cmd_and_bft(struct ctlr_info *h)
|
static int hpsa_alloc_ioaccel_cmd_and_bft(struct ctlr_info *h)
|
||||||
|
|
Loading…
Reference in New Issue