Re: [PATCH 02/17] megaraid: simplify internal command handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Neela,

can you look over this from the megaraid perspective?

On Wed, Feb 05, 2014 at 04:39:32AM -0800, Christoph Hellwig wrote:
> 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.
> 
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
> ---
>  drivers/scsi/megaraid.c |  120 ++++++++++++-----------------------------------
>  drivers/scsi/megaraid.h |    3 +-
>  2 files changed, 32 insertions(+), 91 deletions(-)
> 
> diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
> index 816db12..8bca30f 100644
> --- a/drivers/scsi/megaraid.c
> +++ b/drivers/scsi/megaraid.c
> @@ -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",
> diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
> index 4d0ce4e..8f2e026 100644
> --- a/drivers/scsi/megaraid.h
> +++ b/drivers/scsi/megaraid.h
> @@ -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
>  
> -- 
> 1.7.10.4
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
---end quoted text---
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux