[SCSI] megaraid: simplify internal command handling
authorChristoph Hellwig <hch@infradead.org>
Thu, 20 Feb 2014 22:20:59 +0000 (14:20 -0800)
committerJames Bottomley <JBottomley@Parallels.com>
Thu, 27 Mar 2014 15:26:31 +0000 (08:26 -0700)
We don't use the passed in scsi command for anything, so just add a adapter-
wide internal status to go along with the internal scb that is used unter
int_mtx to pass back the return value and get rid of all the complexities
and abuse of the scsi_cmnd structure.

This gets rid of the only user of scsi_allocate_command/scsi_free_command,
which can now be removed.

[jejb: checkpatch fixes]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Adam Radford <aradford@gmail.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/scsi.c
include/scsi/scsi_cmnd.h

index 816db12ef5d555159226c5eb618b110ebb790776..b7770516f4c2dc5ebfda41727fec541c47dff6c6 100644 (file)
@@ -531,13 +531,6 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
        int     target = 0;
        int     ldrv_num = 0;   /* logical drive number */
 
-
-       /*
-        * filter the internal and ioctl commands
-        */
-       if((cmd->cmnd[0] == MEGA_INTERNAL_CMD))
-               return (scb_t *)cmd->host_scribble;
-
        /*
         * We know what channels our logical drives are on - mega_find_card()
         */
@@ -1439,19 +1432,22 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
 
                cmdid = completed[i];
 
