Commit e391d5f6 authored by Matthew Dharm's avatar Matthew Dharm Committed by Linus Torvalds

[PATCH] usb-storage: convert to common transfer functions

This patch makes all sub-drivers use the same data-moving functions.  It
also eliminates the duplicate functions from raw_bulk.c
parent 2167f96c
......@@ -67,25 +67,23 @@ static int datafab_determine_lun(struct us_data *us,
static inline int
datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) {
unsigned int act_len; /* ignored */
if (len == 0)
return USB_STOR_XFER_GOOD;
US_DEBUGP("datafab_bulk_read: len = %d\n", len);
return usb_storage_raw_bulk(us, SCSI_DATA_READ, data, len, &act_len);
return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
data, len, NULL);
}
static inline int
datafab_bulk_write(struct us_data *us, unsigned char *data, unsigned int len) {
unsigned int act_len; /* ignored */
if (len == 0)
return USB_STOR_XFER_GOOD;
US_DEBUGP("datafab_bulk_write: len = %d\n", len);
return usb_storage_raw_bulk(us, SCSI_DATA_WRITE, data, len, &act_len);
return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
data, len, NULL);
}
......
......@@ -62,13 +62,12 @@ static inline int jumpshot_bulk_read(struct us_data *us,
unsigned char *data,
unsigned int len)
{
unsigned int act_len; /* ignored */
if (len == 0)
return USB_STOR_XFER_GOOD;
US_DEBUGP("jumpshot_bulk_read: len = %d\n", len);
return usb_storage_raw_bulk(us, SCSI_DATA_READ, data, len, &act_len);
return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
data, len, NULL);
}
......@@ -76,13 +75,12 @@ static inline int jumpshot_bulk_write(struct us_data *us,
unsigned char *data,
unsigned int len)
{
unsigned int act_len; /* ignored */
if (len == 0)
return USB_STOR_XFER_GOOD;
US_DEBUGP("jumpshot_bulk_write: len = %d\n", len);
return usb_storage_raw_bulk(us, SCSI_DATA_WRITE, data, len, &act_len);
return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
data, len, NULL);
}
......@@ -95,11 +93,11 @@ static int jumpshot_get_status(struct us_data *us)
return USB_STOR_TRANSPORT_ERROR;
// send the setup
rc = usb_storage_send_control(us, us->recv_ctrl_pipe,
rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
0, 0xA0, 0, 7, &reply, 1);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
if (reply != 0x50) {
US_DEBUGP("jumpshot_get_status: 0x%2x\n",
......@@ -159,9 +157,9 @@ static int jumpshot_read_data(struct us_data *us,
command[5] |= (sector >> 24) & 0x0F;
// send the setup + command
result = usb_storage_send_control(us, us->send_ctrl_pipe,
result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
0, 0x20, 0, 1, command, 7);
if (result != USB_STOR_TRANSPORT_GOOD)
if (result != USB_STOR_XFER_GOOD)
goto leave;
// read the result
......@@ -245,8 +243,10 @@ static int jumpshot_write_data(struct us_data *us,
command[5] |= (sector >> 24) & 0x0F;
// send the setup + command
result = usb_storage_send_control(us, us->send_ctrl_pipe,
result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
0, 0x20, 0, 1, command, 7);
if (result != USB_STOR_XFER_GOOD)
goto leave;
// send the data
result = jumpshot_bulk_write(us, ptr, len);
......@@ -299,10 +299,10 @@ static int jumpshot_id_device(struct us_data *us,
return USB_STOR_TRANSPORT_ERROR;
// send the setup
rc = usb_storage_send_control(us, us->send_ctrl_pipe,
rc = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
0, 0x20, 0, 6, command, 2);
if (rc != USB_STOR_TRANSPORT_GOOD) {
if (rc != USB_STOR_XFER_GOOD) {
US_DEBUGP("jumpshot_id_device: Gah! "
"send_control for read_capacity failed\n");
return rc;
......
......@@ -13,219 +13,6 @@
#include "transport.h"
#include "raw_bulk.h"
#ifdef CONFIG_USB_STORAGE_DEBUG
#define DEBUG_PRCT 12
#else
#define DEBUG_PRCT 0
#endif
/*
* Send a control message and wait for the response.
*
* us - the pointer to the us_data structure for the device to use
*
* request - the URB Setup Packet's first 6 bytes. The first byte always
* corresponds to the request type, and the second byte always corresponds
* to the request. The other 4 bytes do not correspond to value and index,
* since they are used in a custom way by the SCM protocol.
*
* xfer_data - a buffer from which to get, or to which to store, any data
* that gets send or received, respectively, with the URB. Even though
* it looks like we allocate a buffer in this code for the data, xfer_data
* must contain enough allocated space.
*
* xfer_len - the number of bytes to send or receive with the URB.
*
*/
int
usb_storage_send_control(struct us_data *us,
unsigned int pipe,
unsigned char request,
unsigned char requesttype,
unsigned int value,
unsigned int index,
unsigned char *xfer_data,
unsigned int xfer_len) {
int result;
// Send the URB to the device and wait for a response.
/* Why are request and request type reversed in this call? */
result = usb_stor_control_msg(us, pipe,
request, requesttype, value, index,
xfer_data, xfer_len);
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_send_control(): transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED;
}
// Check the return code for the command.
if (result < 0) {
/* a stall indicates a protocol error */
if (result == -EPIPE) {
US_DEBUGP("-- Stall on control pipe\n");
return USB_STOR_TRANSPORT_ERROR;
}
/* Uh oh... serious problem here */
return USB_STOR_TRANSPORT_ERROR;
}
return USB_STOR_TRANSPORT_GOOD;
}
int
usb_storage_raw_bulk(struct us_data *us, int direction, unsigned char *data,
unsigned int len, unsigned int *act_len) {
int result;
unsigned int pipe;
if (direction == SCSI_DATA_READ)
pipe = us->recv_bulk_pipe;
else
pipe = us->send_bulk_pipe;
result = usb_stor_bulk_msg(us, data, pipe, len, act_len);
/* if we stall, we need to clear it before we go on */
if (result == -EPIPE) {
US_DEBUGP("EPIPE: clearing endpoint halt for"
" pipe 0x%x, stalled at %d bytes\n",
pipe, *act_len);
if (usb_stor_clear_halt(us, pipe) < 0)
return USB_STOR_XFER_ERROR;
return USB_STOR_XFER_STALLED;
}
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_storage_raw_bulk(): transfer aborted\n");
return USB_STOR_XFER_ABORTED;
}
if (result) {
/* NAK - that means we've retried a few times already */
if (result == -ETIMEDOUT)
US_DEBUGP("raw_bulk(): device NAKed\n");
else if (result == -EOVERFLOW)
US_DEBUGP("raw_bulk(): babble/overflow\n");
else if (result == -ECONNRESET)
US_DEBUGP("raw_bulk(): asynchronous reset\n");
else if (result != -EPIPE)
US_DEBUGP("raw_bulk(): unknown error %d\n",
result);
return USB_STOR_XFER_ERROR;
}
if (*act_len != len) {
US_DEBUGP("Warning: Transferred only %d of %d bytes\n",
*act_len, len);
return USB_STOR_XFER_SHORT;
}
#if 0
US_DEBUGP("raw_bulk(): Transferred %s %d of %d bytes\n",
(direction == SCSI_DATA_READ) ? "in" : "out",
*act_len, len);
#endif
return USB_STOR_XFER_GOOD;
}
int
usb_storage_bulk_transport(struct us_data *us, int direction,
unsigned char *data, unsigned int len,
int use_sg) {
int result = USB_STOR_XFER_ERROR;
int transferred = 0;
int i;
struct scatterlist *sg;
unsigned int act_len;
if (len == 0)
return USB_STOR_XFER_GOOD;
#if DEBUG_PRCT
if (direction == SCSI_DATA_WRITE && !use_sg) {
char string[64];
/* Debug-print the first N bytes of the write transfer */
strcpy(string, "wr: ");
for (i=0; i<len && i<DEBUG_PRCT; i++) {
sprintf(string+strlen(string), "%02X ", data[i]);
if ((i%16) == 15) {
US_DEBUGP("%s\n", string);
strcpy(string, "wr: ");
}
}
if ((i%16)!=0)
US_DEBUGP("%s\n", string);
}
US_DEBUGP("SCM data %s transfer %d sg buffers %d\n",
(direction == SCSI_DATA_READ) ? "in" : "out",
len, use_sg);
#endif /* DEBUG_PRCT */
if (!use_sg)
result = usb_storage_raw_bulk(us, direction,
data, len, &act_len);
else {
sg = (struct scatterlist *)data;
for (i=0; i<use_sg && transferred<len; i++) {
unsigned char *buf;
unsigned int length;
buf = sg_address(sg[i]);
length = len-transferred;
if (length > sg[i].length)
length = sg[i].length;
result = usb_storage_raw_bulk(us, direction,
buf, length, &act_len);
if (result != USB_STOR_XFER_GOOD)
break;
transferred += length;
}
}
#if DEBUG_PRCT
if (direction == SCSI_DATA_READ && !use_sg) {
char string[64];
/* Debug-print the first N bytes of the read transfer */
strcpy(string, "rd: ");
for (i=0; i<len && i<act_len && i<DEBUG_PRCT; i++) {
sprintf(string+strlen(string), "%02X ", data[i]);
if ((i%16) == 15) {
US_DEBUGP("%s\n", string);
strcpy(string, "rd: ");
}
}
if ((i%16)!=0)
US_DEBUGP("%s\n", string);
}
#endif /* DEBUG_PRCT */
return result;
}
/*
* The routines below convert scatter-gather to single buffer.
* Some drivers claim this is necessary.
......
#ifndef _USB_STORAGE_RAW_BULK_H_
#define _USB_STORAGE_RAW_BULK_H_
/* usb bulk */
extern int usb_storage_send_control(
struct us_data *us, unsigned int pipe,
unsigned char request, unsigned char requesttype,
unsigned int value, unsigned int index,
unsigned char *xfer_data, unsigned int xfer_len);
extern int usb_storage_raw_bulk(
struct us_data *us, int direction,
unsigned char *data, unsigned int len, unsigned int *act_len);
extern int usb_storage_bulk_transport(
struct us_data *us, int direction,
unsigned char *data, unsigned int len, int use_sg);
/* scatter-gather */
extern unsigned char *us_copy_from_sgbuf(
unsigned char *content, int buflen,
......
......@@ -226,6 +226,7 @@ sddr09_send_command(struct us_data *us,
unsigned int xfer_len) {
unsigned int pipe;
unsigned char requesttype = (0x41 | direction);
int rc;
// Get the receive or send control pipe number
......@@ -234,8 +235,10 @@ sddr09_send_command(struct us_data *us,
else
pipe = us->send_ctrl_pipe;
return usb_storage_send_control(us, pipe, request, requesttype,
rc = usb_stor_ctrl_transfer(us, pipe, request, requesttype,
0, 0, xfer_data, xfer_len);
return (rc == USB_STOR_XFER_GOOD ? USB_STOR_TRANSPORT_GOOD :
USB_STOR_TRANSPORT_ERROR);
}
static int
......@@ -276,7 +279,6 @@ sddr09_request_sense(struct us_data *us, unsigned char *sensebuf, int buflen) {
0x03, LUNBITS, 0, 0, buflen, 0, 0, 0, 0, 0, 0, 0
};
int result;
unsigned int act_len;
result = sddr09_send_scsi_command(us, command, sizeof(command));
if (result != USB_STOR_TRANSPORT_GOOD) {
......@@ -284,7 +286,8 @@ sddr09_request_sense(struct us_data *us, unsigned char *sensebuf, int buflen) {
return result;
}
result = usb_storage_raw_bulk(us, SCSI_DATA_READ, sensebuf, buflen, &act_len);
result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
sensebuf, buflen, NULL);
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("request sense bulk in failed\n");
return USB_STOR_TRANSPORT_ERROR;
......@@ -343,11 +346,11 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress,
return result;
}
result = usb_storage_bulk_transport(us, SCSI_DATA_READ,
buf, bulklen, use_sg);
result = usb_stor_bulk_transfer_sg(us, us->recv_bulk_pipe,
buf, bulklen, use_sg, NULL);
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("Result for bulk_transport in sddr09_read2%d %d\n",
US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n",
x, result);
return USB_STOR_TRANSPORT_ERROR;
}
......@@ -510,11 +513,11 @@ sddr09_writeX(struct us_data *us,
return result;
}
result = usb_storage_bulk_transport(us, SCSI_DATA_WRITE,
buf, bulklen, use_sg);
result = usb_stor_bulk_transfer_sg(us, us->send_bulk_pipe,
buf, bulklen, use_sg, NULL);
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("Result for bulk_transport in sddr09_writeX %d\n",
US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n",
result);
return USB_STOR_TRANSPORT_ERROR;
}
......@@ -592,11 +595,11 @@ sddr09_read_sg_test_only(struct us_data *us) {
if (!buf)
return USB_STOR_TRANSPORT_ERROR;
result = usb_storage_bulk_transport(us, SCSI_DATA_READ,
buf, bulklen, 0);
result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
buf, bulklen, NULL);
kfree(buf);
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("Result for bulk_transport in sddr09_read_sg %d\n",
US_DEBUGP("Result for bulk_transfer in sddr09_read_sg %d\n",
result);
return USB_STOR_TRANSPORT_ERROR;
}
......@@ -631,8 +634,8 @@ sddr09_read_status(struct us_data *us, unsigned char *status) {
if (result != USB_STOR_TRANSPORT_GOOD)
return result;
result = usb_storage_bulk_transport(us, SCSI_DATA_READ,
data, sizeof(data), 0);
result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
data, sizeof(data), NULL);
*status = data[0];
return (result == USB_STOR_XFER_GOOD ?
USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
......@@ -954,7 +957,8 @@ sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) {
if (result != USB_STOR_TRANSPORT_GOOD)
return result;
result = usb_storage_bulk_transport(us, SCSI_DATA_READ, content, 64, 0);
result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
content, 64, NULL);
for (i = 0; i < 4; i++)
deviceID[i] = content[i];
......@@ -1545,17 +1549,16 @@ int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us)
if (srb->sc_data_direction == SCSI_DATA_WRITE ||
srb->sc_data_direction == SCSI_DATA_READ) {
unsigned int pipe = (srb->sc_data_direction == SCSI_DATA_WRITE)
? us->send_bulk_pipe : us->recv_bulk_pipe;
US_DEBUGP("SDDR09: %s %d bytes\n",
(srb->sc_data_direction == SCSI_DATA_WRITE) ?
"sending" : "receiving",
srb->request_bufflen);
result = usb_storage_bulk_transport(us,
srb->sc_data_direction,
srb->request_buffer,
srb->request_bufflen,
srb->use_sg);
result = usb_stor_bulk_transfer_srb(us, pipe, srb,
srb->request_bufflen);
return (result == USB_STOR_XFER_GOOD ?
USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
......
......@@ -75,10 +75,13 @@ static int
sddr55_bulk_transport(struct us_data *us, int direction,
unsigned char *data, unsigned int len) {
struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;
unsigned int pipe = (direction == SCSI_DATA_READ) ?
us->recv_bulk_pipe : us->send_bulk_pipe;
if (len)
if (!len)
return USB_STOR_XFER_GOOD;
info->last_access = jiffies;
return usb_storage_bulk_transport(us, direction, data, len, 0);
return usb_stor_bulk_transfer_buf(us, pipe, data, len, NULL);
}
/* check if card inserted, if there is, update read_only status
......
This diff is collapsed.
......@@ -579,7 +579,7 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
/* was the entire command transferred? */
if (result < size) {
US_DEBUGP("-- transfer was short\n");
US_DEBUGP("-- transferred only %d bytes\n", result);
return USB_STOR_XFER_SHORT;
}
......@@ -614,7 +614,8 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
/* if we stall, we need to clear it before we go on */
if (result == -EPIPE) {
US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
US_DEBUGP("clearing endpoint halt for pipe 0x%x,"
" stalled at %d bytes\n", pipe, partial);
if (usb_stor_clear_halt(us, pipe) < 0)
return USB_STOR_XFER_ERROR;
return USB_STOR_XFER_STALLED;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment