public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
       [not found] <20060603112610.GB17018@lst.de>
@ 2006-06-03 11:31 ` Christoph Hellwig
  2006-06-10 16:08 ` Christoph Hellwig
  2006-07-24 17:27 ` Tony Luck
  2 siblings, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2006-06-03 11:31 UTC (permalink / raw)
  To: jejb; +Cc: fischer, linux-kernel, linux-scsi

This should have gone to linux-scsi of course.  Fup'to to -scsi instead
of -kernel please.

On Sat, Jun 03, 2006 at 01:26:10PM +0200, Christoph Hellwig wrote:
> Currently struct scsi_cmnd has various fields that are used to backup
> original data after the corresponding fields have been overridden for
> EH commands.  This means drivers can easily get at it and misuse it.
> Due to the old_ naming this doesn't happen for most of them, but two
> that have different names have been used wrong a lot (see previous
> patch).  Another downside is that they unessecarily bloat the scsi_cmnd
> size.
> 
> This patch moves them onstack in scsi_send_eh_cmnd to fix those two
> issues above.
> 
> Note that this breaks the aha152x and 53x700 drivers because they're
> plaing with those fields internally.
> 
> J"urgen and James, could you take a look at whether it's feasible to
> fix those drivers?
> 
> Otherwise any comments on the general approach?
> 
> (Note:  you probably want the patch to remove the wrong buffer and
>  bufflen patches applied before this, else lots of drivers will stop
>  compiling)
> 
> Index: scsi-misc-2.6/drivers/scsi/scsi_error.c
> ===================================================================
> --- scsi-misc-2.6.orig/drivers/scsi/scsi_error.c	2006-06-02 18:20:23.000000000 +0200
> +++ scsi-misc-2.6/drivers/scsi/scsi_error.c	2006-06-03 12:31:05.000000000 +0200
> @@ -438,19 +438,67 @@
>   * Return value:
>   *    SUCCESS or FAILED or NEEDS_RETRY
>   **/
> -static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
> +static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense)
>  {
>  	struct scsi_device *sdev = scmd->device;
>  	struct Scsi_Host *shost = sdev->host;
> +	int old_result = scmd->result;
>  	DECLARE_COMPLETION(done);
>  	unsigned long timeleft;
>  	unsigned long flags;
> +	unsigned char old_cmnd[MAX_COMMAND_SIZE];
> +	enum dma_data_direction old_data_direction;
> +	unsigned short old_use_sg;
> +	unsigned char old_cmd_len;
> +	unsigned old_bufflen;
> +	void *old_buffer;
>  	int rtn;
>  
> +	/*
> +	 * We need saved copies of a number of fields - this is because
> +	 * error handling may need to overwrite these with different values
> +	 * to run different commands, and once error handling is complete,
> +	 * we will need to restore these values prior to running the actual
> +	 * command.
> +	 */
> +	old_buffer = scmd->request_buffer;
> +	old_bufflen = scmd->request_bufflen;
> +	memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd));
> +	old_data_direction = scmd->sc_data_direction;
> +	old_cmd_len = scmd->cmd_len;
> +	old_use_sg = scmd->use_sg;
> +
> +	if (copy_sense) {
> +		int gfp_mask = GFP_ATOMIC;
> +
> +		if (shost->hostt->unchecked_isa_dma)
> +			gfp_mask |= __GFP_DMA;
> +
> +		scmd->sc_data_direction = DMA_FROM_DEVICE;
> +		scmd->request_bufflen = 252;
> +		scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask);
> +		if (!scmd->request_buffer)
> +			return FAILED;
> +	} else {
> +		scmd->request_buffer = NULL;
> +		scmd->request_bufflen = 0;
> +		scmd->sc_data_direction = DMA_NONE;
> +	}
> +
> +	scmd->underflow = 0;
> +	scmd->use_sg = 0;
> +	scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
> +
>  	if (sdev->scsi_level <= SCSI_2)
>  		scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
>  			(sdev->lun << 5 & 0xe0);
>  
> +	/*
> +	 * Zero the sense buffer.  The scsi spec mandates that any
> +	 * untransferred sense data should be interpreted as being zero.
> +	 */
> +	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
> +
>  	shost->eh_action = &done;
>  	scmd->request->rq_status = RQ_SCSI_BUSY;
>  
> @@ -502,6 +550,27 @@
>  		rtn = FAILED;
>  	}
>  
> +
> +	/*
> +	 * Last chance to have valid sense data.
> +	 */
> +	if (copy_sense && !SCSI_SENSE_VALID(scmd)) {
> +		memcpy(scmd->sense_buffer, scmd->request_buffer,
> +		       sizeof(scmd->sense_buffer));
> +		kfree(scmd->request_buffer);
> +	}
> +
> +
> +	/*
> +	 * Restore original data
> +	 */
> +	scmd->request_buffer = old_buffer;
> +	scmd->request_bufflen = old_bufflen;
> +	memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd));
> +	scmd->sc_data_direction = old_data_direction;
> +	scmd->cmd_len = old_cmd_len;
> +	scmd->use_sg = old_use_sg;
> +	scmd->result = old_result;
>  	return rtn;
>  }
>  
> @@ -517,56 +586,10 @@
>  static int scsi_request_sense(struct scsi_cmnd *scmd)
>  {
>  	static unsigned char generic_sense[6] =
> -	{REQUEST_SENSE, 0, 0, 0, 252, 0};
> -	unsigned char *scsi_result;
> -	int saved_result;
> -	int rtn;
> +		{REQUEST_SENSE, 0, 0, 0, 252, 0};
>  
>  	memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense));
> -
> -	scsi_result = kmalloc(252, GFP_ATOMIC | ((scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0));
> -
> -
> -	if (unlikely(!scsi_result)) {
> -		printk(KERN_ERR "%s: cannot allocate scsi_result.\n",
> -		       __FUNCTION__);
> -		return FAILED;
> -	}
> -
> -	/*
> -	 * zero the sense buffer.  some host adapters automatically always
> -	 * request sense, so it is not a good idea that
> -	 * scmd->request_buffer and scmd->sense_buffer point to the same
> -	 * address (db).  0 is not a valid sense code. 
> -	 */
> -	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
> -	memset(scsi_result, 0, 252);
> -
> -	saved_result = scmd->result;
> -	scmd->request_buffer = scsi_result;
> -	scmd->request_bufflen = 252;
> -	scmd->use_sg = 0;
> -	scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
> -	scmd->sc_data_direction = DMA_FROM_DEVICE;
> -	scmd->underflow = 0;
> -
> -	rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
> -
> -	/* last chance to have valid sense data */
> -	if(!SCSI_SENSE_VALID(scmd)) {
> -		memcpy(scmd->sense_buffer, scmd->request_buffer,
> -		       sizeof(scmd->sense_buffer));
> -	}
> -
> -	kfree(scsi_result);
> -
> -	/*
> -	 * when we eventually call scsi_finish, we really wish to complete
> -	 * the original request, so let's restore the original data. (db)
> -	 */
> -	scsi_setup_cmd_retry(scmd);
> -	scmd->result = saved_result;
> -	return rtn;
> +	return scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 1);
>  }
>  
>  /**
> @@ -585,12 +608,6 @@
>  {
>  	scmd->device->host->host_failed--;
>  	scmd->eh_eflags = 0;
> -
> -	/*
> -	 * set this back so that the upper level can correctly free up
> -	 * things.
> -	 */
> -	scsi_setup_cmd_retry(scmd);
>  	list_move_tail(&scmd->eh_entry, done_q);
>  }
>  EXPORT_SYMBOL(scsi_eh_finish_cmd);
> @@ -695,47 +712,26 @@
>  {
>  	static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
>  	int retry_cnt = 1, rtn;
> -	int saved_result;
>  
>  retry_tur:
>  	memcpy(scmd->cmnd, tur_command, sizeof(tur_command));
>  
> -	/*
> -	 * zero the sense buffer.  the scsi spec mandates that any
> -	 * untransferred sense data should be interpreted as being zero.
> -	 */
> -	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
>  
> -	saved_result = scmd->result;
> -	scmd->request_buffer = NULL;
> -	scmd->request_bufflen = 0;
> -	scmd->use_sg = 0;
> -	scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
> -	scmd->underflow = 0;
> -	scmd->sc_data_direction = DMA_NONE;
> +	rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 0);
>  
> -	rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
> -
> -	/*
> -	 * when we eventually call scsi_finish, we really wish to complete
> -	 * the original request, so let's restore the original data. (db)
> -	 */
> -	scsi_setup_cmd_retry(scmd);
> -	scmd->result = saved_result;
> -
> -	/*
> -	 * hey, we are done.  let's look to see what happened.
> -	 */
>  	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
>  		__FUNCTION__, scmd, rtn));
> -	if (rtn == SUCCESS)
> -		return 0;
> -	else if (rtn == NEEDS_RETRY) {
> +
> +	switch (rtn) {
> +	case NEEDS_RETRY:
>  		if (retry_cnt--)
>  			goto retry_tur;
> +		/*FALLTHRU*/
> +	case SUCCESS:
>  		return 0;
> +	default:
> +		return 1;
>  	}
> -	return 1;
>  }
>  
>  /**
> @@ -817,44 +813,16 @@
>  static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
>  {
>  	static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
> -	int rtn;
> -	int saved_result;
> -
> -	if (!scmd->device->allow_restart)
> -		return 1;
> -
> -	memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
> -
> -	/*
> -	 * zero the sense buffer.  the scsi spec mandates that any
> -	 * untransferred sense data should be interpreted as being zero.
> -	 */
> -	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
>  
> -	saved_result = scmd->result;
> -	scmd->request_buffer = NULL;
> -	scmd->request_bufflen = 0;
> -	scmd->use_sg = 0;
> -	scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
> -	scmd->underflow = 0;
> -	scmd->sc_data_direction = DMA_NONE;
> +	if (scmd->device->allow_restart) {
> +		int rtn;
>  
> -	rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT);
> -
> -	/*
> -	 * when we eventually call scsi_finish, we really wish to complete
> -	 * the original request, so let's restore the original data. (db)
> -	 */
> -	scsi_setup_cmd_retry(scmd);
> -	scmd->result = saved_result;
> +		memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
> +		rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT, 0);
> +		if (rtn == SUCCESS)
> +			return 0;
> +	}
>  
> -	/*
> -	 * hey, we are done.  let's look to see what happened.
> -	 */
> -	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
> -		__FUNCTION__, scmd, rtn));
> -	if (rtn == SUCCESS)
> -		return 0;
>  	return 1;
>  }
>  
> @@ -1663,8 +1631,6 @@
>      
>  	scmd->scsi_done		= scsi_reset_provider_done_command;
>  	scmd->done			= NULL;
> -	scmd->buffer			= NULL;
> -	scmd->bufflen			= 0;
>  	scmd->request_buffer		= NULL;
>  	scmd->request_bufflen		= 0;
>  
> Index: scsi-misc-2.6/drivers/scsi/scsi_lib.c
> ===================================================================
> --- scsi-misc-2.6.orig/drivers/scsi/scsi_lib.c	2006-06-02 18:20:23.000000000 +0200
> +++ scsi-misc-2.6/drivers/scsi/scsi_lib.c	2006-06-03 12:31:05.000000000 +0200
> @@ -502,60 +502,16 @@
>   *
>   * Arguments:   cmd	- command that is ready to be queued.
>   *
> - * Returns:     Nothing
> - *
>   * Notes:       This function has the job of initializing a number of
>   *              fields related to error handling.   Typically this will
>   *              be called once for each command, as required.
>   */
> -static int scsi_init_cmd_errh(struct scsi_cmnd *cmd)
> +static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
>  {
>  	cmd->serial_number = 0;
> -
>  	memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer);
> -
>  	if (cmd->cmd_len == 0)
>  		cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
> -
> -	/*
> -	 * We need saved copies of a number of fields - this is because
> -	 * error handling may need to overwrite these with different values
> -	 * to run different commands, and once error handling is complete,
> -	 * we will need to restore these values prior to running the actual
> -	 * command.
> -	 */
> -	cmd->old_use_sg = cmd->use_sg;
> -	cmd->old_cmd_len = cmd->cmd_len;
> -	cmd->sc_old_data_direction = cmd->sc_data_direction;
> -	cmd->old_underflow = cmd->underflow;
> -	memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd));
> -	cmd->buffer = cmd->request_buffer;
> -	cmd->bufflen = cmd->request_bufflen;
> -
> -	return 1;
> -}
> -
> -/*
> - * Function:   scsi_setup_cmd_retry()
> - *
> - * Purpose:    Restore the command state for a retry
> - *
> - * Arguments:  cmd	- command to be restored
> - *
> - * Returns:    Nothing
> - *
> - * Notes:      Immediately prior to retrying a command, we need
> - *             to restore certain fields that we saved above.
> - */
> -void scsi_setup_cmd_retry(struct scsi_cmnd *cmd)
> -{
> -	memcpy(cmd->cmnd, cmd->data_cmnd, sizeof(cmd->data_cmnd));
> -	cmd->request_buffer = cmd->buffer;
> -	cmd->request_bufflen = cmd->bufflen;
> -	cmd->use_sg = cmd->old_use_sg;
> -	cmd->cmd_len = cmd->old_cmd_len;
> -	cmd->sc_data_direction = cmd->sc_old_data_direction;
> -	cmd->underflow = cmd->old_underflow;
>  }
>  
>  void scsi_device_unbusy(struct scsi_device *sdev)
> @@ -873,22 +829,13 @@
>   */
>  static void scsi_release_buffers(struct scsi_cmnd *cmd)
>  {
> -	struct request *req = cmd->request;
> -
> -	/*
> -	 * Free up any indirection buffers we allocated for DMA purposes. 
> -	 */
>  	if (cmd->use_sg)
>  		scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
> -	else if (cmd->request_buffer != req->buffer)
> -		kfree(cmd->request_buffer);
>  
>  	/*
>  	 * Zero these out.  They now point to freed memory, and it is
>  	 * dangerous to hang onto the pointers.
>  	 */
> -	cmd->buffer  = NULL;
> -	cmd->bufflen = 0;
>  	cmd->request_buffer = NULL;
>  	cmd->request_bufflen = 0;
>  }
> @@ -925,7 +872,7 @@
>  			unsigned int block_bytes)
>  {
>  	int result = cmd->result;
> -	int this_count = cmd->bufflen;
> +	int this_count = cmd->request_bufflen;
>  	request_queue_t *q = cmd->device->request_queue;
>  	struct request *req = cmd->request;
>  	int clear_errors = 1;
> @@ -933,28 +880,14 @@
>  	int sense_valid = 0;
>  	int sense_deferred = 0;
>  
> -	/*
> -	 * Free up any indirection buffers we allocated for DMA purposes. 
> -	 * For the case of a READ, we need to copy the data out of the
> -	 * bounce buffer and into the real buffer.
> -	 */
> -	if (cmd->use_sg)
> -		scsi_free_sgtable(cmd->buffer, cmd->sglist_len);
> -	else if (cmd->buffer != req->buffer) {
> -		if (rq_data_dir(req) == READ) {
> -			unsigned long flags;
> -			char *to = bio_kmap_irq(req->bio, &flags);
> -			memcpy(to, cmd->buffer, cmd->bufflen);
> -			bio_kunmap_irq(to, &flags);
> -		}
> -		kfree(cmd->buffer);
> -	}
> +	scsi_release_buffers(cmd);
>  
>  	if (result) {
>  		sense_valid = scsi_command_normalize_sense(cmd, &sshdr);
>  		if (sense_valid)
>  			sense_deferred = scsi_sense_is_deferred(&sshdr);
>  	}
> +
>  	if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
>  		req->errors = result;
>  		if (result) {
> @@ -975,15 +908,6 @@
>  	}
>  
>  	/*
> -	 * Zero these out.  They now point to freed memory, and it is
> -	 * dangerous to hang onto the pointers.
> -	 */
> -	cmd->buffer  = NULL;
> -	cmd->bufflen = 0;
> -	cmd->request_buffer = NULL;
> -	cmd->request_bufflen = 0;
> -
> -	/*
>  	 * Next deal with any sectors which we were able to correctly
>  	 * handle.
>  	 */
> @@ -1083,7 +1007,7 @@
>  			if (!(req->flags & REQ_QUIET)) {
>  				scmd_printk(KERN_INFO, cmd,
>  					   "Volume overflow, CDB: ");
> -				__scsi_print_command(cmd->data_cmnd);
> +				__scsi_print_command(cmd->cmnd);
>  				scsi_print_sense("", cmd);
>  			}
>  			scsi_end_request(cmd, 0, block_bytes, 1);
> @@ -1222,7 +1146,7 @@
>  	 * successfully. Since this is a REQ_BLOCK_PC command the
>  	 * caller should check the request's errors value
>  	 */
> -	scsi_io_completion(cmd, cmd->bufflen, 0);
> +	scsi_io_completion(cmd, cmd->request_bufflen, 0);
>  }
>  
>  static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
> Index: scsi-misc-2.6/drivers/scsi/scsi.c
> ===================================================================
> --- scsi-misc-2.6.orig/drivers/scsi/scsi.c	2006-06-02 18:20:23.000000000 +0200
> +++ scsi-misc-2.6/drivers/scsi/scsi.c	2006-06-03 12:31:05.000000000 +0200
> @@ -420,7 +420,7 @@
>  			if (level > 3) {
>  				printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
>  				       " done = 0x%p, queuecommand 0x%p\n",
> -					cmd->buffer, cmd->bufflen,
> +					cmd->request_buffer, cmd->request_bufflen,
>  					cmd->done,
>  					sdev->host->hostt->queuecommand);
>  
> @@ -678,10 +678,7 @@
>  	cmd->use_sg = sreq->sr_use_sg;
>  
>  	cmd->request = sreq->sr_request;
> -	memcpy(cmd->data_cmnd, sreq->sr_cmnd, sizeof(cmd->data_cmnd));
>  	cmd->serial_number = 0;
> -	cmd->bufflen = sreq->sr_bufflen;
> -	cmd->buffer = sreq->sr_buffer;
>  	cmd->retries = 0;
>  	cmd->allowed = sreq->sr_allowed;
>  	cmd->done = sreq->sr_done;
> @@ -699,12 +696,8 @@
>  	memset(cmd->sense_buffer, 0, sizeof(sreq->sr_sense_buffer));
>  	cmd->request_buffer = sreq->sr_buffer;
>  	cmd->request_bufflen = sreq->sr_bufflen;
> -	cmd->old_use_sg = cmd->use_sg;
>  	if (cmd->cmd_len == 0)
>  		cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
> -	cmd->old_cmd_len = cmd->cmd_len;
> -	cmd->sc_old_data_direction = cmd->sc_data_direction;
> -	cmd->old_underflow = cmd->underflow;
>  
>  	/*
>  	 * Start the timer ticking.
> @@ -784,11 +777,6 @@
>   */
>  int scsi_retry_command(struct scsi_cmnd *cmd)
>  {
> -	/*
> -	 * Restore the SCSI command state.
> -	 */
> -	scsi_setup_cmd_retry(cmd);
> -
>          /*
>           * Zero the sense information from the last time we tried
>           * this command.
> @@ -836,11 +824,6 @@
>  				"(result %x)\n", cmd->result));
>  
>  	/*
> -	 * We can get here with use_sg=0, causing a panic in the upper level
> -	 */
> -	cmd->use_sg = cmd->old_use_sg;
> -
> -	/*
>  	 * If there is an associated request structure, copy the data over
>  	 * before we call the completion function.
>  	 */
> Index: scsi-misc-2.6/include/scsi/scsi_cmnd.h
> ===================================================================
> --- scsi-misc-2.6.orig/include/scsi/scsi_cmnd.h	2006-06-03 12:07:51.000000000 +0200
> +++ scsi-misc-2.6/include/scsi/scsi_cmnd.h	2006-06-03 12:31:05.000000000 +0200
> @@ -64,9 +64,7 @@
>  	int timeout_per_command;
>  
>  	unsigned char cmd_len;
> -	unsigned char old_cmd_len;
>  	enum dma_data_direction sc_data_direction;
> -	enum dma_data_direction sc_old_data_direction;
>  
>  	/* These elements define the operation we are about to perform */
>  #define MAX_COMMAND_SIZE	16
> @@ -77,18 +75,11 @@
>  	void *request_buffer;		/* Actual requested buffer */
>  
>  	/* These elements define the operation we ultimately want to perform */
> -	unsigned char data_cmnd[MAX_COMMAND_SIZE];
> -	unsigned short old_use_sg;	/* We save  use_sg here when requesting
> -					 * sense info */
>  	unsigned short use_sg;	/* Number of pieces of scatter-gather */
>  	unsigned short sglist_len;	/* size of malloc'd scatter-gather list */
> -	unsigned bufflen;	/* Size of data buffer */
> -	void *buffer;		/* Data buffer */
>  
>  	unsigned underflow;	/* Return error if less than
>  				   this amount is transferred */
> -	unsigned old_underflow;	/* save underflow here when reusing the
> -				 * command for error handling */
>  
>  	unsigned transfersize;	/* How much we are guaranteed to
>  				   transfer with each SCSI transfer
> Index: scsi-misc-2.6/drivers/scsi/scsi_priv.h
> ===================================================================
> --- scsi-misc-2.6.orig/drivers/scsi/scsi_priv.h	2006-06-02 18:20:23.000000000 +0200
> +++ scsi-misc-2.6/drivers/scsi/scsi_priv.h	2006-06-03 12:31:05.000000000 +0200
> @@ -68,7 +68,6 @@
>  
>  /* scsi_lib.c */
>  extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
> -extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd);
>  extern void scsi_device_unbusy(struct scsi_device *sdev);
>  extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason);
>  extern void scsi_next_command(struct scsi_cmnd *cmd);
> Index: scsi-misc-2.6/drivers/scsi/sd.c
> ===================================================================
> --- scsi-misc-2.6.orig/drivers/scsi/sd.c	2006-06-03 12:25:32.000000000 +0200
> +++ scsi-misc-2.6/drivers/scsi/sd.c	2006-06-03 12:31:05.000000000 +0200
> @@ -477,8 +477,7 @@
>  		SCpnt->cmnd[4] = (unsigned char) this_count;
>  		SCpnt->cmnd[5] = 0;
>  	}
> -	SCpnt->request_bufflen = SCpnt->bufflen =
> -			this_count * sdp->sector_size;
> +	SCpnt->request_bufflen = this_count * sdp->sector_size;
>  
>  	/*
>  	 * We shouldn't disconnect in the middle of a sector, so with a dumb
> Index: scsi-misc-2.6/drivers/scsi/sr.c
> ===================================================================
> --- scsi-misc-2.6.orig/drivers/scsi/sr.c	2006-06-03 12:25:32.000000000 +0200
> +++ scsi-misc-2.6/drivers/scsi/sr.c	2006-06-03 12:31:05.000000000 +0200
> @@ -360,7 +360,7 @@
>  				"mismatch count %d, bytes %d\n",
>  				size, SCpnt->request_bufflen);
>  			if (SCpnt->request_bufflen > size)
> -				SCpnt->request_bufflen = SCpnt->bufflen = size;
> +				SCpnt->request_bufflen = size;
>  		}
>  	}
>  
> @@ -387,8 +387,7 @@
>  
>  	if (this_count > 0xffff) {
>  		this_count = 0xffff;
> -		SCpnt->request_bufflen = SCpnt->bufflen =
> -				this_count * s_size;
> +		SCpnt->request_bufflen = this_count * s_size;
>  	}
>  
>  	SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
> Index: scsi-misc-2.6/drivers/scsi/aha152x.c
> ===================================================================
> --- scsi-misc-2.6.orig/drivers/scsi/aha152x.c	2006-06-02 18:20:22.000000000 +0200
> +++ scsi-misc-2.6/drivers/scsi/aha152x.c	2006-06-03 12:39:30.000000000 +0200
> @@ -1165,6 +1165,10 @@
>  	DECLARE_MUTEX_LOCKED(sem);
>  	struct timer_list timer;
>  	int ret, issued, disconnected;
> +	unsigned char old_cmd_len = SCpnt->cmd_len;
> +	unsigned short old_use_sg = SCpnt->use_sg;
> +	void *old_buffer = SCpnt->request_buffer;
> +	unsigned old_bufflen = SCpnt->request_bufflen;
>  	unsigned long flags;
>  
>  #if defined(AHA152X_DEBUG)
> @@ -1198,11 +1202,11 @@
>  	add_timer(&timer);
>  	down(&sem);
>  	del_timer(&timer);
> -	
> -	SCpnt->cmd_len         = SCpnt->old_cmd_len;
> -	SCpnt->use_sg          = SCpnt->old_use_sg;
> -  	SCpnt->request_buffer  = SCpnt->buffer;
> -       	SCpnt->request_bufflen = SCpnt->bufflen;
> +
> +	SCpnt->cmd_len         = old_cmd_len;
> +	SCpnt->use_sg          = old_use_sg;
> +  	SCpnt->request_buffer  = old_buffer;
> +       	SCpnt->request_bufflen = old_bufflen;
>  
>  	DO_LOCK(flags);
>  
---end quoted text---

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
       [not found] <20060603112610.GB17018@lst.de>
  2006-06-03 11:31 ` [PATCH, RFC] hide EH backup data outside the scsi_cmnd Christoph Hellwig
