Patchwork [4/7] scsi: Use SAM status codes

login
register
mail settings
Submitter Hannes Reinecke
Date June 15, 2010, 3:16 p.m.
Message ID <20100615151624.A3DF72B964@ochil.suse.de>
Download mbox | patch
Permalink /patch/55730/
State New
Headers show

Comments

Hannes Reinecke - June 15, 2010, 3:16 p.m.
Any SCSI emulation is supposed to return status codes as defined
by SAM, not the linux ones which are shifted by one.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 hw/megasas.c      |   12 +++++++-----
 hw/scsi-bus.c     |    4 +++-
 hw/scsi-defs.h    |   20 +++++++++++---------
 hw/scsi-generic.c |   12 ++++++------
 4 files changed, 27 insertions(+), 21 deletions(-)
Nicholas A. Bellinger - June 16, 2010, 8:59 a.m.
On Tue, 2010-06-15 at 17:16 +0200, Hannes Reinecke wrote:
> Any SCSI emulation is supposed to return status codes as defined
> by SAM, not the linux ones which are shifted by one.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> ---
>  hw/megasas.c      |   12 +++++++-----
>  hw/scsi-bus.c     |    4 +++-
>  hw/scsi-defs.h    |   20 +++++++++++---------
>  hw/scsi-generic.c |   12 ++++++------
>  4 files changed, 27 insertions(+), 21 deletions(-)
> 

Wow, good catch.  Commited.

--nab

