#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/slab.h>

#include <scsi/scsi.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_device.h>

#include "usb.h"
#include "scsiglue.h"
#include "transport.h"

/***********************************************************************
 * Data transfer routines
 ***********************************************************************/
/*
 * usb_stor_blocking_completion()
 */
static void usb_stor_blocking_completion(struct urb *urb)
{
	struct completion *urb_done_ptr = urb->context;

	/* pr_info("transport --- usb_stor_blocking_completion\n"); */
	complete(urb_done_ptr);
}

/*
 * usb_stor_msg_common()
 */
static int usb_stor_msg_common(struct us_data *us, int timeout)
{
	struct completion urb_done;
	long timeleft;
	int status;

	/* pr_info("transport --- usb_stor_msg_common\n"); */
	if (test_bit(US_FLIDX_ABORTING, &us->dflags))
		return -EIO;

	init_completion(&urb_done);

	us->current_urb->context = &urb_done;
	us->current_urb->actual_length = 0;
	us->current_urb->error_count = 0;
	us->current_urb->status = 0;

	us->current_urb->transfer_flags = 0;
	if (us->current_urb->transfer_buffer == us->iobuf)
		us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	us->current_urb->transfer_dma = us->iobuf_dma;
	us->current_urb->setup_dma = us->cr_dma;

	status = usb_submit_urb(us->current_urb, GFP_NOIO);
	if (status)
		return status;

	set_bit(US_FLIDX_URB_ACTIVE, &us->dflags);

	if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
		if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
			/* pr_info("-- cancelling URB\n"); */
			usb_unlink_urb(us->current_urb);
		}
	}

	timeleft = wait_for_completion_interruptible_timeout(&urb_done,
					timeout ? : MAX_SCHEDULE_TIMEOUT);
	clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags);

	if (timeleft <= 0) {
		/* pr_info("%s -- cancelling URB\n",
			timeleft == 0 ? "Timeout" : "Signal"); */
		usb_kill_urb(us->current_urb);
	}

	return us->current_urb->status;
}

/*
 * usb_stor_print_cmd():
 */
static void usb_stor_print_cmd(struct us_data *us, struct scsi_cmnd *srb)
{
	u8 *Cdb = srb->cmnd;
	u32   cmd = Cdb[0];

	switch (cmd) {
	case TEST_UNIT_READY:
		break;
	case INQUIRY:
		dev_dbg(&us->pusb_dev->dev,
				"scsi cmd %X --- SCSIOP_INQUIRY\n", cmd);
		break;
	case MODE_SENSE:
		dev_dbg(&us->pusb_dev->dev,
				"scsi cmd %X --- SCSIOP_MODE_SENSE\n", cmd);
		break;
	case START_STOP:
		dev_dbg(&us->pusb_dev->dev,
				"scsi cmd %X --- SCSIOP_START_STOP\n", cmd);
		break;
	case READ_CAPACITY:
		dev_dbg(&us->pusb_dev->dev,
				"scsi cmd %X --- SCSIOP_READ_CAPACITY\n", cmd);
		break;
	case READ_10:
		break;
	case WRITE_10:
		break;
	case ALLOW_MEDIUM_REMOVAL:
		dev_dbg(&us->pusb_dev->dev,
			"scsi cmd %X --- SCSIOP_ALLOW_MEDIUM_REMOVAL\n", cmd);
		break;
	default:
		dev_dbg(&us->pusb_dev->dev, "scsi cmd %X --- Other cmd\n", cmd);
		break;
	}
}

/*
 * usb_stor_control_msg()
 */
int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
		 u8 request, u8 requesttype, u16 value, u16 index,
		 void *data, u16 size, int timeout)
{
	int status;

	/* pr_info("transport --- usb_stor_control_msg\n"); */

	/* fill in the devrequest structure */
	us->cr->bRequestType = requesttype;
	us->cr->bRequest = request;
	us->cr->wValue = cpu_to_le16(value);
	us->cr->wIndex = cpu_to_le16(index);
	us->cr->wLength = cpu_to_le16(size);

	/* fill and submit the URB */
	usb_fill_control_urb(us->current_urb, us->pusb_dev, pipe,
			 (unsigned char *) us->cr, data, size,
			 usb_stor_blocking_completion, NULL);
	status = usb_stor_msg_common(us, timeout);

	/* return the actual length of the data transferred if no error */
	if (status == 0)
		status = us->current_urb->actual_length;
	return status;
}