@ 2006-06-10 16:08 ` Christoph Hellwig
  2006-06-12 19:19   ` Christoph Hellwig
  2006-07-24 17:27 ` Tony Luck
  2 siblings, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2006-06-10 16:08 UTC (permalink / raw)
  To: jejb; +Cc: fischer, linux-scsi

On Sat, Jun 03, 2006 at 01:26:10PM +0200, Christoph Hellwig wrote:
> Currently struct scsi_cmnd has various fields that are used to backup
> original data after the corresponding fields have been overridden for
> EH commands.  This means drivers can easily get at it and misuse it.
> Due to the old_ naming this doesn't happen for most of them, but two
> that have different names have been used wrong a lot (see previous
> patch).  Another downside is that they unessecarily bloat the scsi_cmnd
> size.
> 
> This patch moves them onstack in scsi_send_eh_cmnd to fix those two
> issues above.
> 
> Note that this breaks the aha152x and 53x700 drivers because they're
> plaing with those fields internally.
> 
> J"urgen and James, could you take a look at whether it's feasible to
> fix those drivers?
> 
> Otherwise any comments on the general approach?
> 
> (Note:  you probably want the patch to remove the wrong buffer and
>  bufflen patches applied before this, else lots of drivers will stop
>  compiling)

That patch is now in.  Below is a patch rediffed against the
scsi_request removal I just posed to linux-scsi.


Index: scsi-misc-2.6/drivers/scsi/scsi_error.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/scsi_error.c	2005-10-29 19:22:47.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/scsi_error.c	2005-10-29 19:23:00.000000000 +0200
@@ -417,43 +417,15 @@
 }
 
 /**
- * scsi_eh_times_out - timeout function for error handling.
- * @scmd:	Cmd that is timing out.
- *
- * Notes:
- *    During error handling, the kernel thread will be sleeping waiting
- *    for some action to complete on the device.  our only job is to
- *    record that it timed out, and to wake up the thread.
- **/
-static void scsi_eh_times_out(struct scsi_cmnd *scmd)
-{
-	scmd->eh_eflags |= SCSI_EH_REC_TIMEOUT;
-	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd:%p\n", __FUNCTION__,
-					  scmd));
-
-	up(scmd->device->host->eh_action);
-}
-
-/**
  * scsi_eh_done - Completion function for error handling.
  * @scmd:	Cmd that is done.
  **/
 static void scsi_eh_done(struct scsi_cmnd *scmd)
 {
-	/*
-	 * if the timeout handler is already running, then just set the
-	 * flag which says we finished late, and return.  we have no
-	 * way of stopping the timeout handler from running, so we must
-	 * always defer to it.
-	 */
-	if (del_timer(&scmd->eh_timeout)) {
-		scmd->request->rq_status = RQ_SCSI_DONE;
-
-		SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n",
-					   __FUNCTION__, scmd, scmd->result));
-
-		up(scmd->device->host->eh_action);
-	}
+	SCSI_LOG_ERROR_RECOVERY(3,
+		printk("%s scmd: %p result: %x\n",
+			__FUNCTION__, scmd, scmd->result));
+	complete(scmd->device->host->eh_action);
 }
 
 /**
@@ -461,10 +433,6 @@
  * @scmd:	SCSI Cmd to send.
  * @timeout:	Timeout for cmd.
  *
- * Notes:
- *    The initialization of the structures is quite a bit different in
- *    this case, and furthermore, there is a different completion handler
- *    vs scsi_dispatch_cmd.
  * Return value:
  *    SUCCESS or FAILED or NEEDS_RETRY
  **/
@@ -472,24 +440,16 @@
 {
 	struct scsi_device *sdev = scmd->device;
 	struct Scsi_Host *shost = sdev->host;
-	DECLARE_MUTEX_LOCKED(sem);
+	DECLARE_COMPLETION(done);
+	unsigned long timeleft;
 	unsigned long flags;
-	int rtn = SUCCESS;
+	int rtn;
 
-	/*
-	 * we will use a queued command if possible, otherwise we will
-	 * emulate the queuing and calling of completion function ourselves.
-	 */
 	if (sdev->scsi_level <= SCSI_2)
 		scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
 			(sdev->lun << 5 & 0xe0);
 
-	scsi_add_timer(scmd, timeout, scsi_eh_times_out);
-
-	/*
-	 * set up the semaphore so we wait for the command to complete.
-	 */
-	shost->eh_action = &sem;
+	shost->eh_action = &done;
 	scmd->request->rq_status = RQ_SCSI_BUSY;
 
 	spin_lock_irqsave(shost->host_lock, flags);
@@ -497,47 +457,29 @@
 	shost->hostt->queuecommand(scmd, scsi_eh_done);
 	spin_unlock_irqrestore(shost->host_lock, flags);
 
-	down(&sem);
-	scsi_log_completion(scmd, SUCCESS);
+	timeleft = wait_for_completion_timeout(&done, timeout);
 
+	scmd->request->rq_status = RQ_SCSI_DONE;
 	shost->eh_action = NULL;
 
-	/*
-	 * see if timeout.  if so, tell the host to forget about it.
-	 * in other words, we don't want a callback any more.
-	 */
-	if (scmd->eh_eflags & SCSI_EH_REC_TIMEOUT) {
-		scmd->eh_eflags &= ~SCSI_EH_REC_TIMEOUT;
-
-		/*
-		 * as far as the low level driver is
-		 * concerned, this command is still active, so
-		 * we must give the low level driver a chance
-		 * to abort it. (db) 
-		 *
-		 * FIXME(eric) - we are not tracking whether we could
-		 * abort a timed out command or not.  not sure how
-		 * we should treat them differently anyways.
-		 */
-		if (shost->hostt->eh_abort_handler)
-			shost->hostt->eh_abort_handler(scmd);
-			
-		scmd->request->rq_status = RQ_SCSI_DONE;
-		rtn = FAILED;
-	}
+	scsi_log_completion(scmd, SUCCESS);
 
-	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd: %p, rtn:%x\n",
-					  __FUNCTION__, scmd, rtn));
+	SCSI_LOG_ERROR_RECOVERY(3,
+		printk("%s: scmd: %p, timeleft: %ld\n",
+			__FUNCTION__, scmd, timeleft));
 
 	/*
-	 * now examine the actual status codes to see whether the command
-	 * actually did complete normally.
+	 * If there is time left scsi_eh_done got called, and we will
+	 * examine the actual status codes to see whether the command
+	 * actually did complete normally, else tell the host to forget
+	 * about this command.
 	 */
-	if (rtn == SUCCESS) {
+	if (timeleft) {
 		rtn = scsi_eh_completed_normally(scmd);
 		SCSI_LOG_ERROR_RECOVERY(3,
 			printk("%s: scsi_eh_completed_normally %x\n",
 			       __FUNCTION__, rtn));
+
 		switch (rtn) {
 		case SUCCESS:
 		case NEEDS_RETRY:
@@ -547,6 +489,15 @@
 			rtn = FAILED;
 			break;
 		}
+	} else {
+		/*
+		 * FIXME(eric) - we are not tracking whether we could
+		 * abort a timed out command or not.  not sure how
+		 * we should treat them differently anyways.
+		 */
+		if (shost->hostt->eh_abort_handler)
+			shost->hostt->eh_abort_handler(scmd);
+		rtn = FAILED;
 	}
 
 	return rtn;
Index: scsi-misc-2.6/drivers/scsi/scsi_priv.h
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/scsi_priv.h	2005-10-29 19:20:33.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/scsi_priv.h	2005-10-29 19:23:00.000000000 +0200
@@ -22,7 +22,6 @@
  * Scsi Error Handler Flags
  */
 #define SCSI_EH_CANCEL_CMD	0x0001	/* Cancel this cmd */
-#define SCSI_EH_REC_TIMEOUT	0x0002	/* EH retry timed out */
 
 #define SCSI_SENSE_VALID(scmd) \
 	(((scmd)->sense_buffer[0] & 0x70) == 0x70)
Index: scsi-misc-2.6/include/scsi/scsi_host.h
===================================================================
--- scsi-misc-2.6.orig/include/scsi/scsi_host.h	2005-10-29 19:22:47.000000000 +0200
+++ scsi-misc-2.6/include/scsi/scsi_host.h	2005-10-29 19:23:00.000000000 +0200
@@ -7,6 +7,7 @@
 #include <linux/workqueue.h>
 
 struct block_device;
+struct completion;
 struct module;
 struct scsi_cmnd;
 struct scsi_device;
@@ -467,8 +468,8 @@
 
 	struct list_head	eh_cmd_q;
 	struct task_struct    * ehandler;  /* Error recovery thread. */
-	struct semaphore      * eh_action; /* Wait for specific actions on the
-                                          host. */
+	struct completion     * eh_action; /* Wait for specific actions on the
+					      host. */
 	wait_queue_head_t       host_wait;
 	struct scsi_host_template *hostt;
 	struct scsi_transport_template *transportt;

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
  2006-06-10 16:08 ` Christoph Hellwig