> diff --git a/hw/megasas.c b/hw/megasas.c
> index 6ddb757..bc35566 100644
> --- a/hw/megasas.c
> +++ b/hw/megasas.c
> @@ -1125,7 +1125,7 @@ static int megasas_handle_scsi(MPTState *s, struct megasas_cmd_t *cmd, int is_lo
>                  cmd->frame->header.target_id, cmd->frame->header.lun_id,
>                  cmd->frame->header.cdb_len);
>          megasas_build_sense(cmd, SENSE_CODE(INVALID_OPCODE));
> -        megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION << 1);
> +        megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION);
>          s->event_count++;
>          return MFI_STAT_SCSI_DONE_WITH_ERROR;
>      }
> @@ -1177,7 +1177,7 @@ static int megasas_handle_io(MPTState *s, struct megasas_cmd_t *cmd)
>                  cmd->frame->header.target_id, cmd->frame->header.lun_id,
>                  cmd->frame->header.cdb_len);
>          megasas_build_sense(cmd, SENSE_CODE(INVALID_OPCODE));
> -        megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION << 1);
> +        megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION);
>          s->event_count++;
>          return MFI_STAT_SCSI_DONE_WITH_ERROR;
>      }
> @@ -1236,9 +1236,11 @@ static void megasas_command_complete(SCSIRequest *req)
>          DPRINTF_IO("%s req %p cmd %p lun %p finished with status %x len %u\n",
>                     mfi_frame_desc[cmd->frame->header.frame_cmd], req, cmd, cmd->sdev,
>                     req->status, (unsigned)req->xferlen);
> -        if (req->status == CHECK_CONDITION << 1) {
> -            megasas_build_sense(cmd, cmd->sdev->sense);
> +        if (req->status != GOOD) {
>              cmd_status = MFI_STAT_SCSI_DONE_WITH_ERROR;
> +        }
> +        if (req->status == CHECK_CONDITION) {
> +            megasas_build_sense(cmd, cmd->sdev->sense);
>              scsi_dev_clear_sense(cmd->sdev);
>          }
>  
> @@ -1302,7 +1304,7 @@ static void megasas_handle_frame(MPTState *s, target_phys_addr_t frame_addr,
>      cmd = megasas_enqueue_frame(s, frame_addr);
>      if (!cmd) {
>          /* reply queue full */
> -        megasas_frame_set_scsi_status(frame_addr, BUSY << 1);
> +        megasas_frame_set_scsi_status(frame_addr, BUSY);
>          frame_status = MFI_STAT_SCSI_DONE_WITH_ERROR;
>          s->event_count++;
>          goto frame_done;
> diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
> index 7d80405..c0e6dd3 100644
> --- a/hw/scsi-bus.c
> +++ b/hw/scsi-bus.c
> @@ -525,7 +525,9 @@ const char *scsi_status_name(uint8_t status)
>          [ INTERMEDIATE_C_GOOD  ] = "INTERMEDIATE_C_GOOD",
>          [ RESERVATION_CONFLICT ] = "RESERVATION_CONFLICT",
>          [ COMMAND_TERMINATED   ] = "COMMAND_TERMINATED",
> -        [ QUEUE_FULL           ] = "QUEUE_FULL",
> +        [ TASK_SET_FULL        ] = "TASK_SET_FULL",
> +        [ ACA_ACTIVE           ] = "ACA_ACTIVE",
> +        [ TASK_ABORTED         ] = "TASK_ABORTED",
>      };
>  
>      if (status >= ARRAY_SIZE(names) || names[status] == NULL)
> diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h
> index a4a3518..1473ecb 100644
> --- a/hw/scsi-defs.h
> +++ b/hw/scsi-defs.h
> @@ -111,18 +111,20 @@
>  #define BLANK 0xa1
>  
>  /*
> - *  Status codes
> + *  SAM Status codes
>   */
>  
>  #define GOOD                 0x00
> -#define CHECK_CONDITION      0x01
> -#define CONDITION_GOOD       0x02
> -#define BUSY                 0x04
> -#define INTERMEDIATE_GOOD    0x08
> -#define INTERMEDIATE_C_GOOD  0x0a
> -#define RESERVATION_CONFLICT 0x0c
> -#define COMMAND_TERMINATED   0x11
> -#define QUEUE_FULL           0x14
> +#define CHECK_CONDITION      0x02
> +#define CONDITION_GOOD       0x04
> +#define BUSY                 0x08
> +#define INTERMEDIATE_GOOD    0x10
> +#define INTERMEDIATE_C_GOOD  0x14
> +#define RESERVATION_CONFLICT 0x18
> +#define COMMAND_TERMINATED   0x22
> +#define TASK_SET_FULL        0x28
> +#define ACA_ACTIVE           0x30
> +#define TASK_ABORTED         0x40
>  
>  #define STATUS_MASK          0x3e
>  
> diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
> index af76826..33d7e52 100644
> --- a/hw/scsi-generic.c
> +++ b/hw/scsi-generic.c
> @@ -99,7 +99,7 @@ static void scsi_command_complete(void *opaque, int ret)
>  	if (ret == -EDOM) {
>  	    /* sg driver uses EDOM to signal queue busy */
>  	    fprintf(stderr, "%s: sg queue busy\n", __FUNCTION__);
> -	    r->req.status = QUEUE_FULL << 1;
> +	    r->req.status = TASK_SET_FULL;
>  	} else {
>  	    scsi_req_print(&r->req);
>  	    fprintf(stderr, "%s: ret %d (%s)\n", __FUNCTION__,
> @@ -107,13 +107,13 @@ static void scsi_command_complete(void *opaque, int ret)
>  	    s->senselen = scsi_build_sense(SENSE_CODE(INVALID_FIELD),
>  					   s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
>  	    s->driver_status = SG_ERR_DRIVER_SENSE;
> -	    r->req.status = CHECK_CONDITION << 1;
> +	    r->req.status = CHECK_CONDITION;
>  	}
>      } else {
>          if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
>              scsi_req_print(&r->req);
>              fprintf(stderr, "%s: timeout\n", __FUNCTION__);
> -            r->req.status = BUSY << 1;
> +            r->req.status = BUSY;
>          } else if (r->io_header.status) {
>  #if 0
>              scsi_req_print(&r->req);
> @@ -124,9 +124,9 @@ static void scsi_command_complete(void *opaque, int ret)
>          } else if (s->driver_status & SG_ERR_DRIVER_SENSE) {
>              scsi_req_print(&r->req);
>              fprintf(stderr, "%s: driver sense\n", __FUNCTION__);
> -            r->req.status = CHECK_CONDITION << 1;
> +            r->req.status = CHECK_CONDITION;
>          } else {
> -            r->req.status = GOOD << 1;
> +            r->req.status = GOOD;
>          }
>      }
>      DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
> @@ -451,7 +451,7 @@ static int scsi_generic_req_common(SCSIRequest *req, uint8_t *buffer)
>          s->senselen = scsi_build_sense(SENSE_CODE(LUN_NOT_SUPPORTED),
>  				       s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
>          s->driver_status = SG_ERR_DRIVER_SENSE;
> -        req->status = CHECK_CONDITION << 1;
> +        req->status = CHECK_CONDITION;
>          return 1;
>      }
>      if (r->req.cmd.buf[0] == REQUEST_SENSE &&

Patch

diff --git a/hw/megasas.c b/hw/megasas.c
index 6ddb757..bc35566 100644
--- a/hw/megasas.c
+++ b/hw/megasas.c
@@ -1125,7 +1125,7 @@  static int megasas_handle_scsi(MPTState *s, struct megasas_cmd_t *cmd, int is_lo
                 cmd->frame->header.target_id, cmd->frame->header.lun_id,
                 cmd->frame->header.cdb_len);
         megasas_build_sense(cmd, SENSE_CODE(INVALID_OPCODE));
-        megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION << 1);
+        megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION);
         s->event_count++;
         return MFI_STAT_SCSI_DONE_WITH_ERROR;
     }