/*
 * usb_stor_clear_halt()
 */
int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
{
	int result;
	int endp = usb_pipeendpoint(pipe);

	/* pr_info("transport --- usb_stor_clear_halt\n"); */
	if (usb_pipein(pipe))
		endp |= USB_DIR_IN;

	result = usb_stor_control_msg(us, us->send_ctrl_pipe,
		USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
		USB_ENDPOINT_HALT, endp,
		NULL, 0, 3*HZ);

	/* reset the endpoint toggle */
	if (result >= 0)
		/* usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe),
						usb_pipeout(pipe), 0); */
		usb_reset_endpoint(us->pusb_dev, endp);

	return result;
}

/*
 * interpret_urb_result()
 */
static int interpret_urb_result(struct us_data *us, unsigned int pipe,
		unsigned int length, int result, unsigned int partial)
{
	/* pr_info("transport --- interpret_urb_result\n"); */
	switch (result) {
	/* no error code; did we send all the data? */
	case 0:
		if (partial != length) {
			/* pr_info("-- short transfer\n"); */
			return USB_STOR_XFER_SHORT;
		}
		/* pr_info("-- transfer complete\n"); */
		return USB_STOR_XFER_GOOD;
	case -EPIPE:
		if (usb_pipecontrol(pipe)) {
			/* pr_info("-- stall on control pipe\n"); */
			return USB_STOR_XFER_STALLED;
		}
		/* pr_info("clearing endpoint halt for pipe 0x%x\n", pipe); */
		if (usb_stor_clear_halt(us, pipe) < 0)
			return USB_STOR_XFER_ERROR;
		return USB_STOR_XFER_STALLED;
	case -EOVERFLOW:
		/* pr_info("-- babble\n"); */
		return USB_STOR_XFER_LONG;
	case -ECONNRESET:
		/* pr_info("-- transfer cancelled\n"); */
		return USB_STOR_XFER_ERROR;
	case -EREMOTEIO:
		/* pr_info("-- short read transfer\n"); */
		return USB_STOR_XFER_SHORT;
	case -EIO:
		/* pr_info("-- abort or disconnect in progress\n"); */
		return USB_STOR_XFER_ERROR;
	default:
		/* pr_info("-- unknown error\n"); */
		return USB_STOR_XFER_ERROR;
	}
}

/*
 * usb_stor_bulk_transfer_buf()
 */
int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
	void *buf, unsigned int length, unsigned int *act_len)
{
	int result;

	/* pr_info("transport --- usb_stor_bulk_transfer_buf\n"); */

	/* fill and submit the URB */
	usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf,
				length, usb_stor_blocking_completion, NULL);
	result = usb_stor_msg_common(us, 0);

	/* store the actual length of the data transferred */
	if (act_len)
		*act_len = us->current_urb->actual_length;

	return interpret_urb_result(us, pipe, length, result,
					us->current_urb->actual_length);
}

/*
 * usb_stor_bulk_transfer_sglist()
 */
static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
		struct scatterlist *sg, int num_sg, unsigned int length,
		unsigned int *act_len)
{
	int result;

	/* pr_info("transport --- usb_stor_bulk_transfer_sglist\n"); */
	if (test_bit(US_FLIDX_ABORTING, &us->dflags))
		return USB_STOR_XFER_ERROR;

	/* initialize the scatter-gather request block */
	result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
					sg, num_sg, length, GFP_NOIO);
	if (result) {
		/* pr_info("usb_sg_init returned %d\n", result); */
		return USB_STOR_XFER_ERROR;
	}

	/* since the block has been initialized successfully,
					it's now okay to cancel it */
	set_bit(US_FLIDX_SG_ACTIVE, &us->dflags);

	/* did an abort/disconnect occur during the submission? */
	if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
		/* cancel the request, if it hasn't been cancelled already */
		if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
			/* pr_info("-- cancelling sg request\n"); */
			usb_sg_cancel(&us->current_sg);
		}
	}

	/* wait for the completion of the transfer */
	usb_sg_wait(&us->current_sg);
	clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags);

	result = us->current_sg.status;
	if (act_len)
		*act_len = us->current_sg.bytes;

	return interpret_urb_result(us, pipe, length,
					result, us->current_sg.bytes);
}

/*
 * usb_stor_bulk_srb()
 */
int usb_stor_bulk_srb(struct us_data *us, unsigned int pipe,
					struct scsi_cmnd *srb)
{
	unsigned int partial;
	int result = usb_stor_bulk_transfer_sglist(us, pipe, scsi_sglist(srb),
				      scsi_sg_count(srb), scsi_bufflen(srb),
				      &partial);

	scsi_set_resid(srb, scsi_bufflen(srb) - partial);
	return result;
}

/*
 * usb_stor_bulk_transfer_sg()
 */
int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
		void *buf, unsigned int length_left, int use_sg, int *residual)
{
	int result;
	unsigned int partial;

	/* pr_info("transport --- usb_stor_bulk_transfer_sg\n"); */
	/* are we scatter-gathering? */
	if (use_sg) {
		/* use the usb core scatter-gather primitives */
		result = usb_stor_bulk_transfer_sglist(us, pipe,
				(struct scatterlist *) buf, use_sg,
				length_left, &partial);
		length_left -= partial;
	} else {
		/* no scatter-gather, just make the request */
		result = usb_stor_bulk_transfer_buf(us, pipe, buf,
							length_left, &partial);
		length_left -= partial;
	}

	/* store the residual and return the error code */
	if (residual)
		*residual = length_left;
	return result;
}

/***********************************************************************
 * Transport routines
 ***********************************************************************/
/*
 * usb_stor_invoke_transport()
 */
void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
{
	int need_auto_sense;
	int result;

	/* pr_info("transport --- usb_stor_invoke_transport\n"); */
	usb_stor_print_cmd(us, srb);
	/* send the command to the transport layer */
	scsi_set_resid(srb, 0);
	result = us->transport(srb, us); /* usb_stor_Bulk_transport; */

	/* 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->dflags)) {
		/* pr_info("-- 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) {
		/* pr_info("-- 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 */
	need_auto_sense = 0;

	if ((us->protocol == USB_PR_CB || us->protocol == USB_PR_DPCM_USB) &&
				srb->sc_data_direction != DMA_FROM_DEVICE) {
		/* pr_info("-- CB transport device requiring auto-sense\n"); */
		need_auto_sense = 1;
	}

	if (result == USB_STOR_TRANSPORT_FAILED) {
		/* pr_info("-- transport indicates command failure\n"); */
		need_auto_sense = 1;
	}

	/* Now, if we need to do the auto-sense, let's do it */
	if (need_auto_sense) {
		int temp_result;
		struct scsi_eh_save ses;

		pr_info("Issuing auto-REQUEST_SENSE\n");

		scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE);

		/* we must do the protocol translation here */
		if (us->subclass == USB_SC_RBC ||
			us->subclass == USB_SC_SCSI ||
			us->subclass == USB_SC_CYP_ATACB) {
			srb->cmd_len = 6;
		} else {
			srb->cmd_len = 12;
		}
		/* issue the auto-sense command */
		scsi_set_resid(srb, 0);
		temp_result = us->transport(us->srb, us);

		/* let's clean up right away */
		scsi_eh_restore_cmnd(srb, &ses);

		if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
			/* pr_info("-- auto-sense aborted\n"); */
			srb->result = DID_ABORT << 16;
			goto Handle_Errors;
		}
		if (temp_result != USB_STOR_TRANSPORT_GOOD) {
			/* pr_info("-- auto-sense failure\n"); */
			srb->result = DID_ERROR << 16;
			if (!(us->fflags & US_FL_SCM_MULT_TARG))
				goto Handle_Errors;
			return;
		}

		/* set the result so the higher layers expect this data */
		srb->result = SAM_STAT_CHECK_CONDITION;

		if (result == USB_STOR_TRANSPORT_GOOD &&
			(srb->sense_buffer[2] & 0xaf) == 0 &&
			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 && scsi_bufflen(srb) -
				scsi_get_resid(srb) < srb->underflow)
		srb->result = (DID_ERROR << 16);
		/* v02 | (SUGGEST_RETRY << 24); */

	return;

