unsigned long old_serial_number; 
void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us){	int need_auto_sense;	int result;	/* send the command to the transport layer */	srb->resid = 0;	result = us->transport(srb, us);	/* if the command gets aborted by the higher layers, we need to	 * short-circuit all other processing	 */	if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {		US_DEBUGP("-- command was aborted\n");		srb->result = DID_ABORT << 16;		goto Handle_Errors;	}	/* if there is a transport error, reset and don't auto-sense */	if (result == USB_STOR_TRANSPORT_ERROR) {		US_DEBUGP("-- transport indicates error, resetting\n");		srb->result = DID_ERROR << 16;		goto Handle_Errors;	}	/* if the transport provided its own sense data, don't auto-sense */	if (result == USB_STOR_TRANSPORT_NO_SENSE) {		srb->result = SAM_STAT_CHECK_CONDITION;		return;	}	srb->result = SAM_STAT_GOOD;	/* Determine if we need to auto-sense	 *	 * I normally don't use a flag like this, but it's almost impossible	 * to understand what's going on here if I don't.	 */	need_auto_sense = 0;	/*	 * If we're running the CB transport, which is incapable	 * of determining status on its own, we will auto-sense	 * unless the operation involved a data-in transfer.  Devices	 * can signal most data-in errors by stalling the bulk-in pipe.	 */	if ((us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) &&			srb->sc_data_direction != DMA_FROM_DEVICE) {		US_DEBUGP("-- CB transport device requiring auto-sense\n");		need_auto_sense = 1;	}	/*	 * If we have a failure, we're going to do a REQUEST_SENSE 	 * automatically.  Note that we differentiate between a command	 * "failure" and an "error" in the transport mechanism.	 */	if (result == USB_STOR_TRANSPORT_FAILED) {		US_DEBUGP("-- transport indicates command failure\n");		need_auto_sense = 1;	}	/*	 * A short transfer on a command where we don't expect it	 * is unusual, but it doesn't mean we need to auto-sense.	 */	if ((srb->resid > 0) &&	    !((srb->cmnd[0] == REQUEST_SENSE) ||	      (srb->cmnd[0] == INQUIRY) ||	      (srb->cmnd[0] == MODE_SENSE) ||	      (srb->cmnd[0] == LOG_SENSE) ||	      (srb->cmnd[0] == MODE_SENSE_10))) {		US_DEBUGP("-- unexpectedly short transfer\n");	}	/* Now, if we need to do the auto-sense, let's do it */	if (need_auto_sense) {		int temp_result;		void* old_request_buffer;		unsigned short old_sg;		unsigned old_request_bufflen;		unsigned char old_sc_data_direction;		unsigned char old_cmd_len;		unsigned char old_cmnd[MAX_COMMAND_SIZE];		unsigned long old_serial_number;		int old_resid;		US_DEBUGP("Issuing auto-REQUEST_SENSE\n");		/* save the old command */		memcpy(old_cmnd, srb->cmnd, MAX_COMMAND_SIZE);		old_cmd_len = srb->cmd_len;		/* set the command and the LUN */		memset(srb->cmnd, 0, MAX_COMMAND_SIZE);		srb->cmnd[0] = REQUEST_SENSE;		srb->cmnd[1] = old_cmnd[1] & 0xE0;		srb->cmnd[4] = 18;		/* FIXME: we must do the protocol translation here */		if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)			srb->cmd_len = 6;		else			srb->cmd_len = 12;		/* set the transfer direction */		old_sc_data_direction = srb->sc_data_direction;		srb->sc_data_direction = DMA_FROM_DEVICE;		/* use the new buffer we have */		old_request_buffer = srb->request_buffer;		srb->request_buffer = srb->sense_buffer;		/* set the buffer length for transfer */		old_request_bufflen = srb->request_bufflen;		srb->request_bufflen = 18;		/* set up for no scatter-gather use */		old_sg = srb->use_sg;		srb->use_sg = 0;		/* change the serial number -- toggle the high bit*/		old_serial_number = srb->serial_number;		srb->serial_number ^= 0x80000000;		/* issue the auto-sense command */		old_resid = srb->resid;		srb->resid = 0;		temp_result = us->transport(us->srb, us);		/* let's clean up right away */		srb->resid = old_resid;		srb->request_buffer = old_request_buffer;		srb->request_bufflen = old_request_bufflen;		srb->use_sg = old_sg;		srb->serial_number = old_serial_number;		srb->sc_data_direction = old_sc_data_direction;		srb->cmd_len = old_cmd_len;		memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);		if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {			US_DEBUGP("-- auto-sense aborted\n");			srb->result = DID_ABORT << 16;			goto Handle_Errors;		}		if (temp_result != USB_STOR_TRANSPORT_GOOD) {			US_DEBUGP("-- auto-sense failure\n");			/* we skip the reset if this happens to be a			 * multi-target device, since failure of an			 * auto-sense is perfectly valid			 */			srb->result = DID_ERROR << 16;			if (!(us->flags & US_FL_SCM_MULT_TARG))				goto Handle_Errors;			return;		}		US_DEBUGP("-- Result from auto-sense is %d\n", temp_result);		US_DEBUGP("-- code: 0x%x, key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n",			  srb->sense_buffer[0],			  srb->sense_buffer[2] & 0xf,			  srb->sense_buffer[12], 			  srb->sense_buffer[13]);#ifdef CONFIG_USB_STORAGE_DEBUG		usb_stor_show_sense(			  srb->sense_buffer[2] & 0xf,			  srb->sense_buffer[12], 			  srb->sense_buffer[13]);#endif		/* set the result so the higher layers expect this data */		srb->result = SAM_STAT_CHECK_CONDITION;		/* If things are really okay, then let's show that.  Zero		 * out the sense buffer so the higher layers won't realize		 * we did an unsolicited auto-sense. */		if (result == USB_STOR_TRANSPORT_GOOD &&			/* Filemark 0, ignore EOM, ILI 0, no sense */				(srb->sense_buffer[2] & 0xaf) == 0 &&			/* No ASC or ASCQ */				srb->sense_buffer[12] == 0 &&				srb->sense_buffer[13] == 0) {			srb->result = SAM_STAT_GOOD;			srb->sense_buffer[0] = 0x0;		}	}	/* Did we transfer less than the minimum amount required? */	if (srb->result == SAM_STAT_GOOD &&			srb->request_bufflen - srb->resid < srb->underflow)		srb->result = (DID_ERROR << 16) | (SUGGEST_RETRY << 24);	return;	/* Error and abort processing: try to resynchronize with the device	 * by issuing a port reset.  If that fails, try a class-specific	 * device reset. */  Handle_Errors:	/* Let the SCSI layer know we are doing a reset, set the	 * RESETTING bit, and clear the ABORTING bit so that the reset	 * may proceed. */	scsi_lock(us_to_host(us));	usb_stor_report_bus_reset(us);	set_bit(US_FLIDX_RESETTING, &us->flags);	clear_bit(US_FLIDX_ABORTING, &us->flags);	scsi_unlock(us_to_host(us));	result = usb_stor_port_reset(us);	if (result < 0) {		scsi_lock(us_to_host(us));		usb_stor_report_device_reset(us);		scsi_unlock(us_to_host(us));		us->transport_reset(us);	}	clear_bit(US_FLIDX_RESETTING, &us->flags);}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/0f64e078139109d1902e5b1274c23cec9a9ad12e/transport.c/clean/drivers/usb/storage/transport.c