-               if( cmdid == CMDID_INT_CMDS ) { /* internal command */
+               /*
+                * Only free SCBs for the commands coming down from the
+                * mid-layer, not for which were issued internally
+                *
+                * For internal command, restore the status returned by the
+                * firmware so that user can interpret it.
+                */
+               if (cmdid == CMDID_INT_CMDS) {
                        scb = &adapter->int_scb;
-                       cmd = scb->cmd;
-                       mbox = (mbox_t *)scb->raw_mbox;
 
-                       /*
-                        * Internal command interface do not fire the extended
-                        * passthru or 64-bit passthru
-                        */
-                       pthru = scb->pthru;
+                       list_del_init(&scb->list);
+                       scb->state = SCB_FREE;
 
-               }
-               else {
+                       adapter->int_status = status;
+                       complete(&adapter->int_waitq);
+               } else {
                        scb = &adapter->scb_list[cmdid];
 
                        /*
@@ -1640,25 +1636,7 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
                                cmd->result |= (DID_BAD_TARGET << 16)|status;
                }
 
-               /*
-                * Only free SCBs for the commands coming down from the
-                * mid-layer, not for which were issued internally
-                *
-                * For internal command, restore the status returned by the
-                * firmware so that user can interpret it.
-                */
-               if( cmdid == CMDID_INT_CMDS ) { /* internal command */
-                       cmd->result = status;
-
-                       /*
-                        * Remove the internal command from the pending list
-                        */
-                       list_del_init(&scb->list);
-                       scb->state = SCB_FREE;
-               }
-               else {
-                       mega_free_scb(adapter, scb);
-               }
+               mega_free_scb(adapter, scb);
 
                /* Add Scsi_Command to end of completed queue */
                list_add_tail(SCSI_LIST(cmd), &adapter->completed_list);
@@ -4133,23 +4111,15 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt,
  * The last argument is the address of the passthru structure if the command
  * to be fired is a passthru command
  *
- * lockscope specifies whether the caller has already acquired the lock. Of
- * course, the caller must know which lock we are talking about.
- *
  * Note: parameter 'pthru' is null for non-passthru commands.
  */
 static int
 mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
 {
-       Scsi_Cmnd       *scmd;
-       struct  scsi_device *sdev;
+       unsigned long flags;
        scb_t   *scb;
        int     rval;
 
-       scmd = scsi_allocate_command(GFP_KERNEL);
-       if (!scmd)
-               return -ENOMEM;
-
        /*
         * The internal commands share one command id and hence are
         * serialized. This is so because we want to reserve maximum number of
@@ -4160,73 +4130,45 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
        scb = &adapter->int_scb;
        memset(scb, 0, sizeof(scb_t));
 
-       sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
-       scmd->device = sdev;
-
-       memset(adapter->int_cdb, 0, sizeof(adapter->int_cdb));
-       scmd->cmnd = adapter->int_cdb;
-       scmd->device->host = adapter->host;
-       scmd->host_scribble = (void *)scb;
-       scmd->cmnd[0] = MEGA_INTERNAL_CMD;
-
-       scb->state |= SCB_ACTIVE;
-       scb->cmd = scmd;
+       scb->idx = CMDID_INT_CMDS;
+       scb->state |= SCB_ACTIVE | SCB_PENDQ;
 
        memcpy(scb->raw_mbox, mc, sizeof(megacmd_t));
 
        /*
         * Is it a passthru command
         */
-       if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
-
+       if (mc->cmd == MEGA_MBOXCMD_PASSTHRU)
                scb->pthru = pthru;
-       }
-
-       scb->idx = CMDID_INT_CMDS;
 
-       megaraid_queue_lck(scmd, mega_internal_done);
+       spin_lock_irqsave(&adapter->lock, flags);
+       list_add_tail(&scb->list, &adapter->pending_list);
+       /*
+        * Check if the HBA is in quiescent state, e.g., during a
+        * delete logical drive opertion. If it is, don't run
+        * the pending_list.
+        */
+       if (atomic_read(&adapter->quiescent) == 0)
+               mega_runpendq(adapter);
+       spin_unlock_irqrestore(&adapter->lock, flags);
 
        wait_for_completion(&adapter->int_waitq);
 
-       rval = scmd->result;
-       mc->status = scmd->result;
-       kfree(sdev);
+       mc->status = rval = adapter->int_status;
 
        /*
         * Print a debug message for all failed commands. Applications can use
         * this information.
         */
-       if( scmd->result && trace_level ) {
+       if (rval && trace_level) {
                printk("megaraid: cmd [%x, %x, %x] status:[%x]\n",
-                       mc->cmd, mc->opcode, mc->subopcode, scmd->result);
+                       mc->cmd, mc->opcode, mc->subopcode, rval);
        }
 
        mutex_unlock(&adapter->int_mtx);
-
-       scsi_free_command(GFP_KERNEL, scmd);
-
        return rval;
 }
 
-
-/**
- * mega_internal_done()
- * @scmd - internal scsi command
- *
- * Callback routine for internal commands.
- */
-static void
-mega_internal_done(Scsi_Cmnd *scmd)
-{
-       adapter_t       *adapter;
-
-       adapter = (adapter_t *)scmd->device->host->hostdata;
-
-       complete(&adapter->int_waitq);
-
-}
-
-
 static struct scsi_host_template megaraid_template = {
        .module                         = THIS_MODULE,
        .name                           = "MegaRAID",
index 4d0ce4e78dfd582a2f4e5e0fabeefae8b8285f21..508d65e5a5184d3259e85fadeea3d846863f492a 100644 (file)
@@ -853,10 +853,10 @@ typedef struct {
 
        u8      sglen;  /* f/w supported scatter-gather list length */
 
-       unsigned char int_cdb[MAX_COMMAND_SIZE];
        scb_t                   int_scb;
        struct mutex            int_mtx;        /* To synchronize the internal
                                                commands */
+       int                     int_status;     /* status of internal cmd */
        struct completion       int_waitq;      /* wait queue for internal
                                                 cmds */
 
@@ -1004,7 +1004,6 @@ static int mega_del_logdrv(adapter_t *, int);
 static int mega_do_del_logdrv(adapter_t *, int);
 static void mega_get_max_sgl(adapter_t *);
 static int mega_internal_command(adapter_t *, megacmd_t *, mega_passthru *);
-static void mega_internal_done(Scsi_Cmnd *);
 static int mega_support_cluster(adapter_t *);
 #endif
 
index 1d98ac96088741a158472c4c670f3ae84fb5555c..c4dd0bfc663a1b212c5929cd7d206fabb5651753 100644 (file)
@@ -402,62 +402,6 @@ static void scsi_put_host_cmd_pool(gfp_t gfp_mask)
        mutex_unlock(&host_cmd_pool_mutex);
 }
 
-/**
- * scsi_allocate_command - get a fully allocated SCSI command
- * @gfp_mask:  allocation mask
- *
- * This function is for use outside of the normal host based pools.
- * It allocates the relevant command and takes an additional reference
- * on the pool it used.  This function *must* be paired with
- * scsi_free_command which also has the identical mask, otherwise the
- * free pool counts will eventually go wrong and you'll trigger a bug.
- *
- * This function should *only* be used by drivers that need a static
- * command allocation at start of day for internal functions.
- */
-struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask)
-{
-       struct scsi_host_cmd_pool *pool = scsi_get_host_cmd_pool(gfp_mask);
-
-       if (!pool)
-               return NULL;
-
-       return scsi_pool_alloc_command(pool, gfp_mask);
-}
-EXPORT_SYMBOL(scsi_allocate_command);
-
-/**
- * scsi_free_command - free a command allocated by scsi_allocate_command
- * @gfp_mask:  mask used in the original allocation
- * @cmd:       command to free
- *
- * Note: using the original allocation mask is vital because that's
- * what determines which command pool we use to free the command.  Any
- * mismatch will cause the system to BUG eventually.
- */
-void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd)
-{
-       struct scsi_host_cmd_pool *pool = scsi_get_host_cmd_pool(gfp_mask);
-
-       /*
-        * this could trigger if the mask to scsi_allocate_command
-        * doesn't match this mask.  Otherwise we're guaranteed that this
-        * succeeds because scsi_allocate_command must have taken a reference
-        * on the pool
-        */
-       BUG_ON(!pool);
-
-       scsi_pool_free_command(pool, cmd);
-       /*
-        * scsi_put_host_cmd_pool is called twice; once to release the
-        * reference we took above, and once to release the reference
-        * originally taken by scsi_allocate_command
-        */
-       scsi_put_host_cmd_pool(gfp_mask);
-       scsi_put_host_cmd_pool(gfp_mask);
-}
-EXPORT_SYMBOL(scsi_free_command);
-
 /**
  * scsi_setup_command_freelist - Setup the command freelist for a scsi host.
  * @shost: host to allocate the freelist for.
index 414edf9b12720ce09c176d89eb622d4383b9407a..dd7c998221b3e7a0253c11426a7940a328279248 100644 (file)
@@ -155,9 +155,6 @@ extern void scsi_release_buffers(struct scsi_cmnd *cmd);
 extern int scsi_dma_map(struct scsi_cmnd *cmd);
 extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
 
-struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask);
-void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd);
-
 static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)
 {
        return cmd->sdb.table.nents;