#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)
{
	PBYTE   Cdb = srb->cmnd;
	DWORD   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)
{
	BYTE    *buf = srb->sense_buffer;
	BYTE    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;
}