@ 2006-06-12 19:19   ` Christoph Hellwig
  2006-06-14  2:31     ` James Bottomley
                       ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Christoph Hellwig @ 2006-06-12 19:19 UTC (permalink / raw)
  To: jejb; +Cc: fischer, linux-scsi

On Sat, Jun 10, 2006 at 06:08:15PM +0200, Christoph Hellwig wrote:
> On Sat, Jun 03, 2006 at 01:26:10PM +0200, Christoph Hellwig wrote:
> > Currently struct scsi_cmnd has various fields that are used to backup
> > original data after the corresponding fields have been overridden for
> > EH commands.  This means drivers can easily get at it and misuse it.
> > Due to the old_ naming this doesn't happen for most of them, but two
> > that have different names have been used wrong a lot (see previous
> > patch).  Another downside is that they unessecarily bloat the scsi_cmnd
> > size.
> > 
> > This patch moves them onstack in scsi_send_eh_cmnd to fix those two
> > issues above.
> > 
> > Note that this breaks the aha152x and 53x700 drivers because they're
> > plaing with those fields internally.
> > 
> > J"urgen and James, could you take a look at whether it's feasible to
> > fix those drivers?
> > 
> > Otherwise any comments on the general approach?
> > 
> > (Note:  you probably want the patch to remove the wrong buffer and
> >  bufflen patches applied before this, else lots of drivers will stop
> >  compiling)
> 
> That patch is now in.  Below is a patch rediffed against the
> scsi_request removal I just posed to linux-scsi.

