diff mbox

[v4,20/43] hpsa: add more ioaccel2 error handling, including underrun statuses.

Message ID 20150416134833.30238.28782.stgit@brunhilda (mailing list archive)
State New, archived
Headers show

Commit Message

Don Brace April 16, 2015, 1:48 p.m. UTC
From: Joe Handzik <joseph.t.handzik@hp.com>

improve ioaccel2 error handling, including better handling of
underrun statuses

Reviewed-by: Scott Teel <scott.teel@pmcs.com>
Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
Signed-off-by: Joe Handzik <joseph.t.handzik@hp.com>
Signed-off-by: Don Brace <don.brace@pmcs.com>
---
 drivers/scsi/hpsa.c     |   33 ++++++++++++++++++++++++++++-----
 drivers/scsi/hpsa_cmd.h |    6 ++++++
 2 files changed, 34 insertions(+), 5 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Hannes Reinecke April 17, 2015, 1:15 p.m. UTC | #1
On 04/16/2015 03:48 PM, Don Brace wrote:
> From: Joe Handzik <joseph.t.handzik@hp.com>
> 
> improve ioaccel2 error handling, including better handling of
> underrun statuses
> 
> Reviewed-by: Scott Teel <scott.teel@pmcs.com>
> Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
> Signed-off-by: Joe Handzik <joseph.t.handzik@hp.com>
> Signed-off-by: Don Brace <don.brace@pmcs.com>
> ---
>  drivers/scsi/hpsa.c     |   33 ++++++++++++++++++++++++++++-----
>  drivers/scsi/hpsa_cmd.h |    6 ++++++
>  2 files changed, 34 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> index 1839761..fd9620d 100644
> --- a/drivers/scsi/hpsa.c
> +++ b/drivers/scsi/hpsa.c
> @@ -1868,6 +1868,7 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
>  {
>  	int data_len;
>  	int retry = 0;
> +	u32 ioaccel2_resid = 0;
>  
>  	switch (c2->error_data.serv_response) {
>  	case IOACCEL2_SERV_RESPONSE_COMPLETE:
> @@ -1926,11 +1927,33 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
>  		}
>  		break;
>  	case IOACCEL2_SERV_RESPONSE_FAILURE:
> -		/* don't expect to get here. */
> -		dev_warn(&h->pdev->dev,
> -			"unexpected delivery or target failure, status = 0x%02x\n",
> -			c2->error_data.status);
> -		retry = 1;
> +		switch (c2->error_data.status) {
> +		case IOACCEL2_STATUS_SR_IO_ERROR:
> +		case IOACCEL2_STATUS_SR_IO_ABORTED:
> +		case IOACCEL2_STATUS_SR_OVERRUN:
> +			retry = 1;
> +			break;
> +		case IOACCEL2_STATUS_SR_UNDERRUN:
> +			cmd->result = (DID_OK << 16);		/* host byte */
> +			cmd->result |= (COMMAND_COMPLETE << 8);	/* msg byte */
> +			ioaccel2_resid = c2->error_data.resid_cnt[3] << 24;
> +			ioaccel2_resid |= c2->error_data.resid_cnt[2] << 16;
> +			ioaccel2_resid |= c2->error_data.resid_cnt[1] << 8;
> +			ioaccel2_resid |= c2->error_data.resid_cnt[0];
> +			scsi_set_resid(cmd, ioaccel2_resid);
> +			break;
How curious. be32_to_cpu is probably a better choice here.

> +		case IOACCEL2_STATUS_SR_NO_PATH_TO_DEVICE:
> +		case IOACCEL2_STATUS_SR_INVALID_DEVICE:
> +		case IOACCEL2_STATUS_SR_IOACCEL_DISABLED:
> +			/* We will get an event from ctlr to trigger rescan */
> +			retry = 1;
> +			break;
> +		default:
> +			retry = 1;
> +			dev_warn(&h->pdev->dev,
> +				"unexpected delivery or target failure, status = 0x%02x\n",
> +				c2->error_data.status);
> +		}
>  		break;
>  	case IOACCEL2_SERV_RESPONSE_TMF_COMPLETE:
>  		break;
> diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
> index 0efb6f2b..cecb62b 100644
> --- a/drivers/scsi/hpsa_cmd.h
> +++ b/drivers/scsi/hpsa_cmd.h
> @@ -532,6 +532,12 @@ struct io_accel2_scsi_response {
>  #define IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL	0x28
>  #define IOACCEL2_STATUS_SR_TASK_COMP_ABORTED	0x40
>  #define IOACCEL2_STATUS_SR_IOACCEL_DISABLED	0x0E
> +#define IOACCEL2_STATUS_SR_IO_ERROR		0x01
> +#define IOACCEL2_STATUS_SR_IO_ABORTED		0x02
> +#define IOACCEL2_STATUS_SR_NO_PATH_TO_DEVICE	0x03
> +#define IOACCEL2_STATUS_SR_INVALID_DEVICE	0x04
> +#define IOACCEL2_STATUS_SR_UNDERRUN		0x51
> +#define IOACCEL2_STATUS_SR_OVERRUN		0x75
>  	u8 data_present;		/* low 2 bits */
>  #define IOACCEL2_NO_DATAPRESENT		0x000
>  #define IOACCEL2_RESPONSE_DATAPRESENT	0x001
> 
Cheers,

Hannes
diff mbox

Patch

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 1839761..fd9620d 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1868,6 +1868,7 @@  static int handle_ioaccel_mode2_error(struct ctlr_info *h,
 {
 	int data_len;
 	int retry = 0;
+	u32 ioaccel2_resid = 0;
 
 	switch (c2->error_data.serv_response) {
 	case IOACCEL2_SERV_RESPONSE_COMPLETE:
@@ -1926,11 +1927,33 @@  static int handle_ioaccel_mode2_error(struct ctlr_info *h,
 		}
 		break;
 	case IOACCEL2_SERV_RESPONSE_FAILURE:
-		/* don't expect to get here. */
-		dev_warn(&h->pdev->dev,
-			"unexpected delivery or target failure, status = 0x%02x\n",
-			c2->error_data.status);
-		retry = 1;
+		switch (c2->error_data.status) {
+		case IOACCEL2_STATUS_SR_IO_ERROR:
+		case IOACCEL2_STATUS_SR_IO_ABORTED:
+		case IOACCEL2_STATUS_SR_OVERRUN:
+			retry = 1;
+			break;
+		case IOACCEL2_STATUS_SR_UNDERRUN:
+			cmd->result = (DID_OK << 16);		/* host byte */
+			cmd->result |= (COMMAND_COMPLETE << 8);	/* msg byte */
+			ioaccel2_resid = c2->error_data.resid_cnt[3] << 24;
+			ioaccel2_resid |= c2->error_data.resid_cnt[2] << 16;
+			ioaccel2_resid |= c2->error_data.resid_cnt[1] << 8;
+			ioaccel2_resid |= c2->error_data.resid_cnt[0];
+			scsi_set_resid(cmd, ioaccel2_resid);
+			break;
+		case IOACCEL2_STATUS_SR_NO_PATH_TO_DEVICE:
+		case IOACCEL2_STATUS_SR_INVALID_DEVICE:
+		case IOACCEL2_STATUS_SR_IOACCEL_DISABLED:
+			/* We will get an event from ctlr to trigger rescan */
+			retry = 1;
+			break;
+		default:
+			retry = 1;
+			dev_warn(&h->pdev->dev,
+				"unexpected delivery or target failure, status = 0x%02x\n",
+				c2->error_data.status);
+		}
 		break;
 	case IOACCEL2_SERV_RESPONSE_TMF_COMPLETE:
 		break;
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 0efb6f2b..cecb62b 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -532,6 +532,12 @@  struct io_accel2_scsi_response {
 #define IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL	0x28
 #define IOACCEL2_STATUS_SR_TASK_COMP_ABORTED	0x40
 #define IOACCEL2_STATUS_SR_IOACCEL_DISABLED	0x0E
+#define IOACCEL2_STATUS_SR_IO_ERROR		0x01
+#define IOACCEL2_STATUS_SR_IO_ABORTED		0x02
+#define IOACCEL2_STATUS_SR_NO_PATH_TO_DEVICE	0x03
+#define IOACCEL2_STATUS_SR_INVALID_DEVICE	0x04
+#define IOACCEL2_STATUS_SR_UNDERRUN		0x51
+#define IOACCEL2_STATUS_SR_OVERRUN		0x75
 	u8 data_present;		/* low 2 bits */
 #define IOACCEL2_NO_DATAPRESENT		0x000
 #define IOACCEL2_RESPONSE_DATAPRESENT	0x001