Handle_Errors:
	scsi_lock(us_to_host(us));
	set_bit(US_FLIDX_RESETTING, &us->dflags);
	clear_bit(US_FLIDX_ABORTING, &us->dflags);
	scsi_unlock(us_to_host(us));

	mutex_unlock(&us->dev_mutex);
	result = usb_stor_port_reset(us);
	mutex_lock(&us->dev_mutex);

	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->dflags);
}

/*
 * ENE_stor_invoke_transport()
 */
void ENE_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
{
	int result = 0;

	/* pr_info("transport --- ENE_stor_invoke_transport\n"); */
	usb_stor_print_cmd(us, srb);
	/* send the command to the transport layer */
	scsi_set_resid(srb, 0);
	if (!(us->SM_Status.Ready))
		result = ENE_InitMedia(us);

	if (us->Power_IsResum == true) {
		result = ENE_InitMedia(us);
		us->Power_IsResum = false;
	}

	if (us->SM_Status.Ready)
		result = SM_SCSIIrp(us, srb);

	/* 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->dflags)) {
		/* pr_info("-- 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) {
		/* pr_info("-- 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;
	if (result == USB_STOR_TRANSPORT_FAILED) {
		/* pr_info("-- transport indicates command failure\n"); */
		/* need_auto_sense = 1; */
		BuildSenseBuffer(srb, us->SrbStatus);
		srb->result = SAM_STAT_CHECK_CONDITION;
	}

	/* Did we transfer less than the minimum amount required? */
	if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) -
					scsi_get_resid(srb) < srb->underflow)
		srb->result = (DID_ERROR << 16);
		/* v02 | (SUGGEST_RETRY << 24); */

	return;

Handle_Errors:
	scsi_lock(us_to_host(us));
	set_bit(US_FLIDX_RESETTING, &us->dflags);
	clear_bit(US_FLIDX_ABORTING, &us->dflags);
	scsi_unlock(us_to_host(us));

	mutex_unlock(&us->dev_mutex);
	result = usb_stor_port_reset(us);
	mutex_lock(&us->dev_mutex);

	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->dflags);
}

/*
 * BuildSenseBuffer()
 */
void BuildSenseBuffer(struct scsi_cmnd *srb, int SrbStatus)
{
	u8    *buf = srb->sense_buffer;
	u8    asc;

	pr_info("transport --- BuildSenseBuffer\n");
	switch (SrbStatus) {
	case SS_NOT_READY:
		asc = 0x3a;
		break;  /*  sense key = 0x02 */
	case SS_MEDIUM_ERR:
		asc = 0x0c;
		break;  /*  sense key = 0x03 */
	case SS_ILLEGAL_REQUEST:
		asc = 0x20;
		break;  /*  sense key = 0x05 */
	default:
		asc = 0x00;
		break;  /*  ?? */
	}

	memset(buf, 0, 18);
	buf[0x00] = 0xf0;
	buf[0x02] = SrbStatus;
	buf[0x07] = 0x0b;
	buf[0x0c] = asc;
}

/*
 * usb_stor_stop_transport()
 */
void usb_stor_stop_transport(struct us_data *us)
{
	/* pr_info("transport --- usb_stor_stop_transport\n"); */

	if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
		/* pr_info("-- cancelling URB\n"); */
		usb_unlink_urb(us->current_urb);
	}

	if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
		/* pr_info("-- cancelling sg request\n"); */
		usb_sg_cancel(&us->current_sg);
	}
}

/*
 * usb_stor_Bulk_max_lun()
 */
int usb_stor_Bulk_max_lun(struct us_data *us)
{
	int result;

	/* pr_info("transport --- usb_stor_Bulk_max_lun\n"); */
	/* issue the command */
	us->iobuf[0] = 0;
	result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
				 US_BULK_GET_MAX_LUN,
				 USB_DIR_IN | USB_TYPE_CLASS |
				 USB_RECIP_INTERFACE,
				 0, us->ifnum, us->iobuf, 1, HZ);

	/* pr_info("GetMaxLUN command result is %d, data is %d\n",
						result, us->iobuf[0]); */

	/* if we have a successful request, return the result */
	if (result > 0)
		return us->iobuf[0];

	return 0;
}