looks like no one but James looked at it as I attached a completely
different patch that has been merged long ago.  Here's the real one:


Index: scsi-misc-2.6/drivers/scsi/scsi_error.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/scsi_error.c	2006-06-10 17:45:59.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/scsi_error.c	2006-06-10 17:53:06.000000000 +0200
@@ -438,19 +438,67 @@
  * Return value:
  *    SUCCESS or FAILED or NEEDS_RETRY
  **/
-static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
+static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense)
 {
 	struct scsi_device *sdev = scmd->device;
 	struct Scsi_Host *shost = sdev->host;
+	int old_result = scmd->result;
 	DECLARE_COMPLETION(done);
 	unsigned long timeleft;
 	unsigned long flags;
+	unsigned char old_cmnd[MAX_COMMAND_SIZE];
+	enum dma_data_direction old_data_direction;
+	unsigned short old_use_sg;
+	unsigned char old_cmd_len;
+	unsigned old_bufflen;
+	void *old_buffer;
 	int rtn;
 
+	/*
+	 * We need saved copies of a number of fields - this is because
+	 * error handling may need to overwrite these with different values
+	 * to run different commands, and once error handling is complete,
+	 * we will need to restore these values prior to running the actual
+	 * command.
+	 */
+	old_buffer = scmd->request_buffer;
+	old_bufflen = scmd->request_bufflen;
+	memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd));
+	old_data_direction = scmd->sc_data_direction;
+	old_cmd_len = scmd->cmd_len;
+	old_use_sg = scmd->use_sg;
+
+	if (copy_sense) {
+		int gfp_mask = GFP_ATOMIC;
+
+		if (shost->hostt->unchecked_isa_dma)
+			gfp_mask |= __GFP_DMA;
+
+		scmd->sc_data_direction = DMA_FROM_DEVICE;
+		scmd->request_bufflen = 252;
+		scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask);
+		if (!scmd->request_buffer)
+			return FAILED;
+	} else {
+		scmd->request_buffer = NULL;
+		scmd->request_bufflen = 0;
+		scmd->sc_data_direction = DMA_NONE;
+	}
+
+	scmd->underflow = 0;
+	scmd->use_sg = 0;
+	scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
+
 	if (sdev->scsi_level <= SCSI_2)
 		scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
 			(sdev->lun << 5 & 0xe0);
 
+	/*
+	 * Zero the sense buffer.  The scsi spec mandates that any
+	 * untransferred sense data should be interpreted as being zero.
+	 */
+	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
+
 	shost->eh_action = &done;
 	scmd->request->rq_status = RQ_SCSI_BUSY;
 
@@ -502,6 +550,27 @@
 		rtn = FAILED;
 	}
 
+
+	/*
+	 * Last chance to have valid sense data.
+	 */
+	if (copy_sense && !SCSI_SENSE_VALID(scmd)) {
+		memcpy(scmd->sense_buffer, scmd->request_buffer,
+		       sizeof(scmd->sense_buffer));
+		kfree(scmd->request_buffer);
+	}
+
+
+	/*
+	 * Restore original data
+	 */
+	scmd->request_buffer = old_buffer;
+	scmd->request_bufflen = old_bufflen;
+	memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd));
+	scmd->sc_data_direction = old_data_direction;
+	scmd->cmd_len = old_cmd_len;
+	scmd->use_sg = old_use_sg;
+	scmd->result = old_result;
 	return rtn;
 }
 
@@ -517,56 +586,10 @@
 static int scsi_request_sense(struct scsi_cmnd *scmd)
 {
 	static unsigned char generic_sense[6] =
-	{REQUEST_SENSE, 0, 0, 0, 252, 0};
-	unsigned char *scsi_result;
-	int saved_result;
-	int rtn;
+		{REQUEST_SENSE, 0, 0, 0, 252, 0};
 
 	memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense));
-
-	scsi_result = kmalloc(252, GFP_ATOMIC | ((scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0));
-
-
-	if (unlikely(!scsi_result)) {
-		printk(KERN_ERR "%s: cannot allocate scsi_result.\n",
-		       __FUNCTION__);
-		return FAILED;
-	}
-
-	/*
-	 * zero the sense buffer.  some host adapters automatically always
-	 * request sense, so it is not a good idea that
-	 * scmd->request_buffer and scmd->sense_buffer point to the same
-	 * address (db).  0 is not a valid sense code. 
-	 */
-	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
-	memset(scsi_result, 0, 252);
-
-	saved_result = scmd->result;
-	scmd->request_buffer = scsi_result;
-	scmd->request_bufflen = 252;
-	scmd->use_sg = 0;
-	scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
-	scmd->sc_data_direction = DMA_FROM_DEVICE;
-	scmd->underflow = 0;
-
-	rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
-
-	/* last chance to have valid sense data */
-	if(!SCSI_SENSE_VALID(scmd)) {
-		memcpy(scmd->sense_buffer, scmd->request_buffer,
-		       sizeof(scmd->sense_buffer));
-	}
-
-	kfree(scsi_result);
-
-	/*
-	 * when we eventually call scsi_finish, we really wish to complete
-	 * the original request, so let's restore the original data. (db)
-	 */
-	scsi_setup_cmd_retry(scmd);
-	scmd->result = saved_result;
-	return rtn;
+	return scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 1);
 }
 
 /**
@@ -585,12 +608,6 @@
 {
 	scmd->device->host->host_failed--;
 	scmd->eh_eflags = 0;
-
-	/*
-	 * set this back so that the upper level can correctly free up
-	 * things.
-	 */
-	scsi_setup_cmd_retry(scmd);
 	list_move_tail(&scmd->eh_entry, done_q);
 }
 EXPORT_SYMBOL(scsi_eh_finish_cmd);
@@ -695,47 +712,26 @@
 {
 	static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
 	int retry_cnt = 1, rtn;
-	int saved_result;
 
 retry_tur:
 	memcpy(scmd->cmnd, tur_command, sizeof(tur_command));
 
-	/*
-	 * zero the sense buffer.  the scsi spec mandates that any
-	 * untransferred sense data should be interpreted as being zero.
-	 */
-	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
 
-	saved_result = scmd->result;
-	scmd->request_buffer = NULL;
-	scmd->request_bufflen = 0;
-	scmd->use_sg = 0;
-	scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
-	scmd->underflow = 0;
-	scmd->sc_data_direction = DMA_NONE;
+	rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 0);
 
-	rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
-
-	/*
-	 * when we eventually call scsi_finish, we really wish to complete
-	 * the original request, so let's restore the original data. (db)
-	 */
-	scsi_setup_cmd_retry(scmd);
-	scmd->result = saved_result;
-
-	/*
-	 * hey, we are done.  let's look to see what happened.
-	 */
 	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
 		__FUNCTION__, scmd, rtn));
-	if (rtn == SUCCESS)
-		return 0;
-	else if (rtn == NEEDS_RETRY) {
+
+	switch (rtn) {
+	case NEEDS_RETRY:
 		if (retry_cnt--)
 			goto retry_tur;
+		/*FALLTHRU*/
+	case SUCCESS:
 		return 0;
+	default:
+		return 1;
 	}
-	return 1;
 }
 
 /**
@@ -817,44 +813,16 @@
 static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
 {
 	static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
-	int rtn;
-	int saved_result;
-
-	if (!scmd->device->allow_restart)
-		return 1;
-
-	memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
-
-	/*
-	 * zero the sense buffer.  the scsi spec mandates that any
-	 * untransferred sense data should be interpreted as being zero.
-	 */
-	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
 
-	saved_result = scmd->result;
-	scmd->request_buffer = NULL;
-	scmd->request_bufflen = 0;
-	scmd->use_sg = 0;
-	scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
-	scmd->underflow = 0;
-	scmd->sc_data_direction = DMA_NONE;
+	if (scmd->device->allow_restart) {
+		int rtn;
 
-	rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT);
-
-	/*
-	 * when we eventually call scsi_finish, we really wish to complete
-	 * the original request, so let's restore the original data. (db)
-	 */
-	scsi_setup_cmd_retry(scmd);
-	scmd->result = saved_result;
+		memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
+		rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT, 0);
+		if (rtn == SUCCESS)
+			return 0;
+	}
 
-	/*
-	 * hey, we are done.  let's look to see what happened.
-	 */
-	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
-		__FUNCTION__, scmd, rtn));
-	if (rtn == SUCCESS)
-		return 0;
 	return 1;
 }
 
@@ -1663,8 +1631,6 @@
     
 	scmd->scsi_done		= scsi_reset_provider_done_command;
 	scmd->done			= NULL;
-	scmd->buffer			= NULL;
-	scmd->bufflen			= 0;
 	scmd->request_buffer		= NULL;
 	scmd->request_bufflen		= 0;
 
Index: scsi-misc-2.6/drivers/scsi/scsi_lib.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/scsi_lib.c	2006-06-10 17:46:59.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/scsi_lib.c	2006-06-10 17:53:06.000000000 +0200
@@ -436,60 +436,16 @@
  *
  * Arguments:   cmd	- command that is ready to be queued.
  *
- * Returns:     Nothing
- *
  * Notes:       This function has the job of initializing a number of
  *              fields related to error handling.   Typically this will
  *              be called once for each command, as required.
  */