@@ -1177,7 +1177,7 @@  static int megasas_handle_io(MPTState *s, struct megasas_cmd_t *cmd)
                 cmd->frame->header.target_id, cmd->frame->header.lun_id,
                 cmd->frame->header.cdb_len);
         megasas_build_sense(cmd, SENSE_CODE(INVALID_OPCODE));
-        megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION << 1);
+        megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION);
         s->event_count++;
         return MFI_STAT_SCSI_DONE_WITH_ERROR;
     }
@@ -1236,9 +1236,11 @@  static void megasas_command_complete(SCSIRequest *req)
         DPRINTF_IO("%s req %p cmd %p lun %p finished with status %x len %u\n",
                    mfi_frame_desc[cmd->frame->header.frame_cmd], req, cmd, cmd->sdev,
                    req->status, (unsigned)req->xferlen);
-        if (req->status == CHECK_CONDITION << 1) {
-            megasas_build_sense(cmd, cmd->sdev->sense);
+        if (req->status != GOOD) {
             cmd_status = MFI_STAT_SCSI_DONE_WITH_ERROR;
+        }
+        if (req->status == CHECK_CONDITION) {
+            megasas_build_sense(cmd, cmd->sdev->sense);
             scsi_dev_clear_sense(cmd->sdev);
         }
 
@@ -1302,7 +1304,7 @@  static void megasas_handle_frame(MPTState *s, target_phys_addr_t frame_addr,
     cmd = megasas_enqueue_frame(s, frame_addr);
     if (!cmd) {
         /* reply queue full */
-        megasas_frame_set_scsi_status(frame_addr, BUSY << 1);
+        megasas_frame_set_scsi_status(frame_addr, BUSY);
         frame_status = MFI_STAT_SCSI_DONE_WITH_ERROR;
         s->event_count++;
         goto frame_done;
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 7d80405..c0e6dd3 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -525,7 +525,9 @@  const char *scsi_status_name(uint8_t status)
         [ INTERMEDIATE_C_GOOD  ] = "INTERMEDIATE_C_GOOD",
         [ RESERVATION_CONFLICT ] = "RESERVATION_CONFLICT",
         [ COMMAND_TERMINATED   ] = "COMMAND_TERMINATED",
-        [ QUEUE_FULL           ] = "QUEUE_FULL",
+        [ TASK_SET_FULL        ] = "TASK_SET_FULL",
+        [ ACA_ACTIVE           ] = "ACA_ACTIVE",
+        [ TASK_ABORTED         ] = "TASK_ABORTED",
     };
 
     if (status >= ARRAY_SIZE(names) || names[status] == NULL)
diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h
index a4a3518..1473ecb 100644
--- a/hw/scsi-defs.h
+++ b/hw/scsi-defs.h
@@ -111,18 +111,20 @@ 
 #define BLANK 0xa1
 
 /*
- *  Status codes
+ *  SAM Status codes
  */
 
 #define GOOD                 0x00
-#define CHECK_CONDITION      0x01
-#define CONDITION_GOOD       0x02
-#define BUSY                 0x04
-#define INTERMEDIATE_GOOD    0x08
-#define INTERMEDIATE_C_GOOD  0x0a
-#define RESERVATION_CONFLICT 0x0c
-#define COMMAND_TERMINATED   0x11
-#define QUEUE_FULL           0x14
+#define CHECK_CONDITION      0x02
+#define CONDITION_GOOD       0x04
+#define BUSY                 0x08
+#define INTERMEDIATE_GOOD    0x10
+#define INTERMEDIATE_C_GOOD  0x14
+#define RESERVATION_CONFLICT 0x18
+#define COMMAND_TERMINATED   0x22
+#define TASK_SET_FULL        0x28
+#define ACA_ACTIVE           0x30
+#define TASK_ABORTED         0x40
 
 #define STATUS_MASK          0x3e
 
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index af76826..33d7e52 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -99,7 +99,7 @@  static void scsi_command_complete(void *opaque, int ret)
 	if (ret == -EDOM) {
 	    /* sg driver uses EDOM to signal queue busy */
 	    fprintf(stderr, "%s: sg queue busy\n", __FUNCTION__);
-	    r->req.status = QUEUE_FULL << 1;
+	    r->req.status = TASK_SET_FULL;
 	} else {
 	    scsi_req_print(&r->req);
 	    fprintf(stderr, "%s: ret %d (%s)\n", __FUNCTION__,
@@ -107,13 +107,13 @@  static void scsi_command_complete(void *opaque, int ret)
 	    s->senselen = scsi_build_sense(SENSE_CODE(INVALID_FIELD),
 					   s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
 	    s->driver_status = SG_ERR_DRIVER_SENSE;
-	    r->req.status = CHECK_CONDITION << 1;
+	    r->req.status = CHECK_CONDITION;
 	}
     } else {
         if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
             scsi_req_print(&r->req);
             fprintf(stderr, "%s: timeout\n", __FUNCTION__);
-            r->req.status = BUSY << 1;
+            r->req.status = BUSY;
         } else if (r->io_header.status) {
 #if 0
             scsi_req_print(&r->req);
@@ -124,9 +124,9 @@  static void scsi_command_complete(void *opaque, int ret)
         } else if (s->driver_status & SG_ERR_DRIVER_SENSE) {
             scsi_req_print(&r->req);
             fprintf(stderr, "%s: driver sense\n", __FUNCTION__);
-            r->req.status = CHECK_CONDITION << 1;
+            r->req.status = CHECK_CONDITION;
         } else {
-            r->req.status = GOOD << 1;
+            r->req.status = GOOD;
         }
     }
     DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
@@ -451,7 +451,7 @@  static int scsi_generic_req_common(SCSIRequest *req, uint8_t *buffer)
         s->senselen = scsi_build_sense(SENSE_CODE(LUN_NOT_SUPPORTED),
 				       s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
         s->driver_status = SG_ERR_DRIVER_SENSE;
-        req->status = CHECK_CONDITION << 1;
+        req->status = CHECK_CONDITION;
         return 1;
     }
     if (r->req.cmd.buf[0] == REQUEST_SENSE &&