summaryrefslogtreecommitdiff
path: root/drivers/staging/keucr/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/keucr/transport.c')
-rw-r--r--drivers/staging/keucr/transport.c865
1 files changed, 0 insertions, 865 deletions
diff --git a/drivers/staging/keucr/transport.c b/drivers/staging/keucr/transport.c
deleted file mode 100644
index 5e59525271f8..000000000000
--- a/drivers/staging/keucr/transport.c
+++ /dev/null
@@ -1,865 +0,0 @@
-#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;
-}
-
-