-static int scsi_init_cmd_errh(struct scsi_cmnd *cmd)
+static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
 {
 	cmd->serial_number = 0;
-
 	memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer);
-
 	if (cmd->cmd_len == 0)
 		cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
-
-	/*
-	 * We need saved copies of a number of fields - this is because
-	 * error handling may need to overwrite these with different values
-	 * to run different commands, and once error handling is complete,
-	 * we will need to restore these values prior to running the actual
-	 * command.
-	 */
-	cmd->old_use_sg = cmd->use_sg;
-	cmd->old_cmd_len = cmd->cmd_len;
-	cmd->sc_old_data_direction = cmd->sc_data_direction;
-	cmd->old_underflow = cmd->underflow;
-	memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd));
-	cmd->buffer = cmd->request_buffer;
-	cmd->bufflen = cmd->request_bufflen;
-
-	return 1;
-}
-
-/*
- * Function:   scsi_setup_cmd_retry()
- *
- * Purpose:    Restore the command state for a retry
- *
- * Arguments:  cmd	- command to be restored
- *
- * Returns:    Nothing
- *
- * Notes:      Immediately prior to retrying a command, we need
- *             to restore certain fields that we saved above.
- */
-void scsi_setup_cmd_retry(struct scsi_cmnd *cmd)
-{
-	memcpy(cmd->cmnd, cmd->data_cmnd, sizeof(cmd->data_cmnd));
-	cmd->request_buffer = cmd->buffer;
-	cmd->request_bufflen = cmd->bufflen;
-	cmd->use_sg = cmd->old_use_sg;
-	cmd->cmd_len = cmd->old_cmd_len;
-	cmd->sc_data_direction = cmd->sc_old_data_direction;
-	cmd->underflow = cmd->old_underflow;
 }
 
 void scsi_device_unbusy(struct scsi_device *sdev)
@@ -807,22 +763,13 @@
  */
 static void scsi_release_buffers(struct scsi_cmnd *cmd)
 {
-	struct request *req = cmd->request;
-
-	/*
-	 * Free up any indirection buffers we allocated for DMA purposes. 
-	 */
 	if (cmd->use_sg)
 		scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
-	else if (cmd->request_buffer != req->buffer)
-		kfree(cmd->request_buffer);
 
 	/*
 	 * Zero these out.  They now point to freed memory, and it is
 	 * dangerous to hang onto the pointers.
 	 */
-	cmd->buffer  = NULL;
-	cmd->bufflen = 0;
 	cmd->request_buffer = NULL;
 	cmd->request_bufflen = 0;
 }
@@ -859,7 +806,7 @@
 			unsigned int block_bytes)
 {
 	int result = cmd->result;
-	int this_count = cmd->bufflen;
+	int this_count = cmd->request_bufflen;
 	request_queue_t *q = cmd->device->request_queue;
 	struct request *req = cmd->request;
 	int clear_errors = 1;
@@ -867,28 +814,14 @@
 	int sense_valid = 0;
 	int sense_deferred = 0;
 
-	/*
-	 * Free up any indirection buffers we allocated for DMA purposes. 
-	 * For the case of a READ, we need to copy the data out of the
-	 * bounce buffer and into the real buffer.
-	 */
-	if (cmd->use_sg)
-		scsi_free_sgtable(cmd->buffer, cmd->sglist_len);
-	else if (cmd->buffer != req->buffer) {
-		if (rq_data_dir(req) == READ) {
-			unsigned long flags;
-			char *to = bio_kmap_irq(req->bio, &flags);
-			memcpy(to, cmd->buffer, cmd->bufflen);
-			bio_kunmap_irq(to, &flags);
-		}
-		kfree(cmd->buffer);
-	}
+	scsi_release_buffers(cmd);
 
 	if (result) {
 		sense_valid = scsi_command_normalize_sense(cmd, &sshdr);
 		if (sense_valid)
 			sense_deferred = scsi_sense_is_deferred(&sshdr);
 	}
+
 	if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
 		req->errors = result;
 		if (result) {
@@ -909,15 +842,6 @@
 	}
 
 	/*
-	 * Zero these out.  They now point to freed memory, and it is
-	 * dangerous to hang onto the pointers.
-	 */
-	cmd->buffer  = NULL;
-	cmd->bufflen = 0;
-	cmd->request_buffer = NULL;
-	cmd->request_bufflen = 0;
-
-	/*
 	 * Next deal with any sectors which we were able to correctly
 	 * handle.
 	 */
@@ -1017,7 +941,7 @@
 			if (!(req->flags & REQ_QUIET)) {
 				scmd_printk(KERN_INFO, cmd,
 					   "Volume overflow, CDB: ");
-				__scsi_print_command(cmd->data_cmnd);
+				__scsi_print_command(cmd->cmnd);
 				scsi_print_sense("", cmd);
 			}
 			scsi_end_request(cmd, 0, block_bytes, 1);
@@ -1156,7 +1080,7 @@
 	 * successfully. Since this is a REQ_BLOCK_PC command the
 	 * caller should check the request's errors value
 	 */
-	scsi_io_completion(cmd, cmd->bufflen, 0);
+	scsi_io_completion(cmd, cmd->request_bufflen, 0);
 }
 
 static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
Index: scsi-misc-2.6/drivers/scsi/scsi.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/scsi.c	2006-06-10 17:22:08.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/scsi.c	2006-06-10 17:53:47.000000000 +0200
@@ -346,7 +346,7 @@
 			if (level > 3) {
 				printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
 				       " done = 0x%p, queuecommand 0x%p\n",
-					cmd->buffer, cmd->bufflen,
+					cmd->request_buffer, cmd->request_bufflen,
 					cmd->done,
 					sdev->host->hostt->queuecommand);
 
@@ -643,11 +643,6 @@
  */
 int scsi_retry_command(struct scsi_cmnd *cmd)
 {
-	/*
-	 * Restore the SCSI command state.
-	 */
-	scsi_setup_cmd_retry(cmd);
-
         /*
          * Zero the sense information from the last time we tried
          * this command.
@@ -693,10 +688,6 @@
 				"Notifying upper driver of completion "
 				"(result %x)\n", cmd->result));
 
-	/*
-	 * We can get here with use_sg=0, causing a panic in the upper level
-	 */
-	cmd->use_sg = cmd->old_use_sg;
 	cmd->done(cmd);
 }
 EXPORT_SYMBOL(scsi_finish_command);
Index: scsi-misc-2.6/include/scsi/scsi_cmnd.h
===================================================================
--- scsi-misc-2.6.orig/include/scsi/scsi_cmnd.h	2006-06-10 17:39:10.000000000 +0200
+++ scsi-misc-2.6/include/scsi/scsi_cmnd.h	2006-06-10 17:53:06.000000000 +0200
@@ -58,9 +58,7 @@
 	int timeout_per_command;
 
 	unsigned char cmd_len;
-	unsigned char old_cmd_len;
 	enum dma_data_direction sc_data_direction;
-	enum dma_data_direction sc_old_data_direction;
 
 	/* These elements define the operation we are about to perform */
 #define MAX_COMMAND_SIZE	16
@@ -71,18 +69,11 @@
 	void *request_buffer;		/* Actual requested buffer */
 
 	/* These elements define the operation we ultimately want to perform */
-	unsigned char data_cmnd[MAX_COMMAND_SIZE];
-	unsigned short old_use_sg;	/* We save  use_sg here when requesting
-					 * sense info */
 	unsigned short use_sg;	/* Number of pieces of scatter-gather */
 	unsigned short sglist_len;	/* size of malloc'd scatter-gather list */
-	unsigned bufflen;	/* Size of data buffer */
-	void *buffer;		/* Data buffer */
 
 	unsigned underflow;	/* Return error if less than
 				   this amount is transferred */
-	unsigned old_underflow;	/* save underflow here when reusing the
-				 * command for error handling */
 
 	unsigned transfersize;	/* How much we are guaranteed to
 				   transfer with each SCSI transfer
Index: scsi-misc-2.6/drivers/scsi/scsi_priv.h
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/scsi_priv.h	2006-06-10 17:29:58.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/scsi_priv.h	2006-06-10 17:53:06.000000000 +0200
@@ -58,7 +58,6 @@
 
 /* scsi_lib.c */
 extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
-extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd);
 extern void scsi_device_unbusy(struct scsi_device *sdev);
 extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason);
 extern void scsi_next_command(struct scsi_cmnd *cmd);
Index: scsi-misc-2.6/drivers/scsi/sd.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/sd.c	2006-06-10 17:00:39.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/sd.c	2006-06-10 17:53:06.000000000 +0200
@@ -477,8 +477,7 @@
 		SCpnt->cmnd[4] = (unsigned char) this_count;
 		SCpnt->cmnd[5] = 0;
 	}
-	SCpnt->request_bufflen = SCpnt->bufflen =
-			this_count * sdp->sector_size;
+	SCpnt->request_bufflen = this_count * sdp->sector_size;
 
 	/*
 	 * We shouldn't disconnect in the middle of a sector, so with a dumb
Index: scsi-misc-2.6/drivers/scsi/sr.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/sr.c	2006-06-10 17:00:39.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/sr.c	2006-06-10 17:53:06.000000000 +0200
@@ -360,7 +360,7 @@
 				"mismatch count %d, bytes %d\n",
 				size, SCpnt->request_bufflen);
 			if (SCpnt->request_bufflen > size)
-				SCpnt->request_bufflen = SCpnt->bufflen = size;
+				SCpnt->request_bufflen = size;
 		}
 	}
 
@@ -387,8 +387,7 @@
 
 	if (this_count > 0xffff) {
 		this_count = 0xffff;
-		SCpnt->request_bufflen = SCpnt->bufflen =
-				this_count * s_size;
+		SCpnt->request_bufflen = this_count * s_size;
 	}
 
 	SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
Index: scsi-misc-2.6/drivers/scsi/aha152x.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/aha152x.c	2006-06-10 16:59:29.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/aha152x.c	2006-06-10 17:53:06.000000000 +0200
@@ -1165,6 +1165,10 @@
 	DECLARE_MUTEX_LOCKED(sem);
 	struct timer_list timer;
 	int ret, issued, disconnected;
+	unsigned char old_cmd_len = SCpnt->cmd_len;
+	unsigned short old_use_sg = SCpnt->use_sg;
+	void *old_buffer = SCpnt->request_buffer;
+	unsigned old_bufflen = SCpnt->request_bufflen;
 	unsigned long flags;
 
 #if defined(AHA152X_DEBUG)
@@ -1198,11 +1202,11 @@
 	add_timer(&timer);
 	down(&sem);
 	del_timer(&timer);
-	
-	SCpnt->cmd_len         = SCpnt->old_cmd_len;
-	SCpnt->use_sg          = SCpnt->old_use_sg;
-  	SCpnt->request_buffer  = SCpnt->buffer;
-       	SCpnt->request_bufflen = SCpnt->bufflen;
+
+	SCpnt->cmd_len         = old_cmd_len;
+	SCpnt->use_sg          = old_use_sg;
+  	SCpnt->request_buffer  = old_buffer;
+       	SCpnt->request_bufflen = old_bufflen;
 
 	DO_LOCK(flags);
 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
  2006-06-12 19:19   ` Christoph Hellwig
@ 2006-06-14  2:31     ` James Bottomley
  2006-06-14  2:40     ` James Bottomley
  2006-06-14  2:43     ` James Bottomley
  2 siblings, 0 replies; 12+ messages in thread
From: James Bottomley @ 2006-06-14  2:31 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: fischer, linux-scsi

On Mon, 2006-06-12 at 21:19 +0200, Christoph Hellwig wrote:
> Note that this breaks the aha152x and 53x700 drivers because they're
> plaing with those fields internally.

Well, this is what I think the changes for the 53c700 need to be ... I
haven't had time to check it with actual hardware yet (particularly as I
need to arrange to trip a check condition in the device to test it) but
it compiles.  Presumably the aha drivers also need something similar
doing to them.

James

Index: BUILD-2.6/drivers/scsi/53c700.c
===================================================================
--- BUILD-2.6.orig/drivers/scsi/53c700.c	2006-06-13 15:53:08.000000000 -0500
+++ BUILD-2.6/drivers/scsi/53c700.c	2006-06-13 15:53:14.000000000 -0500
@@ -183,6 +183,10 @@
 
 STATIC struct scsi_transport_template *NCR_700_transport_template = NULL;
 
+struct NCR_700_sense {
+	unsigned char cmnd[MAX_COMMAND_SIZE];
+};
+
 static char *NCR_700_phase[] = {
 	"",
 	"after selection",
@@ -537,6 +541,7 @@
 	 * finish routine.  If we cannot queue the command when it
 	 * is properly build, we then change to NCR_700_SLOT_QUEUED */
 	slot->state = NCR_700_SLOT_BUSY;
