cciss: factor out core of sendcmd_withirq() for use by SCSI error handling code
authorscameron@beardog.cca.cpqcorp.net <scameron@beardog.cca.cpqcorp.net>
Mon, 8 Jun 2009 21:01:11 +0000 (16:01 -0500)
committerJens Axboe <jens.axboe@oracle.com>
Tue, 9 Jun 2009 03:47:42 +0000 (05:47 +0200)
Factor the core of sendcmd_withirq out to provide a simpler interface
which provides access to full error information.

Signed-off-by: Stephen M. Cameron <scameron@beardog.cca.cpqcorp.net>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
drivers/block/cciss.c

index e7d00952dd4fe23b6013fc50b06944f62d505a3e..74fc85aded921156b1d6eb86e1a34d59bd20dda9 100644 (file)
@@ -2278,114 +2278,123 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_
        return status;
 }
 
-static int sendcmd_withirq(__u8 cmd,
-                          int ctlr,
-                          void *buff,
-                          size_t size,
-                          unsigned int use_unit_num,
-                          unsigned int log_unit, __u8 page_code, int cmd_type)
+static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c)
 {
-       ctlr_info_t *h = hba[ctlr];
-       CommandList_struct *c;
+       DECLARE_COMPLETION_ONSTACK(wait);
        u64bit buff_dma_handle;
        unsigned long flags;
-       int return_status;
-       DECLARE_COMPLETION_ONSTACK(wait);
+       int return_status = IO_OK;
 
-       if ((c = cmd_alloc(h, 0)) == NULL)
-               return -ENOMEM;
-       return_status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
-                                log_unit, page_code, NULL, cmd_type);
-       if (return_status != IO_OK) {
-               cmd_free(h, c, 0);
-               return return_status;
-       }
-      resend_cmd2:
+resend_cmd2:
        c->waiting = &wait;
-
        /* Put the request on the tail of the queue and send it */
-       spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
+       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
        addQ(&h->reqQ, c);
        h->Qdepth++;
        start_io(h);
-       spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
 
        wait_for_completion(&wait);
 
-       if (c->err_info->CommandStatus != 0) {  /* an error has occurred */
-               switch (c->err_info->CommandStatus) {
-               case CMD_TARGET_STATUS:
-                       printk(KERN_WARNING "cciss: cmd %p has "
-                              " completed with errors\n", c);
-                       if (c->err_info->ScsiStatus) {
-                               printk(KERN_WARNING "cciss: cmd %p "
-                                      "has SCSI Status = %x\n",
-                                      c, c->err_info->ScsiStatus);
-                       }
+       if (c->err_info->CommandStatus == 0)
+               goto command_done;
 
-                       break;
-               case CMD_DATA_UNDERRUN:
-               case CMD_DATA_OVERRUN:
-                       /* expected for inquire and report lun commands */
-                       break;
-               case CMD_INVALID:
-                       printk(KERN_WARNING "cciss: Cmd %p is "
-                              "reported invalid\n", c);
-                       return_status = IO_ERROR;
-                       break;
-               case CMD_PROTOCOL_ERR:
-                       printk(KERN_WARNING "cciss: cmd %p has "
-                              "protocol error \n", c);
-                       return_status = IO_ERROR;
-                       break;
-               case CMD_HARDWARE_ERR:
-                       printk(KERN_WARNING "cciss: cmd %p had "
-                              " hardware error\n", c);
-                       return_status = IO_ERROR;
-                       break;
-               case CMD_CONNECTION_LOST:
-                       printk(KERN_WARNING "cciss: cmd %p had "
-                              "connection lost\n", c);
-                       return_status = IO_ERROR;
-                       break;
-               case CMD_ABORTED:
-                       printk(KERN_WARNING "cciss: cmd %p was "
-                              "aborted\n", c);
-                       return_status = IO_ERROR;
-                       break;
-               case CMD_ABORT_FAILED:
-                       printk(KERN_WARNING "cciss: cmd %p reports "
-                              "abort failed\n", c);
-                       return_status = IO_ERROR;
-                       break;
-               case CMD_UNSOLICITED_ABORT:
+       switch (c->err_info->CommandStatus) {
+       case CMD_TARGET_STATUS:
+               printk(KERN_WARNING "cciss: cmd 0x%02x "
+               "has completed with errors\n", c->Request.CDB[0]);
+               if (c->err_info->ScsiStatus) {
+                       printk(KERN_WARNING "cciss: cmd 0x%02x "
+                              "has SCSI Status = %x\n",
+                              c->Request.CDB[0], c->err_info->ScsiStatus);
+               }
+               break;
+       case CMD_DATA_UNDERRUN:
+       case CMD_DATA_OVERRUN:
+               /* expected for inquiry and report lun commands */
+               break;
+       case CMD_INVALID:
+               printk(KERN_WARNING "cciss: Cmd 0x%02x is "
+                      "reported invalid\n", c->Request.CDB[0]);
+               return_status = IO_ERROR;
+               break;
+       case CMD_PROTOCOL_ERR:
+               printk(KERN_WARNING "cciss: cmd 0x%02x has "
+                      "protocol error \n", c->Request.CDB[0]);
+               return_status = IO_ERROR;
+               break;
+       case CMD_HARDWARE_ERR:
+               printk(KERN_WARNING "cciss: cmd 0x%02x had "
+                      " hardware error\n", c->Request.CDB[0]);
+               return_status = IO_ERROR;
+               break;
+       case CMD_CONNECTION_LOST:
+               printk(KERN_WARNING "cciss: cmd 0x%02x had "
+                      "connection lost\n", c->Request.CDB[0]);
+               return_status = IO_ERROR;
+               break;
+       case CMD_ABORTED:
+               printk(KERN_WARNING "cciss: cmd 0x%02x was "
+                      "aborted\n", c->Request.CDB[0]);
+               return_status = IO_ERROR;
+               break;
+       case CMD_ABORT_FAILED:
+               printk(KERN_WARNING "cciss: cmd 0x%02x reports "
+                      "abort failed\n", c->Request.CDB[0]);
+               return_status = IO_ERROR;
+               break;
+       case CMD_UNSOLICITED_ABORT:
+               printk(KERN_WARNING
+                      "cciss%d: unsolicited abort 0x%02x\n", h->ctlr,
+                       c->Request.CDB[0]);
+               if (c->retry_count < MAX_CMD_RETRIES) {
                        printk(KERN_WARNING
-                              "cciss%d: unsolicited abort %p\n", ctlr, c);
-                       if (c->retry_count < MAX_CMD_RETRIES) {
-                               printk(KERN_WARNING
-                                      "cciss%d: retrying %p\n", ctlr, c);
-                               c->retry_count++;
-                               /* erase the old error information */
-                               memset(c->err_info, 0,
-                                      sizeof(ErrorInfo_struct));
-                               return_status = IO_OK;
-                               INIT_COMPLETION(wait);
-                               goto resend_cmd2;
-                       }
-                       return_status = IO_ERROR;
-                       break;
-               default:
-                       printk(KERN_WARNING "cciss: cmd %p returned "
-                              "unknown status %x\n", c,
-                              c->err_info->CommandStatus);
-                       return_status = IO_ERROR;
+                              "cciss%d: retrying 0x%02x\n", h->ctlr,
+                               c->Request.CDB[0]);
+                       c->retry_count++;
+                       /* erase the old error information */
+                       memset(c->err_info, 0,
+                              sizeof(ErrorInfo_struct));
+                       return_status = IO_OK;
+                       INIT_COMPLETION(wait);
+                       goto resend_cmd2;
                }
+               return_status = IO_ERROR;
+               break;
+       default:
+               printk(KERN_WARNING "cciss: cmd 0x%02x returned "
+                      "unknown status %x\n", c->Request.CDB[0],
+                      c->err_info->CommandStatus);
+               return_status = IO_ERROR;
        }
+
+command_done:
        /* unlock the buffers from DMA */
        buff_dma_handle.val32.lower = c->SG[0].Addr.lower;
        buff_dma_handle.val32.upper = c->SG[0].Addr.upper;
        pci_unmap_single(h->pdev, (dma_addr_t) buff_dma_handle.val,
                         c->SG[0].Len, PCI_DMA_BIDIRECTIONAL);
+       return return_status;
+}
+
+static int sendcmd_withirq(__u8 cmd,
+                          int ctlr,
+                          void *buff,
+                          size_t size,
+                          unsigned int use_unit_num,
+                          unsigned int log_unit, __u8 page_code, int cmd_type)
+{
+       ctlr_info_t *h = hba[ctlr];
+       CommandList_struct *c;
+       int return_status;
+
+       c = cmd_alloc(h, 0);
+       if (!c)
+               return -ENOMEM;
+       return_status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
+                                log_unit, page_code, NULL, cmd_type);
+       if (return_status == IO_OK)
+               return_status = sendcmd_withirq_core(h, c);
        cmd_free(h, c, 0);
        return return_status;
 }