/*
 * usb_stor_Bulk_transport()
 */
int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
{
	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
	struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
	unsigned int transfer_length = scsi_bufflen(srb);
	unsigned int residue;
	int result;
	int fake_sense = 0;
	unsigned int cswlen;
	unsigned int cbwlen = US_BULK_CB_WRAP_LEN;

	/* pr_info("transport --- usb_stor_Bulk_transport\n"); */
	/* Take care of BULK32 devices; set extra byte to 0 */
	if (unlikely(us->fflags & US_FL_BULK32)) {
		cbwlen = 32;
		us->iobuf[31] = 0;
	}

	/* set up the command wrapper */
	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
	bcb->DataTransferLength = cpu_to_le32(transfer_length);
	bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0;
	bcb->Tag = ++us->tag;
	bcb->Lun = srb->device->lun;
	if (us->fflags & US_FL_SCM_MULT_TARG)
		bcb->Lun |= srb->device->id << 4;
	bcb->Length = srb->cmd_len;

	/* copy the command payload */
	memset(bcb->CDB, 0, sizeof(bcb->CDB));
	memcpy(bcb->CDB, srb->cmnd, bcb->Length);

	/*  send command */
	/* send it to out endpoint */
	/* pr_info("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n",
			le32_to_cpu(bcb->Signature), bcb->Tag,
			le32_to_cpu(bcb->DataTransferLength), bcb->Flags,
			(bcb->Lun >> 4), (bcb->Lun & 0x0F),
			bcb->Length); */
	result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
						bcb, cbwlen, NULL);
	/* pr_info("Bulk command transfer result=%d\n", result); */
	if (result != USB_STOR_XFER_GOOD)
		return USB_STOR_TRANSPORT_ERROR;

	if (unlikely(us->fflags & US_FL_GO_SLOW))
		udelay(125);

	/*  R/W data */
	if (transfer_length) {
		unsigned int pipe;
		if (srb->sc_data_direction == DMA_FROM_DEVICE)
			pipe = us->recv_bulk_pipe;
		else
			pipe = us->send_bulk_pipe;

		result = usb_stor_bulk_srb(us, pipe, srb);
		/* pr_info("Bulk data transfer result 0x%x\n", result); */
		if (result == USB_STOR_XFER_ERROR)
			return USB_STOR_TRANSPORT_ERROR;

		if (result == USB_STOR_XFER_LONG)
			fake_sense = 1;
	}

	/* get CSW for device status */
	/* pr_info("Attempting to get CSW...\n"); */
	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
						US_BULK_CS_WRAP_LEN, &cswlen);

	if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
		/* pr_info("Received 0-length CSW; retrying...\n"); */
		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
						US_BULK_CS_WRAP_LEN, &cswlen);
	}

	/* did the attempt to read the CSW fail? */
	if (result == USB_STOR_XFER_STALLED) {
		/* get the status again */
		/* pr_info("Attempting to get CSW (2nd try)...\n"); */
		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
						US_BULK_CS_WRAP_LEN, NULL);
	}

	/* if we still have a failure at this point, we're in trouble */
	/* pr_info("Bulk status result = %d\n", result); */
	if (result != USB_STOR_XFER_GOOD)
		return USB_STOR_TRANSPORT_ERROR;

	/* check bulk status */
	residue = le32_to_cpu(bcs->Residue);
	/* pr_info("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
				le32_to_cpu(bcs->Signature),
				bcs->Tag, residue, bcs->Status); */
	if (!(bcs->Tag == us->tag ||
		(us->fflags & US_FL_BULK_IGNORE_TAG)) ||
		bcs->Status > US_BULK_STAT_PHASE) {
		/* pr_info("Bulk logical error\n"); */
		return USB_STOR_TRANSPORT_ERROR;
	}

	if (!us->bcs_signature) {
		us->bcs_signature = bcs->Signature;
		/* if (us->bcs_signature != cpu_to_le32(US_BULK_CS_SIGN)) */
		/* pr_info("Learnt BCS signature 0x%08X\n",
				le32_to_cpu(us->bcs_signature)); */
	} else if (bcs->Signature != us->bcs_signature) {
		/* pr_info("Signature mismatch: got %08X, expecting %08X\n",
			  le32_to_cpu(bcs->Signature),
			  le32_to_cpu(us->bcs_signature)); */
		return USB_STOR_TRANSPORT_ERROR;
	}

	/* try to compute the actual residue, based on how much data
	 * was really transferred and what the device tells us */
	if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {

		/* Heuristically detect devices that generate bogus residues
		 * by seeing what happens with INQUIRY and READ CAPACITY
		 * commands.
		 */
		if (bcs->Status == US_BULK_STAT_OK &&
				scsi_get_resid(srb) == 0 &&
					((srb->cmnd[0] == INQUIRY &&
						transfer_length == 36) ||
					(srb->cmnd[0] == READ_CAPACITY &&
						transfer_length == 8))) {
			us->fflags |= US_FL_IGNORE_RESIDUE;

		} else {
			residue = min(residue, transfer_length);
			scsi_set_resid(srb, max_t(int, scsi_get_resid(srb),
							residue));
		}
	}

	/* based on the status code, we report good or bad */
	switch (bcs->Status) {
	case US_BULK_STAT_OK:
		if (fake_sense) {
			memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB,
					sizeof(usb_stor_sense_invalidCDB));
			return USB_STOR_TRANSPORT_NO_SENSE;
		}
		return USB_STOR_TRANSPORT_GOOD;

	case US_BULK_STAT_FAIL:
		return USB_STOR_TRANSPORT_FAILED;

	case US_BULK_STAT_PHASE:
		return USB_STOR_TRANSPORT_ERROR;
	}
	return USB_STOR_TRANSPORT_ERROR;
}