+	slot->flags = 0;
 	hostdata->command_slot_count++;
 	
 	return slot;
@@ -586,7 +591,7 @@
 	if(SCp->sc_data_direction != DMA_NONE &&
 	   SCp->sc_data_direction != DMA_BIDIRECTIONAL) {
 		if(SCp->use_sg) {
-			dma_unmap_sg(hostdata->dev, SCp->buffer,
+			dma_unmap_sg(hostdata->dev, SCp->request_buffer,
 				     SCp->use_sg, SCp->sc_data_direction);
 		} else {
 			dma_unmap_single(hostdata->dev, slot->dma_handle,
@@ -608,30 +613,23 @@
 			(struct NCR_700_command_slot *)SCp->host_scribble;
 		
 		NCR_700_unmap(hostdata, SCp, slot);
-		dma_unmap_single(hostdata->dev, slot->pCmd,
-				 sizeof(SCp->cmnd), DMA_TO_DEVICE);
-		if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) {
+		if (slot->flags == NCR_700_FLAG_AUTOSENSE) {
+			struct NCR_700_sense *sense = SCp->device->hostdata;
 #ifdef NCR_700_DEBUG
 			printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
 			       SCp, SCp->cmnd[7], result);
 			scsi_print_sense("53c700", SCp);
 
 #endif
+			dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
 			/* restore the old result if the request sense was
 			 * successful */
 			if(result == 0)
-				result = SCp->cmnd[7];
-			/* now restore the original command */
-			memcpy((void *) SCp->cmnd, (void *) SCp->data_cmnd,
-			       sizeof(SCp->data_cmnd));
-			SCp->request_buffer = SCp->buffer;
-			SCp->request_bufflen = SCp->bufflen;
-			SCp->use_sg = SCp->old_use_sg;
-			SCp->cmd_len = SCp->old_cmd_len;
-			SCp->sc_data_direction = SCp->sc_old_data_direction;
-			SCp->underflow = SCp->old_underflow;
-			
-		}
+				result = sense->cmnd[7];
+		} else
+			dma_unmap_single(hostdata->dev, slot->pCmd,
+					 sizeof(SCp->cmnd), DMA_TO_DEVICE);
+
 		free_slot(slot, hostdata);
 #ifdef NCR_700_DEBUG
 		if(NCR_700_get_depth(SCp->device) == 0 ||
@@ -979,6 +977,7 @@
 					"broken device is looping in contingent allegiance: ignoring\n");
 				NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
 			} else {
+				struct NCR_700_sense *sense = SCp->device->hostdata;
 #ifdef NCR_DEBUG
 				scsi_print_command(SCp);
 				printk("  cmd %p has status %d, requesting sense\n",
@@ -992,27 +991,25 @@
 				 * data associated with the command
 				 * here */
 				NCR_700_unmap(hostdata, SCp, slot);
-
-				SCp->cmnd[0] = REQUEST_SENSE;
-				SCp->cmnd[1] = (SCp->device->lun & 0x7) << 5;
-				SCp->cmnd[2] = 0;
-				SCp->cmnd[3] = 0;
-				SCp->cmnd[4] = sizeof(SCp->sense_buffer);
-				SCp->cmnd[5] = 0;
-				SCp->cmd_len = 6;
+				dma_unmap_single(hostdata->dev, slot->pCmd,
+						 sizeof(SCp->cmnd),
+						 DMA_TO_DEVICE);
+
+				sense->cmnd[0] = REQUEST_SENSE;
+				sense->cmnd[1] = (SCp->device->lun & 0x7) << 5;
+				sense->cmnd[2] = 0;
+				sense->cmnd[3] = 0;
+				sense->cmnd[4] = sizeof(SCp->sense_buffer);
+				sense->cmnd[5] = 0;
 				/* Here's a quiet hack: the
 				 * REQUEST_SENSE command is six bytes,
 				 * so store a flag indicating that
 				 * this was an internal sense request
 				 * and the original status at the end
 				 * of the command */
-				SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
-				SCp->cmnd[7] = hostdata->status[0];
-				SCp->use_sg = 0;
-				SCp->sc_data_direction = DMA_FROM_DEVICE;
-				dma_sync_single_for_device(hostdata->dev, slot->pCmd,
-							   SCp->cmd_len, DMA_TO_DEVICE);
-				SCp->request_bufflen = sizeof(SCp->sense_buffer);
+				sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
+				sense->cmnd[7] = hostdata->status[0];
+				slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE);
 				slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
 				slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
 				slot->SG[0].pAddr = bS_to_host(slot->dma_handle);
@@ -1024,6 +1021,7 @@
 				
 				/* queue the command for reissue */
 				slot->state = NCR_700_SLOT_QUEUED;
+				slot->flags = NCR_700_FLAG_AUTOSENSE;
 				hostdata->state = NCR_700_HOST_FREE;
 				hostdata->cmd = NULL;
 			}
@@ -1244,7 +1242,7 @@
 
 			if(SCp->use_sg) {
 				for(i = 0; i < SCp->use_sg + 1; i++) {
-					printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
+					printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->request_buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
 				}
 			}
 		}	       
@@ -1403,12 +1401,14 @@
 	/* keep interrupts disabled until we have the command correctly
 	 * set up so we cannot take a selection interrupt */
 
-	hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE,
+	hostdata->msgout[0] = NCR_700_identify((SCp->cmnd[0] != REQUEST_SENSE &&
+						slot->flags != NCR_700_FLAG_AUTOSENSE),
 					       SCp->device->lun);
 	/* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
 	 * if the negotiated transfer parameters still hold, so
 	 * always renegotiate them */
-	if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE) {
+	if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE ||
+	   slot->flags == NCR_700_FLAG_AUTOSENSE) {
 		NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
 	}
 
@@ -1417,7 +1417,8 @@
 	 * will refuse all tags, so send the request sense as untagged
 	 * */
 	if((hostdata->tag_negotiated & (1<<scmd_id(SCp)))
-	   && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) {
+	   && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE &&
+	       slot->flags != NCR_700_FLAG_AUTOSENSE)) {
 		count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]);
 	}
 
