Commit 490f5458 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/linus-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents e0c8dbaa eae28375
...@@ -9,16 +9,18 @@ mod-subdirs := serial ...@@ -9,16 +9,18 @@ mod-subdirs := serial
subdir-$(CONFIG_USB) += core subdir-$(CONFIG_USB) += core
subdir-$(CONFIG_USB_EHCI_HCD) += host subdir-$(CONFIG_USB_EHCI_HCD) += host
subdir-$(CONFIG_USB_OHCI_HCD) += host subdir-$(CONFIG_USB_OHCI_HCD) += host
subdir-$(CONFIG_USB_OHCI) += host subdir-$(CONFIG_USB_OHCI) += host
subdir-$(CONFIG_USB_UHCI_ALT) += host subdir-$(CONFIG_USB_UHCI_ALT) += host
subdir-$(CONFIG_USB_UHCI) += host subdir-$(CONFIG_USB_UHCI_HCD_ALT) += host
subdir-$(CONFIG_USB_UHCI_HCD) += host
subdir-$(CONFIG_USB_UHCI) += host
subdir-$(CONFIG_USB_ACM) += class subdir-$(CONFIG_USB_ACM) += class
subdir-$(CONFIG_USB_AUDIO) += class subdir-$(CONFIG_USB_AUDIO) += class
subdir-$(CONFIG_USB_BLUETOOTH_TTY) += class subdir-$(CONFIG_USB_BLUETOOTH_TTY) += class
subdir-$(CONFIG_USB_PRINTER) += class subdir-$(CONFIG_USB_PRINTER) += class
subdir-$(CONFIG_USB_STORAGE) += storage subdir-$(CONFIG_USB_STORAGE) += storage
......
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
static const char driver_name [] = "pegasus"; static const char driver_name[] = "pegasus";
#define PEGASUS_USE_INTR #define PEGASUS_USE_INTR
#define PEGASUS_WRITE_EEPROM #define PEGASUS_WRITE_EEPROM
......
...@@ -123,6 +123,7 @@ struct usb_eth_dev { ...@@ -123,6 +123,7 @@ struct usb_eth_dev {
#define VENDOR_ABOCOM 0x07b8 #define VENDOR_ABOCOM 0x07b8
#define VENDOR_ACCTON 0x083a #define VENDOR_ACCTON 0x083a
#define VENDOR_ADMTEK 0x07a6 #define VENDOR_ADMTEK 0x07a6
#define VENDOR_AEILAB 0x3334
#define VENDOR_ALLIEDTEL 0x07c9 #define VENDOR_ALLIEDTEL 0x07c9
#define VENDOR_BELKIN 0x050d #define VENDOR_BELKIN 0x050d
#define VENDOR_BILLIONTON 0x08dd #define VENDOR_BILLIONTON 0x08dd
...@@ -179,6 +180,8 @@ PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval. board)", ...@@ -179,6 +180,8 @@ PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval. board)",
DEFAULT_GPIO_RESET | HAS_HOME_PNA ) DEFAULT_GPIO_RESET | HAS_HOME_PNA )
PEGASUS_DEV( "AN986A USB MAC", VENDOR_ADMTEK, 1986, PEGASUS_DEV( "AN986A USB MAC", VENDOR_ADMTEK, 1986,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100, PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121,
......
...@@ -11,14 +11,14 @@ EXTRA_CFLAGS := -I../../scsi/ ...@@ -11,14 +11,14 @@ EXTRA_CFLAGS := -I../../scsi/
obj-$(CONFIG_USB_STORAGE) += usb-storage.o obj-$(CONFIG_USB_STORAGE) += usb-storage.o
usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o
usb-storage-obj-$(CONFIG_USB_STORAGE_HP8200e) += shuttle_usbat.o usb-storage-obj-$(CONFIG_USB_STORAGE_HP8200e) += shuttle_usbat.o raw_bulk.o
usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09) += sddr09.o usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09) += sddr09.o raw_bulk.o
usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR55) += sddr55.o usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR55) += sddr55.o raw_bulk.o
usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM) += freecom.o usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM) += freecom.o
usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o
usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o
usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o raw_bulk.o
usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o raw_bulk.o
usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
initializers.o $(usb-storage-obj-y) initializers.o $(usb-storage-obj-y)
......
This diff is collapsed.
This diff is collapsed.
/*
* Common routines for a handful of drivers.
* Unrelated to CF/SM - just USB stuff.
*
* This is mostly a thin layer on top of transport.c.
* It converts routines that return values like -ENOENT and -EPIPE
* into routines that return USB_STOR_TRANSPORT_ABORTED etc.
*
* There is also some debug printing here.
*/
#include "debug.h"
#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,
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);
// Check the return code for the command.
if (result < 0) {
/* if the command was aborted, indicate that */
if (result == -ENOENT)
return USB_STOR_TRANSPORT_ABORTED;
/* a stall is a fatal condition from the device */
if (result == -EPIPE) {
US_DEBUGP("-- Stall on control pipe. Clearing\n");
result = usb_stor_clear_halt(us, pipe);
US_DEBUGP("-- usb_stor_clear_halt() returns %d\n",
result);
return USB_STOR_TRANSPORT_FAILED;
}
/* 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;
int pipe;
if (direction == SCSI_DATA_READ)
pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
else
pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
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);
usb_stor_clear_halt(us, pipe);
/* return US_BULK_TRANSFER_SHORT; */
}
if (result) {
/* -ENOENT -- we canceled this transfer */
if (result == -ENOENT) {
US_DEBUGP("raw_bulk(): transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
}
/* 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 US_BULK_TRANSFER_FAILED;
}
if (*act_len != len) {
US_DEBUGP("Warning: Transferred only %d of %d bytes\n",
*act_len, len);
return US_BULK_TRANSFER_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 US_BULK_TRANSFER_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_TRANSPORT_GOOD;
int transferred = 0;
int i;
struct scatterlist *sg;
unsigned int act_len;
if (len == 0)
return USB_STOR_TRANSPORT_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 = page_address(sg[i].page) + sg[i].offset;
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 != US_BULK_TRANSFER_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.
* Nothing is done when use_sg is zero.
*/
/*
* Copy from scatter-gather buffer into a newly allocated single buffer,
* starting at a given index and offset.
* When done, update index and offset.
* Return a pointer to the single buffer.
*/
unsigned char *
us_copy_from_sgbuf(unsigned char *content, int len,
int *index, int *offset, int use_sg) {
struct scatterlist *sg;
unsigned char *buffer;
int transferred, i;
if (!use_sg)
return content;
sg = (struct scatterlist *)content;
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL)
return NULL;
transferred = 0;
i = *index;
while (i < use_sg && transferred < len) {
unsigned char *ptr;
unsigned int length, room;
ptr = page_address(sg[i].page) + sg[i].offset + *offset;
room = sg[i].length - *offset;
length = len - transferred;
if (length > room)
length = room;
memcpy(buffer+transferred, ptr, length);
transferred += length;
*offset += length;
if (length == room) {
i++;
*offset = 0;
}
}
*index = i;
return buffer;
}
unsigned char *
us_copy_from_sgbuf_all(unsigned char *content, int len, int use_sg) {
int index, offset;
index = offset = 0;
return us_copy_from_sgbuf(content, len, &index, &offset, use_sg);
}
/*
* Copy from a single buffer into a scatter-gather buffer,
* starting at a given index and offset.
* When done, update index and offset.
*/
void
us_copy_to_sgbuf(unsigned char *buffer, int buflen,
void *content, int *index, int *offset, int use_sg) {
struct scatterlist *sg;
int i, transferred;
if (!use_sg)
return;
transferred = 0;
sg = content;
i = *index;
while (i < use_sg && transferred < buflen) {
unsigned char *ptr;
unsigned int length, room;
ptr = page_address(sg[i].page) + sg[i].offset + *offset;
room = sg[i].length - *offset;
length = buflen - transferred;
if (length > room)
length = room;
memcpy(ptr, buffer+transferred, length);
transferred += sg[i].length;
*offset += length;
if (length == room) {
i++;
*offset = 0;
}
}
*index = i;
}
void
us_copy_to_sgbuf_all(unsigned char *buffer, int buflen,
void *content, int use_sg) {
int index, offset;
index = offset = 0;
us_copy_to_sgbuf(buffer, buflen, content, &index, &offset, use_sg);
}
#ifndef _USB_STORAGE_RAW_BULK_H_
#define _USB_STORAGE_RAW_BULK_H_
/* usb bulk */
extern int usb_storage_send_control(
struct us_data *us, 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,
int *index, int *offset, int use_sg);
extern unsigned char *us_copy_from_sgbuf_all(
unsigned char *content, int len, int use_sg);
extern void us_copy_to_sgbuf(
unsigned char *buffer, int buflen,
void *content, int *index, int *offset, int use_sg);
extern void us_copy_to_sgbuf_all(
unsigned char *buffer, int buflen,
void *content, int use_sg);
#endif
...@@ -255,7 +255,7 @@ static int bus_reset( Scsi_Cmnd *srb ) ...@@ -255,7 +255,7 @@ static int bus_reset( Scsi_Cmnd *srb )
/* FIXME: This needs to lock out driver probing while it's working /* FIXME: This needs to lock out driver probing while it's working
* or we can have race conditions */ * or we can have race conditions */
/* Is that still true? I don't see how... AS */ /* Is that still true? I don't see how... AS */
for (i = 0; i < pusb_dev_save->actconfig->bNumInterfaces; i++) { for (i = 0; i < pusb_dev_save->actconfig->bNumInterfaces; i++) {
struct usb_interface *intf = struct usb_interface *intf =
&pusb_dev_save->actconfig->interface[i]; &pusb_dev_save->actconfig->interface[i];
const struct usb_device_id *id; const struct usb_device_id *id;
...@@ -560,11 +560,11 @@ int usb_stor_scsiSense10to6( Scsi_Cmnd* the10 ) ...@@ -560,11 +560,11 @@ int usb_stor_scsiSense10to6( Scsi_Cmnd* the10 )
/* copy one byte */ /* copy one byte */
{ {
char *src = page_address(sg[sb].page) + sg[sb].offset + si; char *src = page_address(sg[sb].page) + sg[sb].offset + si;
char *dst = page_address(sg[db].page) + sg[db].offset + di; char *dst = page_address(sg[db].page) + sg[db].offset + di;
*dst = *src; *dst = *src;
} }
/* get next destination */ /* get next destination */
if ( sg[db].length-1 == di ) if ( sg[db].length-1 == di )
...@@ -753,11 +753,11 @@ int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 ) ...@@ -753,11 +753,11 @@ int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 )
/* copy one byte */ /* copy one byte */
{ {
char *src = page_address(sg[sb].page) + sg[sb].offset + si; char *src = page_address(sg[sb].page) + sg[sb].offset + si;
char *dst = page_address(sg[db].page) + sg[db].offset + di; char *dst = page_address(sg[db].page) + sg[db].offset + di;
*dst = *src; *dst = *src;
} }
/* get next destination */ /* get next destination */
if ( di == 0 ) if ( di == 0 )
...@@ -794,11 +794,11 @@ int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 ) ...@@ -794,11 +794,11 @@ int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 )
break; break;
} }
{ {
char *dst = page_address(sg[db].page) + sg[db].offset + di; char *dst = page_address(sg[db].page) + sg[db].offset + di;
*dst = tempBuffer[element-USB_STOR_SCSI_SENSE_HDRSZ]; *dst = tempBuffer[element-USB_STOR_SCSI_SENSE_HDRSZ];
} }
/* get next destination */ /* get next destination */
...@@ -852,14 +852,14 @@ void usb_stor_scsiSenseParseBuffer( Scsi_Cmnd* srb, Usb_Stor_Scsi_Sense_Hdr_u* t ...@@ -852,14 +852,14 @@ void usb_stor_scsiSenseParseBuffer( Scsi_Cmnd* srb, Usb_Stor_Scsi_Sense_Hdr_u* t
the6->array[element] = page_address(sg[i].page) + the6->array[element] = page_address(sg[i].page) +
sg[i].offset + j; sg[i].offset + j;
the10->array[element] = page_address(sg[i].page) + the10->array[element] = page_address(sg[i].page) +
sg[i].offset + j; sg[i].offset + j;
} }
else if ( element < USB_STOR_SCSI_SENSE_10_HDRSZ ) else if ( element < USB_STOR_SCSI_SENSE_10_HDRSZ )
{ {
/* only the longer headers still cares now */ /* only the longer headers still cares now */
the10->array[element] = page_address(sg[i].page) + the10->array[element] = page_address(sg[i].page) +
sg[i].offset + j; sg[i].offset + j;
} }
/* increase element counter */ /* increase element counter */
......
This diff is collapsed.
This diff is collapsed.
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
*/ */
#include "transport.h" #include "transport.h"
#include "raw_bulk.h"
#include "protocol.h" #include "protocol.h"
#include "usb.h" #include "usb.h"
#include "debug.h" #include "debug.h"
...@@ -61,174 +62,6 @@ extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe, ...@@ -61,174 +62,6 @@ extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
int transferred = 0; int transferred = 0;
/*
* 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.
*
*/
static int usbat_send_control(struct us_data *us,
int pipe,
unsigned char request,
unsigned char requesttype,
unsigned short value,
unsigned short 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);
// Check the return code for the command.
if (result < 0) {
/* if the command was aborted, indicate that */
if (result == -ENOENT)
return USB_STOR_TRANSPORT_ABORTED;
/* a stall is a fatal condition from the device */
if (result == -EPIPE) {
US_DEBUGP("-- Stall on control pipe. Clearing\n");
result = usb_stor_clear_halt(us, pipe);
US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result);
return USB_STOR_TRANSPORT_FAILED;
}
/* Uh oh... serious problem here */
return USB_STOR_TRANSPORT_ERROR;
}
return USB_STOR_TRANSPORT_GOOD;
}
static int usbat_raw_bulk(struct us_data *us,
int direction,
unsigned char *data,
unsigned short len) {
int result;
int act_len;
int pipe;
if (direction == SCSI_DATA_READ)
pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
else
pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
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);
usb_stor_clear_halt(us, pipe);
}
if (result) {
/* NAK - that means we've retried a few times already */
if (result == -ETIMEDOUT) {
US_DEBUGP("usbat_raw_bulk():"
" device NAKed\n");
return US_BULK_TRANSFER_FAILED;
}
/* -ENOENT -- we canceled this transfer */
if (result == -ENOENT) {
US_DEBUGP("usbat_raw_bulk():"
" transfer aborted\n");
return US_BULK_TRANSFER_ABORTED;
}
if (result == -EPIPE) {
US_DEBUGP("usbat_raw_bulk():"
" output pipe stalled\n");
return US_BULK_TRANSFER_SHORT;
}
/* the catch-all case */
US_DEBUGP("us_transfer_partial(): unknown error\n");
return US_BULK_TRANSFER_FAILED;
}
if (act_len != len) {
US_DEBUGP("Warning: Transferred only %d bytes\n",
act_len);
return US_BULK_TRANSFER_SHORT;
}
US_DEBUGP("Transferred %s %d of %d bytes\n",
direction==SCSI_DATA_READ ? "in" : "out", act_len, len);
return US_BULK_TRANSFER_GOOD;
}
/*
* Note: direction must be set if command_len == 0.
*/
static int usbat_bulk_transport(struct us_data *us,
unsigned char *command,
unsigned short command_len,
int direction,
unsigned char *data,
unsigned short len,
int use_sg) {
int result = USB_STOR_TRANSPORT_GOOD;
int transferred = 0;
int i;
struct scatterlist *sg;
if (len==0)
return USB_STOR_TRANSPORT_GOOD;
/* transfer the data payload for the command, if there is any */
if (command_len != 0)
direction = (command[0]&0x80) ? SCSI_DATA_READ :
SCSI_DATA_WRITE;
if (!use_sg)
result = usbat_raw_bulk(us, direction, data, len);
else {
sg = (struct scatterlist *)data;
for (i=0; i<use_sg && transferred<len; i++) {
result = usbat_raw_bulk(us, direction,
page_address(sg[i].page) + sg[i].offset,
len-transferred > sg[i].length ?
sg[i].length : len-transferred);
if (result!=US_BULK_TRANSFER_GOOD)
break;
transferred += sg[i].length;
}
}
return result;
}
int usbat_read(struct us_data *us, int usbat_read(struct us_data *us,
unsigned char access, unsigned char access,
unsigned char reg, unsigned char reg,
...@@ -236,7 +69,7 @@ int usbat_read(struct us_data *us, ...@@ -236,7 +69,7 @@ int usbat_read(struct us_data *us,
int result; int result;
result = usbat_send_control(us, result = usb_storage_send_control(us,
usb_rcvctrlpipe(us->pusb_dev,0), usb_rcvctrlpipe(us->pusb_dev,0),
access, access,
0xC0, 0xC0,
...@@ -255,7 +88,7 @@ int usbat_write(struct us_data *us, ...@@ -255,7 +88,7 @@ int usbat_write(struct us_data *us,
int result; int result;
result = usbat_send_control(us, result = usb_storage_send_control(us,
usb_sndctrlpipe(us->pusb_dev,0), usb_sndctrlpipe(us->pusb_dev,0),
access|0x01, access|0x01,
0x40, 0x40,
...@@ -281,7 +114,7 @@ int usbat_set_shuttle_features(struct us_data *us, ...@@ -281,7 +114,7 @@ int usbat_set_shuttle_features(struct us_data *us,
test_pattern, mask_byte, subcountL, subcountH test_pattern, mask_byte, subcountL, subcountH
}; };
result = usbat_send_control(us, result = usb_storage_send_control(us,
usb_sndctrlpipe(us->pusb_dev,0), usb_sndctrlpipe(us->pusb_dev,0),
0x80, 0x80,
0x40, 0x40,
...@@ -306,7 +139,7 @@ int usbat_read_block(struct us_data *us, ...@@ -306,7 +139,7 @@ int usbat_read_block(struct us_data *us,
LSB_of(len), MSB_of(len) LSB_of(len), MSB_of(len)
}; };
result = usbat_send_control(us, result = usb_storage_send_control(us,
usb_sndctrlpipe(us->pusb_dev,0), usb_sndctrlpipe(us->pusb_dev,0),
0x80, 0x80,
0x40, 0x40,
...@@ -318,8 +151,7 @@ int usbat_read_block(struct us_data *us, ...@@ -318,8 +151,7 @@ int usbat_read_block(struct us_data *us,
if (result != USB_STOR_TRANSPORT_GOOD) if (result != USB_STOR_TRANSPORT_GOOD)
return result; return result;
result = usbat_bulk_transport(us, result = usb_storage_bulk_transport(us, SCSI_DATA_READ, content, len, use_sg);
NULL, 0, SCSI_DATA_READ, content, len, use_sg);
return result; return result;
} }
...@@ -388,7 +220,7 @@ int usbat_write_block(struct us_data *us, ...@@ -388,7 +220,7 @@ int usbat_write_block(struct us_data *us,
LSB_of(len), MSB_of(len) LSB_of(len), MSB_of(len)
}; };
result = usbat_send_control(us, result = usb_storage_send_control(us,
usb_sndctrlpipe(us->pusb_dev,0), usb_sndctrlpipe(us->pusb_dev,0),
0x80, 0x80,
0x40, 0x40,
...@@ -400,8 +232,7 @@ int usbat_write_block(struct us_data *us, ...@@ -400,8 +232,7 @@ int usbat_write_block(struct us_data *us,
if (result != USB_STOR_TRANSPORT_GOOD) if (result != USB_STOR_TRANSPORT_GOOD)
return result; return result;
result = usbat_bulk_transport(us, result = usb_storage_bulk_transport(us, SCSI_DATA_WRITE, content, len, use_sg);
NULL, 0, SCSI_DATA_WRITE, content, len, use_sg);
if (result != USB_STOR_TRANSPORT_GOOD) if (result != USB_STOR_TRANSPORT_GOOD)
return result; return result;
...@@ -460,7 +291,7 @@ int usbat_rw_block_test(struct us_data *us, ...@@ -460,7 +291,7 @@ int usbat_rw_block_test(struct us_data *us,
* that, we just return a failure. * that, we just return a failure.
*/ */
result = usbat_send_control(us, result = usb_storage_send_control(us,
usb_sndctrlpipe(us->pusb_dev,0), usb_sndctrlpipe(us->pusb_dev,0),
0x80, 0x80,
0x40, 0x40,
...@@ -474,8 +305,8 @@ int usbat_rw_block_test(struct us_data *us, ...@@ -474,8 +305,8 @@ int usbat_rw_block_test(struct us_data *us,
if (i==0) { if (i==0) {
result = usbat_bulk_transport(us, result = usb_storage_bulk_transport(us,
NULL, 0, SCSI_DATA_WRITE, SCSI_DATA_WRITE,
data, num_registers*2, 0); data, num_registers*2, 0);
if (result!=USB_STOR_TRANSPORT_GOOD) if (result!=USB_STOR_TRANSPORT_GOOD)
...@@ -488,8 +319,8 @@ int usbat_rw_block_test(struct us_data *us, ...@@ -488,8 +319,8 @@ int usbat_rw_block_test(struct us_data *us,
// direction == SCSI_DATA_WRITE ? "out" : "in", // direction == SCSI_DATA_WRITE ? "out" : "in",
// len, use_sg); // len, use_sg);
result = usbat_bulk_transport(us, result = usb_storage_bulk_transport(us,
NULL, 0, direction, content, len, use_sg); direction, content, len, use_sg);
/* /*
* If we get a stall on the bulk download, we'll retry * If we get a stall on the bulk download, we'll retry
...@@ -576,7 +407,7 @@ int usbat_multiple_write(struct us_data *us, ...@@ -576,7 +407,7 @@ int usbat_multiple_write(struct us_data *us,
data[1+(i<<1)] = data_out[i]; data[1+(i<<1)] = data_out[i];
} }
result = usbat_send_control(us, result = usb_storage_send_control(us,
usb_sndctrlpipe(us->pusb_dev,0), usb_sndctrlpipe(us->pusb_dev,0),
0x80, 0x80,
0x40, 0x40,
...@@ -588,10 +419,10 @@ int usbat_multiple_write(struct us_data *us, ...@@ -588,10 +419,10 @@ int usbat_multiple_write(struct us_data *us,
if (result != USB_STOR_TRANSPORT_GOOD) if (result != USB_STOR_TRANSPORT_GOOD)
return result; return result;
result = usbat_bulk_transport(us, result = usb_storage_bulk_transport(us,
NULL, 0, SCSI_DATA_WRITE, data, num_registers*2, 0); SCSI_DATA_WRITE, data, num_registers*2, 0);
if (result!=USB_STOR_TRANSPORT_GOOD) if (result != USB_STOR_TRANSPORT_GOOD)
return result; return result;
return usbat_wait_not_busy(us, 0); return usbat_wait_not_busy(us, 0);
...@@ -602,7 +433,7 @@ int usbat_read_user_io(struct us_data *us, ...@@ -602,7 +433,7 @@ int usbat_read_user_io(struct us_data *us,
int result; int result;
result = usbat_send_control(us, result = usb_storage_send_control(us,
usb_rcvctrlpipe(us->pusb_dev,0), usb_rcvctrlpipe(us->pusb_dev,0),
0x82, 0x82,
0xC0, 0xC0,
...@@ -620,7 +451,7 @@ int usbat_write_user_io(struct us_data *us, ...@@ -620,7 +451,7 @@ int usbat_write_user_io(struct us_data *us,
int result; int result;
result = usbat_send_control(us, result = usb_storage_send_control(us,
usb_sndctrlpipe(us->pusb_dev,0), usb_sndctrlpipe(us->pusb_dev,0),
0x82, 0x82,
0x40, 0x40,
...@@ -646,7 +477,6 @@ int usbat_handle_read10(struct us_data *us, ...@@ -646,7 +477,6 @@ int usbat_handle_read10(struct us_data *us,
unsigned char *buffer; unsigned char *buffer;
unsigned int len; unsigned int len;
unsigned int sector; unsigned int sector;
unsigned int amount;
struct scatterlist *sg = NULL; struct scatterlist *sg = NULL;
int sg_segment = 0; int sg_segment = 0;
int sg_offset = 0; int sg_offset = 0;
...@@ -735,31 +565,11 @@ int usbat_handle_read10(struct us_data *us, ...@@ -735,31 +565,11 @@ int usbat_handle_read10(struct us_data *us,
// Transfer the received data into the srb buffer // Transfer the received data into the srb buffer
if (!srb->use_sg) { if (srb->use_sg)
us_copy_to_sgbuf(buffer, len, sg,
&sg_segment, &sg_offset, srb->use_sg);
else
memcpy(srb->request_buffer+transferred, buffer, len); memcpy(srb->request_buffer+transferred, buffer, len);
} else {
amount = 0;
while (amount<len) {
if (len - amount >=
sg[sg_segment].length-sg_offset) {
memcpy(page_address(sg[sg_segment].page) +
sg[sg_segment].offset + sg_offset,
buffer + amount,
sg[sg_segment].length - sg_offset);
amount +=
sg[sg_segment].length-sg_offset;
sg_segment++;
sg_offset=0;
} else {
memcpy(page_address(sg[sg_segment].page) +
sg[sg_segment].offset + sg_offset,
buffer + amount,
len - amount);
sg_offset += (len - amount);
amount = len;
}
}
}
// Update the amount transferred and the sector number // Update the amount transferred and the sector number
......
...@@ -151,10 +151,13 @@ extern unsigned int usb_stor_transfer_length(Scsi_Cmnd*); ...@@ -151,10 +151,13 @@ extern unsigned int usb_stor_transfer_length(Scsi_Cmnd*);
extern void usb_stor_invoke_transport(Scsi_Cmnd*, struct us_data*); extern void usb_stor_invoke_transport(Scsi_Cmnd*, struct us_data*);
extern void usb_stor_abort_transport(struct us_data*); extern void usb_stor_abort_transport(struct us_data*);
extern int usb_stor_transfer_partial(struct us_data*, char*, int); extern int usb_stor_transfer_partial(struct us_data*, char*, int);
extern int usb_stor_bulk_msg(struct us_data*, void*, int, unsigned int,
unsigned int*); extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
extern int usb_stor_control_msg(struct us_data*, unsigned int, u8, u8, unsigned int len, unsigned int *act_len);
u16, u16, void*, u16); extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
u8 request, u8 requesttype, u16 value, u16 index,
void *data, u16 size);
extern int usb_stor_clear_halt(struct us_data*, int ); extern int usb_stor_clear_halt(struct us_data*, int );
extern void usb_stor_transfer(Scsi_Cmnd*, struct us_data*); extern void usb_stor_transfer(Scsi_Cmnd*, struct us_data*);
#endif #endif
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