/***********************************************************************
 * Reset routines
 ***********************************************************************/
/*
 * usb_stor_reset_common()
 */
static int usb_stor_reset_common(struct us_data *us,
		u8 request, u8 requesttype,
		u16 value, u16 index, void *data, u16 size)
{
	int result;
	int result2;

	/* pr_info("transport --- usb_stor_reset_common\n"); */
	if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
		/* pr_info("No reset during disconnect\n"); */
		return -EIO;
	}

	result = usb_stor_control_msg(us, us->send_ctrl_pipe,
			request, requesttype, value, index, data, size,	5*HZ);

	if (result < 0) {
		/* pr_info("Soft reset failed: %d\n", result); */
		return result;
	}

	wait_event_interruptible_timeout(us->delay_wait,
			test_bit(US_FLIDX_DISCONNECTING, &us->dflags),	HZ*6);

	if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
		/* pr_info("Reset interrupted by disconnect\n"); */
		return -EIO;
	}

	/* pr_info("Soft reset: clearing bulk-in endpoint halt\n"); */
	result = usb_stor_clear_halt(us, us->recv_bulk_pipe);

	/* pr_info("Soft reset: clearing bulk-out endpoint halt\n"); */
	result2 = usb_stor_clear_halt(us, us->send_bulk_pipe);

	/* return a result code based on the result of the clear-halts */
	if (result >= 0)
		result = result2;
	/* if (result < 0) */
		/* pr_info("Soft reset failed\n"); */
	/* else */
		/* pr_info("Soft reset done\n"); */
	return result;
}

/*
 * usb_stor_Bulk_reset()
 */
int usb_stor_Bulk_reset(struct us_data *us)
{
	/* pr_info("transport --- usb_stor_Bulk_reset\n"); */
	return usb_stor_reset_common(us, US_BULK_RESET_REQUEST,
				 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
				 0, us->ifnum, NULL, 0);
}

/*
 * usb_stor_port_reset()
 */
int usb_stor_port_reset(struct us_data *us)
{
	int result;

	/* pr_info("transport --- usb_stor_port_reset\n"); */
	result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
	if (result < 0)
		pr_info("unable to lock device for reset: %d\n", result);
	else {
		/* Were we disconnected while waiting for the lock? */
		if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
			result = -EIO;
			/* pr_info("No reset during disconnect\n"); */
		} else {
			result = usb_reset_device(us->pusb_dev);
			/* pr_info("usb_reset_composite_device returns %d\n",
								result); */
		}
		usb_unlock_device(us->pusb_dev);
	}
	return result;
}