@@ -1863,8 +1864,9 @@
 		__u32 count = 0;
 
 		if(SCp->use_sg) {
-			sg_count = dma_map_sg(hostdata->dev, SCp->buffer,
-					      SCp->use_sg, direction);
+			sg_count = dma_map_sg(hostdata->dev,
+					      SCp->request_buffer, SCp->use_sg,
+					      direction);
 		} else {
 			vPtr = dma_map_single(hostdata->dev,
 					      SCp->request_buffer, 
@@ -1879,7 +1881,7 @@
 		for(i = 0; i < sg_count; i++) {
 
 			if(SCp->use_sg) {
-				struct scatterlist *sg = SCp->buffer;
+				struct scatterlist *sg = SCp->request_buffer;
 
 				vPtr = sg_dma_address(&sg[i]);
 				count = sg_dma_len(&sg[i]);
@@ -2042,6 +2044,11 @@
 	struct NCR_700_Host_Parameters *hostdata = 
 		(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
 
+	SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense));
+
+	if (!SDp->hostdata)
+		return -ENOMEM;
+
 	/* to do here: allocate memory; build a queue_full list */
 	if(SDp->tagged_supported) {
 		scsi_set_tag_type(SDp, MSG_ORDERED_TAG);
@@ -2065,7 +2072,8 @@
 STATIC void
 NCR_700_slave_destroy(struct scsi_device *SDp)
 {
-	/* to do here: deallocate memory */
+	kfree(SDp->hostdata);
+	SDp->hostdata = NULL;
 }
 
 static int
Index: BUILD-2.6/drivers/scsi/53c700.h
===================================================================
--- BUILD-2.6.orig/drivers/scsi/53c700.h	2006-06-13 15:53:10.000000000 -0500
+++ BUILD-2.6/drivers/scsi/53c700.h	2006-06-13 15:53:14.000000000 -0500
@@ -163,6 +163,8 @@
 	#define NCR_700_SLOT_BUSY (1|NCR_700_SLOT_MAGIC) /* slot has command active on HA */
 	#define NCR_700_SLOT_QUEUED (2|NCR_700_SLOT_MAGIC) /* slot has command to be made active on HA */
 	__u8	state;
+	#define NCR_700_FLAG_AUTOSENSE	0x01
+	__u8	flags;
 	int	tag;
 	__u32	resume_offset;
 	struct scsi_cmnd *cmnd;



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
  2006-06-12 19:19   ` Christoph Hellwig
  2006-06-14  2:31     ` James Bottomley
@ 2006-06-14  2:40     ` James Bottomley
  2006-06-14  2:43     ` James Bottomley
  2 siblings, 0 replies; 12+ messages in thread
From: James Bottomley @ 2006-06-14  2:40 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: jejb, fischer, linux-scsi

On Mon, 2006-06-12 at 21:19 +0200, Christoph Hellwig wrote:
> looks like no one but James looked at it as I attached a completely
> different patch that has been merged long ago.  Here's the real one:

Here's a piece that was missed from the recently added highpoint driver

James

Index: BUILD-2.6/drivers/scsi/hptiop.c
===================================================================
--- BUILD-2.6.orig/drivers/scsi/hptiop.c	2006-06-13 15:53:53.000000000 -0500
+++ BUILD-2.6/drivers/scsi/hptiop.c	2006-06-13 15:53:57.000000000 -0500
@@ -554,7 +554,7 @@
 	req->header.context = cpu_to_le32(IOPMU_QUEUE_ADDR_HOST_BIT |
 							(u32)_req->index);
 	req->header.context_hi32 = 0;
-	req->dataxfer_length = cpu_to_le32(scp->bufflen);
+	req->dataxfer_length = cpu_to_le32(scp->request_bufflen);
 	req->channel = scp->device->channel;
 	req->target = scp->device->id;
 	req->lun = scp->device->lun;



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
  2006-06-12 19:19   ` Christoph Hellwig
  2006-06-14  2:31     ` James Bottomley
  2006-06-14  2:40     ` James Bottomley
@ 2006-06-14  2:43     ` James Bottomley
  2006-06-14 18:43       ` FUJITA Tomonori
  2 siblings, 1 reply; 12+ messages in thread
From: James Bottomley @ 2006-06-14  2:43 UTC (permalink / raw)
  To: FUJITA Tomonori, Christoph Hellwig; +Cc: linux-scsi

On Mon, 2006-06-12 at 21:19 +0200, Christoph Hellwig wrote:
> looks like no one but James looked at it as I attached a completely
> different patch that has been merged long ago.  Here's the real one:

And finally, the scsi-target-2.6 tree likewise needs converting.  This
one I'm not sure about, since they appear to need the copy from
cmnd_data to cmnd which I just killed.  Can someone who knows this tree
look this over?

Thanks,

James

Index: BUILD-2.6/drivers/scsi/libsrp.c
===================================================================
--- BUILD-2.6.orig/drivers/scsi/libsrp.c	2006-06-13 15:54:32.000000000 -0500
+++ BUILD-2.6/drivers/scsi/libsrp.c	2006-06-13 15:54:35.000000000 -0500
@@ -434,7 +434,7 @@
 	scmd = scsi_host_get_command(shost, data_dir, GFP_KERNEL);
 	BUG_ON(!scmd);
 	scmd->SCp.ptr = (char *) iue;
-	memcpy(scmd->data_cmnd, cmd->cdb, MAX_COMMAND_SIZE);
+	memcpy(scmd->cmnd, cmd->cdb, MAX_COMMAND_SIZE);
 	scmd->request_bufflen = len;
 	scmd->tag = tag;
 	iue->scmd = scmd;
Index: BUILD-2.6/drivers/scsi/scsi_tgt_if.c
===================================================================
--- BUILD-2.6.orig/drivers/scsi/scsi_tgt_if.c	2006-06-13 15:54:32.000000000 -0500
+++ BUILD-2.6/drivers/scsi/scsi_tgt_if.c	2006-06-13 15:54:35.000000000 -0500
@@ -65,9 +65,6 @@
 	struct tgt_event *ev;
 	int err, len;
 
-	/* FIXME: we need scsi core to do that. */
-	memcpy(cmd->cmnd, cmd->data_cmnd, MAX_COMMAND_SIZE);
-
 	len = NLMSG_SPACE(sizeof(*ev));
 	/*
 	 * TODO: add MAX_COMMAND_SIZE to ev and add mempool
@@ -122,7 +119,7 @@
 	ev.k.tsk_mgmt_req.function = function;
 	ev.k.tsk_mgmt_req.tag = tag;
 	memcpy(ev.k.tsk_mgmt_req.lun, scsilun, sizeof(ev.k.tsk_mgmt_req.lun));
-	ev.k.tsk_mgmt_req.mid = (u64) data;
+	ev.k.tsk_mgmt_req.mid = (u64)(unsigned long)data;
 
 	dprintk("%d %x %llx %llx\n", host_no, function, (unsigned long long) tag,
 		(unsigned long long) ev.k.tsk_mgmt_req.mid);
Index: BUILD-2.6/drivers/scsi/scsi_tgt_lib.c
===================================================================
--- BUILD-2.6.orig/drivers/scsi/scsi_tgt_lib.c	2006-06-13 15:54:33.000000000 -0500
+++ BUILD-2.6/drivers/scsi/scsi_tgt_lib.c	2006-06-13 15:54:35.000000000 -0500
@@ -337,7 +337,7 @@
 
 	cmd->request_bufflen = rq->data_len;
 
-	dprintk("cmd %p addr %p cnt %d %lu\n", cmd, cmd->buffer, cmd->use_sg,
+	dprintk("cmd %p addr %p cnt %d %lu\n", cmd, cmd->request_buffer, cmd->use_sg,
 		rq_data_dir(rq));
 	count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer);
 	if (likely(count <= cmd->use_sg)) {
@@ -345,7 +345,7 @@
 		return 0;
 	}
 
-	eprintk("cmd %p addr %p cnt %d\n", cmd, cmd->buffer, cmd->use_sg);
+	eprintk("cmd %p addr %p cnt %d\n", cmd, cmd->request_buffer, cmd->use_sg);
 	scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
 	return -EINVAL;
 }
@@ -356,8 +356,8 @@
 {
 	struct request_queue *q = cmd->request->q;
 	struct request *rq = cmd->request;
-	void *uaddr = cmd->buffer;
-	unsigned int len = cmd->bufflen;
+	void *uaddr = cmd->request_buffer;
+	unsigned int len = cmd->request_bufflen;
 	struct bio *bio;
 	int err;
 
@@ -425,12 +425,12 @@
 	}
 
 	dprintk("cmd %p request_bufflen %u bufflen %u\n",
-		cmd, cmd->request_bufflen, cmd->bufflen);
+		cmd, cmd->request_bufflen, cmd->request_bufflen);
 
 	scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
 	bio_list_add(&tcmd->xfer_done_list, cmd->request->bio);
 
-	cmd->buffer += cmd->request_bufflen;
+	cmd->request_buffer += cmd->request_bufflen;
 	cmd->offset += cmd->request_bufflen;
 
 	if (!tcmd->xfer_list.head) {
@@ -439,7 +439,7 @@
 	}
 
 	dprintk("cmd2 %p request_bufflen %u bufflen %u\n",
-		cmd, cmd->request_bufflen, cmd->bufflen);
+		cmd, cmd->request_bufflen, cmd->request_bufflen);
 
 	bio = bio_list_pop(&tcmd->xfer_list);
 	BUG_ON(!bio);
@@ -556,12 +556,12 @@
 	 * store the userspace values here, the working values are
 	 * in the request_* values
 	 */
-	cmd->buffer = (void *)uaddr;
+	cmd->request_buffer = (void *)uaddr;
 	if (len)
-		cmd->bufflen = len;
+		cmd->request_bufflen = len;
 	cmd->result = result;
 
-	if (!cmd->bufflen) {
+	if (!cmd->request_bufflen) {
 		err = __scsi_tgt_transfer_response(cmd);
 		goto done;
 	}



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
  2006-06-14  2:43     ` James Bottomley
@ 2006-06-14 18:43       ` FUJITA Tomonori
  2006-06-14 19:03         ` Mike Christie
                           ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: FUJITA Tomonori @ 2006-06-14 18:43 UTC (permalink / raw)
  To: James.Bottomley; +Cc: fujita.tomonori, hch, linux-scsi

From: James Bottomley <James.Bottomley@SteelEye.com>
Subject: Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
Date: Tue, 13 Jun 2006 21:43:49 -0500

> On Mon, 2006-06-12 at 21:19 +0200, Christoph Hellwig wrote:
> > looks like no one but James looked at it as I attached a completely
> > different patch that has been merged long ago.  Here's the real one:
> 
> And finally, the scsi-target-2.6 tree likewise needs converting.  This
> one I'm not sure about, since they appear to need the copy from
> cmnd_data to cmnd which I just killed.  Can someone who knows this tree
> look this over?

Thanks for the patch.

tgt uses request_bufflen, bufflen, request_buffer, buffer to handle
very large requests (that involves multiple bios). We can add
substitutes into tgt specific data structure (scsi_tgt_cmd structure).

I sent a patch related with scsi_tgt_cmd structure last week.

http://marc.theaimsgroup.com/?l=linux-scsi&m=114960851929878&w=2

Will this patch be merged? I like to send a new patch on the top of
it.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
  2006-06-14 18:43       ` FUJITA Tomonori
@ 2006-06-14 19:03         ` Mike Christie
  2006-06-16  6:31         ` FUJITA Tomonori
  2006-06-20  7:49         ` FUJITA Tomonori
  2 siblings, 0 replies; 12+ messages in thread
From: Mike Christie @ 2006-06-14 19:03 UTC (permalink / raw)
  To: FUJITA Tomonori; +Cc: James.Bottomley, hch, linux-scsi

FUJITA Tomonori wrote:
> From: James Bottomley <James.Bottomley@SteelEye.com>
> Subject: Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
> Date: Tue, 13 Jun 2006 21:43:49 -0500
> 
>> On Mon, 2006-06-12 at 21:19 +0200, Christoph Hellwig wrote:
>>> looks like no one but James looked at it as I attached a completely
>>> different patch that has been merged long ago.  Here's the real one:
>> And finally, the scsi-target-2.6 tree likewise needs converting.  This
>> one I'm not sure about, since they appear to need the copy from
>> cmnd_data to cmnd which I just killed.  Can someone who knows this tree
>> look this over?
> 
> Thanks for the patch.
> 
> tgt uses request_bufflen, bufflen, request_buffer, buffer to handle
> very large requests (that involves multiple bios). We can add
> substitutes into tgt specific data structure (scsi_tgt_cmd structure).
> 

I think that is going to be best since we are the only users now.

> I sent a patch related with scsi_tgt_cmd structure last week.
> 
> http://marc.theaimsgroup.com/?l=linux-scsi&m=114960851929878&w=2
> 
> Will this patch be merged? I like to send a new patch on the top of
> it.
> -
> 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


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
  2006-06-14 18:43       ` FUJITA Tomonori
  2006-06-14 19:03         ` Mike Christie
@ 2006-06-16  6:31         ` FUJITA Tomonori
  2006-06-20  7:49         ` FUJITA Tomonori
  2 siblings, 0 replies; 12+ messages in thread
From: FUJITA Tomonori @ 2006-06-16  6:31 UTC (permalink / raw)
  To: James.Bottomley; +Cc: hch, linux-scsi

From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Subject: Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
Date: Thu, 15 Jun 2006 03:43:26 +0900

> From: James Bottomley <James.Bottomley@SteelEye.com>
> Subject: Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
> Date: Tue, 13 Jun 2006 21:43:49 -0500
> 
> > On Mon, 2006-06-12 at 21:19 +0200, Christoph Hellwig wrote:
> > > looks like no one but James looked at it as I attached a completely
> > > different patch that has been merged long ago.  Here's the real one:
> > 
> > And finally, the scsi-target-2.6 tree likewise needs converting.  This
> > one I'm not sure about, since they appear to need the copy from
> > cmnd_data to cmnd which I just killed.  Can someone who knows this tree
> > look this over?
> 
> Thanks for the patch.
> 
> tgt uses request_bufflen, bufflen, request_buffer, buffer to handle
> very large requests (that involves multiple bios). We can add
> substitutes into tgt specific data structure (scsi_tgt_cmd structure).
> 
> I sent a patch related with scsi_tgt_cmd structure last week.
> 
> http://marc.theaimsgroup.com/?l=linux-scsi&m=114960851929878&w=2
> 
> Will this patch be merged? I like to send a new patch on the top of
> it.

Kill the tgt code touching data_cmnd, sc->buffer, and sc->bufflen.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>

---

 drivers/scsi/libsrp.c       |    2 +-
 drivers/scsi/scsi_tgt_if.c  |    5 +----
 drivers/scsi/scsi_tgt_lib.c |   27 ++++++++++++++++-----------
 3 files changed, 18 insertions(+), 16 deletions(-)

35dcdd1d8ccb54502129abae619c58b4b3ab6eaf
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
index 8a4534c..b8a7c3d 100644
--- a/drivers/scsi/libsrp.c
+++ b/drivers/scsi/libsrp.c
@@ -434,7 +434,7 @@ int srp_cmd_perform(struct iu_entry *iue
 	scmd = scsi_host_get_command(shost, data_dir, GFP_KERNEL);
 	BUG_ON(!scmd);
 	scmd->SCp.ptr = (char *) iue;
-	memcpy(scmd->data_cmnd, cmd->cdb, MAX_COMMAND_SIZE);
+	memcpy(scmd->cmnd, cmd->cdb, MAX_COMMAND_SIZE);
 	scmd->request_bufflen = len;
 	scmd->tag = tag;
 	iue->scmd = scmd;
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
index ba1b75b..37e0feb 100644
--- a/drivers/scsi/scsi_tgt_if.c
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -65,9 +65,6 @@ int scsi_tgt_uspace_send(struct scsi_cmn
 	struct tgt_event *ev;
 	int err, len;
 
-	/* FIXME: we need scsi core to do that. */
-	memcpy(cmd->cmnd, cmd->data_cmnd, MAX_COMMAND_SIZE);
-
 	len = NLMSG_SPACE(sizeof(*ev));
 	/*
 	 * TODO: add MAX_COMMAND_SIZE to ev and add mempool
@@ -122,7 +119,7 @@ int scsi_tgt_uspace_send_tsk_mgmt(int ho
 	ev.k.tsk_mgmt_req.function = function;
 	ev.k.tsk_mgmt_req.tag = tag;
 	memcpy(ev.k.tsk_mgmt_req.lun, scsilun, sizeof(ev.k.tsk_mgmt_req.lun));
-	ev.k.tsk_mgmt_req.mid = (u64) data;
+	ev.k.tsk_mgmt_req.mid = (u64) (unsigned long) data;
 
 	dprintk("%d %x %llx %llx\n", host_no, function, (unsigned long long) tag,
 		(unsigned long long) ev.k.tsk_mgmt_req.mid);
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 2385db0..e82340c 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -50,6 +50,9 @@ struct scsi_tgt_cmd {
 	struct list_head hash_list;
 	struct request *rq;
 	u64 tag;
+
+	void *buffer;
+	unsigned bufflen;
 };
 
 #define TGT_HASH_ORDER	4
@@ -407,6 +410,7 @@ static void scsi_tgt_transfer_response(s
 static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 {
 	struct request *rq = cmd->request;
+	struct scsi_tgt_cmd *tcmd = rq->end_io_data;
 	int count;
 
 	cmd->use_sg = rq->nr_phys_segments;
@@ -416,7 +420,7 @@ static int scsi_tgt_init_cmd(struct scsi
 
 	cmd->request_bufflen = rq->data_len;
 
-	dprintk("cmd %p addr %p cnt %d %lu\n", cmd, cmd->buffer, cmd->use_sg,
+	dprintk("cmd %p addr %p cnt %d %lu\n", cmd, tcmd->buffer, cmd->use_sg,
 		rq_data_dir(rq));
 	count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer);
 	if (likely(count <= cmd->use_sg)) {
@@ -424,7 +428,7 @@ static int scsi_tgt_init_cmd(struct scsi
 		return 0;
 	}
 
-	eprintk("cmd %p addr %p cnt %d\n", cmd, cmd->buffer, cmd->use_sg);
+	eprintk("cmd %p addr %p cnt %d\n", cmd, tcmd->buffer, cmd->use_sg);
 	scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
 	return -EINVAL;
 }
@@ -435,8 +439,8 @@ static int scsi_map_user_pages(struct sc
 {
 	struct request_queue *q = cmd->request->q;
 	struct request *rq = cmd->request;
-	void *uaddr = cmd->buffer;
-	unsigned int len = cmd->bufflen;
+	void *uaddr = tcmd->buffer;
+	unsigned int len = tcmd->bufflen;
 	struct bio *bio;
 	int err;
 
@@ -504,12 +508,12 @@ send_uspace_err:
 	}
 
 	dprintk("cmd %p request_bufflen %u bufflen %u\n",
-		cmd, cmd->request_bufflen, cmd->bufflen);
+		cmd, cmd->request_bufflen, tcmd->bufflen);
 
 	scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
 	bio_list_add(&tcmd->xfer_done_list, cmd->request->bio);
 
-	cmd->buffer += cmd->request_bufflen;
+	tcmd->buffer += cmd->request_bufflen;
 	cmd->offset += cmd->request_bufflen;
 
 	if (!tcmd->xfer_list.head) {
@@ -518,7 +522,7 @@ send_uspace_err:
 	}
 
 	dprintk("cmd2 %p request_bufflen %u bufflen %u\n",
-		cmd, cmd->request_bufflen, cmd->bufflen);
+		cmd, cmd->request_bufflen, tcmd->bufflen);
 
 	bio = bio_list_pop(&tcmd->xfer_list);
 	BUG_ON(!bio);
@@ -604,6 +608,7 @@ int scsi_tgt_kspace_exec(int host_no, u3
 	struct Scsi_Host *shost;
 	struct scsi_cmnd *cmd;
 	struct request *rq;
+	struct scsi_tgt_cmd *tcmd;
 	int err = 0;
 
 	dprintk("%d %u %d %u %lx %u\n", host_no, cid, result,
@@ -635,12 +640,12 @@ int scsi_tgt_kspace_exec(int host_no, u3
 	 * store the userspace values here, the working values are
 	 * in the request_* values
 	 */
-	cmd->buffer = (void *)uaddr;
-	if (len)
-		cmd->bufflen = len;
+	tcmd = cmd->request->end_io_data;
+	tcmd->buffer = (void *)uaddr;
+	tcmd->bufflen = len;
 	cmd->result = result;
 
-	if (!cmd->bufflen) {
+	if (!tcmd->bufflen) {
 		err = __scsi_tgt_transfer_response(cmd);
 		goto done;
 	}
-- 
1.1.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
  2006-06-14 18:43       ` FUJITA Tomonori
  2006-06-14 19:03         ` Mike Christie
  2006-06-16  6:31         ` FUJITA Tomonori
@ 2006-06-20  7:49         ` FUJITA Tomonori
  2 siblings, 0 replies; 12+ messages in thread
From: FUJITA Tomonori @ 2006-06-20  7:49 UTC (permalink / raw)
  To: fujita.tomonori; +Cc: James.Bottomley, hch, linux-scsi

From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Subject: Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
Date: Thu, 15 Jun 2006 03:43:26 +0900

> From: James Bottomley <James.Bottomley@SteelEye.com>
> Subject: Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
> Date: Tue, 13 Jun 2006 21:43:49 -0500
> 
> > On Mon, 2006-06-12 at 21:19 +0200, Christoph Hellwig wrote:
> > > looks like no one but James looked at it as I attached a completely
> > > different patch that has been merged long ago.  Here's the real one:
> > 
> > And finally, the scsi-target-2.6 tree likewise needs converting.  This
> > one I'm not sure about, since they appear to need the copy from
> > cmnd_data to cmnd which I just killed.  Can someone who knows this tree
> > look this over?
> 
> Thanks for the patch.
> 
> tgt uses request_bufflen, bufflen, request_buffer, buffer to handle
> very large requests (that involves multiple bios). We can add
> substitutes into tgt specific data structure (scsi_tgt_cmd structure).
> 
> I sent a patch related with scsi_tgt_cmd structure last week.
> 
> http://marc.theaimsgroup.com/?l=linux-scsi&m=114960851929878&w=2
> 
> Will this patch be merged? I like to send a new patch on the top of
> it.

Hi James,

The 'update for cmnd field removal' patch got merged but the patch
refereed to in this mail did not. Did you just forget or you don't
like it?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
       [not found] <20060603112610.GB17018@lst.de>
  2006-06-03 11:31 ` [PATCH, RFC] hide EH backup data outside the scsi_cmnd Christoph Hellwig
  2006-06-10 16:08 ` Christoph Hellwig
@ 2006-07-24 17:27 ` Tony Luck
  2006-07-24 19:29   ` Christoph Hellwig
  2 siblings, 1 reply; 12+ messages in thread
From: Tony Luck @ 2006-07-24 17:27 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: jejb, fischer, linux-scsi

On 6/3/06, Christoph Hellwig <hch@lst.de> wrote:
> Currently struct scsi_cmnd has various fields that are used to backup
> original data after the corresponding fields have been overridden for
> EH commands.  This means drivers can easily get at it and misuse it.
> Due to the old_ naming this doesn't happen for most of them, but two
> that have different names have been used wrong a lot (see previous
> patch).

I guess that I'm an abuser  :-(

> Index: scsi-misc-2.6/include/scsi/scsi_cmnd.h

> -       void *buffer;           /* Data buffer */

arch/ia64/hp/sim/simscsi.c is still using this (and so doesn't compile
now that this change has hit mainline).  It seems that simscsi.c is
expecting to find a "scatterlist" there ... but looking at the rest of
the patch that removed this element, it isn't obvious where it went.

-Tony

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, RFC] hide EH backup data outside the scsi_cmnd
  2006-07-24 17:27 ` Tony Luck
@ 2006-07-24 19:29   ` Christoph Hellwig
  0 siblings, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2006-07-24 19:29 UTC (permalink / raw)
  To: Tony Luck; +Cc: Christoph Hellwig, jejb, fischer, linux-scsi

On Mon, Jul 24, 2006 at 10:27:55AM -0700, Tony Luck wrote:
> On 6/3/06, Christoph Hellwig <hch@lst.de> wrote:
> >Currently struct scsi_cmnd has various fields that are used to backup
> >original data after the corresponding fields have been overridden for
> >EH commands.  This means drivers can easily get at it and misuse it.
> >Due to the old_ naming this doesn't happen for most of them, but two
> >that have different names have been used wrong a lot (see previous
> >patch).
> 
> I guess that I'm an abuser  :-(
> 
> >Index: scsi-misc-2.6/include/scsi/scsi_cmnd.h
> 
> >-       void *buffer;           /* Data buffer */
> 
> arch/ia64/hp/sim/simscsi.c is still using this (and so doesn't compile
> now that this change has hit mainline).  It seems that simscsi.c is
> expecting to find a "scatterlist" there ... but looking at the rest of
> the patch that removed this element, it isn't obvious where it went.

Just change it to access the request_buffer member instead.  buffer
and request_buffer have been synonymous 99% of the time, and a driver
never even wants to access buffer.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2006-07-24 19:30 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20060603112610.GB17018@lst.de>
2006-06-03 11:31 ` [PATCH, RFC] hide EH backup data outside the scsi_cmnd Christoph Hellwig
2006-06-10 16:08 ` Christoph Hellwig
2006-06-12 19:19   ` Christoph Hellwig
2006-06-14  2:31     ` James Bottomley
2006-06-14  2:40     ` James Bottomley
2006-06-14  2:43     ` James Bottomley
2006-06-14 18:43       ` FUJITA Tomonori
2006-06-14 19:03         ` Mike Christie
2006-06-16  6:31         ` FUJITA Tomonori
2006-06-20  7:49         ` FUJITA Tomonori
2006-07-24 17:27 ` Tony Luck
2006-07-24 19:29   ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox