Commit e8825268 authored by Linus Torvalds's avatar Linus Torvalds

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

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 9de88958 34bc27e5
......@@ -109,7 +109,8 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b
interface->num_altsetting = 0;
interface->max_altsetting = USB_ALTSETTINGALLOC;
interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);
interface->altsetting = kmalloc(sizeof(*interface->altsetting) * interface->max_altsetting,
GFP_KERNEL);
if (!interface->altsetting) {
err("couldn't kmalloc interface->altsetting");
......@@ -118,29 +119,27 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b
while (size > 0) {
struct usb_interface_descriptor *d;
if (interface->num_altsetting >= interface->max_altsetting) {
void *ptr;
struct usb_host_interface *ptr;
int oldmas;
oldmas = interface->max_altsetting;
interface->max_altsetting += USB_ALTSETTINGALLOC;
if (interface->max_altsetting > USB_MAXALTSETTING) {
warn("too many alternate settings (max %d)",
USB_MAXALTSETTING);
warn("too many alternate settings (incr %d max %d)\n",
USB_ALTSETTINGALLOC, USB_MAXALTSETTING);
return -1;
}
ptr = interface->altsetting;
interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);
if (!interface->altsetting) {
ptr = kmalloc(sizeof(*ptr) * interface->max_altsetting, GFP_KERNEL);
if (ptr == NULL) {
err("couldn't kmalloc interface->altsetting");
interface->altsetting = ptr;
return -1;
}
memcpy(interface->altsetting, ptr, sizeof(struct usb_interface_descriptor) * oldmas);
kfree(ptr);
memcpy(ptr, interface->altsetting, sizeof(*interface->altsetting) * oldmas);
kfree(interface->altsetting);
interface->altsetting = ptr;
}
ifp = interface->altsetting + interface->num_altsetting;
......
This diff is collapsed.
This diff is collapsed.
......@@ -85,6 +85,7 @@ typedef struct pegasus {
struct usb_device *usb;
struct net_device *net;
struct net_device_stats stats;
struct mii_if_info mii;
unsigned flags;
unsigned features;
int dev_index;
......@@ -97,6 +98,7 @@ typedef struct pegasus {
wait_queue_head_t ctrl_wait;
struct semaphore sem;
spinlock_t rx_pool_lock;
int chip;
unsigned char intr_buff[8];
__u8 tx_buff[PEGASUS_MTU];
__u8 eth_regs[4];
......@@ -131,11 +133,11 @@ struct usb_eth_dev {
#define VENDOR_LANEED 0x056e
#define VENDOR_LINKSYS 0x066b
#define VENDOR_MELCO 0x0411
#define VENDOR_NETGEAR 0x0846
#define VENDOR_SMARTBRIDGES 0x08d1
#define VENDOR_SMC 0x0707
#define VENDOR_SOHOWARE 0x15e8
#define VENDOR_SIEMENS 0x067c
#define VENDOR_JTEC 0x11ad
#else /* PEGASUS_DEV */
......@@ -169,7 +171,10 @@ PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
VENDOR_ADMTEK, 0x8511,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval. board)",
PEGASUS_DEV( "ADMtek ADM8513 \"Pegasus II\" USB Ethernet",
VENDOR_ADMTEK, 0x8513,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (evaluation board)",
VENDOR_ADMTEK, 0x0986,
DEFAULT_GPIO_RESET | HAS_HOME_PNA )
PEGASUS_DEV( "AN986A USB MAC", VENDOR_ADMTEK, 1986,
......@@ -192,7 +197,7 @@ PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "Corega FEter", VENDOR_COREGA, 0x000d,
PEGASUS_DEV( "Corega FEter USB-TXS", VENDOR_COREGA, 0x000d,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001,
LINKSYS_GPIO_RESET )
......@@ -246,6 +251,8 @@ PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "NETGEAR FA101", VENDOR_NETGEAR, 0x1020,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
......@@ -258,8 +265,6 @@ PEGASUS_DEV( "SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "FA8101 USB To ETHERNET", VENDOR_JTEC, 0x8101,
DEFAULT_GPIO_RESET | PEGASUS_II )
#endif /* PEGASUS_DEV */
......@@ -14,6 +14,10 @@
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
* (11/19/2002) gkh
* removed a few #ifdefs for the generic code and cleaned up the failure
* logic in initialization.
*
* (10/02/2002) gkh
* moved the console code to console.c and out of this file.
*
......@@ -341,7 +345,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v1.6"
#define DRIVER_VERSION "v1.7"
#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
#define DRIVER_DESC "USB Serial Driver core"
......@@ -382,7 +386,29 @@ static struct usb_device_id generic_serial_ids[] = {
{.driver_info = 42},
{}
};
#endif
static int generic_register (void)
{
generic_device_ids[0].idVendor = vendor;
generic_device_ids[0].idProduct = product;
generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
/* register our generic driver with ourselves */
return usb_serial_register (&generic_device);
}
static void generic_deregister (void)
{
/* remove our generic driver */
usb_serial_deregister (&generic_device);
}
#else
static inline int generic_register (void) { return 0; }
static inline void generic_deregister (void) { }
#endif /* CONFIG_USB_SERIAL_GENERIC */
/* Driver structure we register with the USB core */
static struct usb_driver usb_serial_driver = {
......@@ -409,7 +435,6 @@ static struct termios * serial_termios_locked[SERIAL_TTY_MINORS];
static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
static LIST_HEAD(usb_serial_driver_list);
struct usb_serial *usb_serial_get_by_minor (unsigned int minor)
{
return serial_table[minor];
......@@ -839,7 +864,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
length += sprintf (page+length, "%d:", i);
if (serial->type->owner)
length += sprintf (page+length, " module:%s", serial->type->owner->name);
length += sprintf (page+length, " module:%s", module_name(serial->type->owner));
length += sprintf (page+length, " name:\"%s\"", serial->type->name);
length += sprintf (page+length, " vendor:%04x product:%04x", serial->vendor, serial->product);
length += sprintf (page+length, " num_ports:%d", serial->num_ports);
......@@ -1574,40 +1599,49 @@ static struct tty_driver serial_tty_driver = {
static int __init usb_serial_init(void)
{
int i;
int result;
int result = 0;
/* Initalize our global data */
for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
serial_table[i] = NULL;
}
/* register the generic driver, if we should */
result = generic_register();
if (result < 0) {
err("%s - registering generic driver failed", __FUNCTION__);
goto exit;
}
/* register the tty driver */
serial_tty_driver.init_termios = tty_std_termios;
serial_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
if (tty_register_driver (&serial_tty_driver)) {
err("%s - failed to register tty driver", __FUNCTION__);
return -1;
result = tty_register_driver (&serial_tty_driver);
if (result) {
err("%s - tty_register_driver failed", __FUNCTION__);
goto exit_generic;
}
/* register the USB driver */
result = usb_register(&usb_serial_driver);
if (result < 0) {
tty_unregister_driver(&serial_tty_driver);
err("usb_register failed for the usb-serial driver. Error number %d", result);
return -1;
err("%s - usb_register failed", __FUNCTION__);
goto exit_tty;
}
#ifdef CONFIG_USB_SERIAL_GENERIC
generic_device_ids[0].idVendor = vendor;
generic_device_ids[0].idProduct = product;
generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
/* register our generic driver with ourselves */
usb_serial_register (&generic_device);
#endif
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
return result;
exit_tty:
tty_unregister_driver(&serial_tty_driver);
exit_generic:
generic_deregister();
exit:
err ("%s - returning with error %d", __FUNCTION__, result);
return result;
}
......@@ -1615,11 +1649,8 @@ static void __exit usb_serial_exit(void)
{
usb_serial_console_exit();
#ifdef CONFIG_USB_SERIAL_GENERIC
/* remove our generic driver */
usb_serial_deregister (&generic_device);
#endif
generic_deregister();
usb_deregister(&usb_serial_driver);
tty_unregister_driver(&serial_tty_driver);
}
......
......@@ -115,7 +115,7 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
freecom_udata_t extra = (freecom_udata_t) us->extra;
struct freecom_xfer_wrap *fxfr =
(struct freecom_xfer_wrap *) extra->buffer;
int result, partial;
int result;
fxfr->Type = FCM_PACKET_INPUT | 0x00;
fxfr->Timeout = 0; /* Short timeout for debugging. */
......@@ -125,14 +125,12 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
US_DEBUGP("Read data Freecom! (c=%d)\n", count);
/* Issue the transfer command. */
result = usb_stor_bulk_msg (us, fxfr, opipe,
FCM_PACKET_LENGTH, &partial);
result = usb_stor_bulk_transfer_buf (us, opipe, fxfr,
FCM_PACKET_LENGTH, NULL);
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP ("Freecom readdata xport failure: r=%d, p=%d\n",
result, partial);
US_DEBUGP ("Freecom readdata transport error\n");
return USB_STOR_TRANSPORT_ERROR;
}
US_DEBUGP("Done issuing read request: %d %d\n", result, partial);
/* Now transfer all of our blocks. */
US_DEBUGP("Start of read\n");
......@@ -151,7 +149,7 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
freecom_udata_t extra = (freecom_udata_t) us->extra;
struct freecom_xfer_wrap *fxfr =
(struct freecom_xfer_wrap *) extra->buffer;
int result, partial;
int result;
fxfr->Type = FCM_PACKET_OUTPUT | 0x00;
fxfr->Timeout = 0; /* Short timeout for debugging. */
......@@ -161,15 +159,12 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
US_DEBUGP("Write data Freecom! (c=%d)\n", count);
/* Issue the transfer command. */
result = usb_stor_bulk_msg (us, fxfr, opipe,
FCM_PACKET_LENGTH, &partial);
result = usb_stor_bulk_transfer_buf (us, opipe, fxfr,
FCM_PACKET_LENGTH, NULL);
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP ("Freecom writedata xport failure: r=%d, p=%d\n",
result, partial);
US_DEBUGP ("Freecom writedata transport error\n");
return USB_STOR_TRANSPORT_ERROR;
}
US_DEBUGP("Done issuing write request: %d %d\n",
result, partial);
/* Now transfer all of our blocks. */
US_DEBUGP("Start of write\n");
......@@ -191,7 +186,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
struct freecom_status *fst;
unsigned int ipipe, opipe; /* We need both pipes. */
int result;
int partial;
unsigned int partial;
int length;
freecom_udata_t extra;
......@@ -215,23 +210,22 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUG(pdump (srb->cmnd, 12));
/* Send it out. */
result = usb_stor_bulk_msg (us, fcb, opipe,
FCM_PACKET_LENGTH, &partial);
result = usb_stor_bulk_transfer_buf (us, opipe, fcb,
FCM_PACKET_LENGTH, NULL);
/* The Freecom device will only fail if there is something wrong in
* USB land. It returns the status in its own registers, which
* come back in the bulk pipe. */
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP ("freecom xport failure: r=%d, p=%d\n",
result, partial);
US_DEBUGP ("freecom transport error\n");
return USB_STOR_TRANSPORT_ERROR;
}
/* There are times we can optimize out this status read, but it
* doesn't hurt us to always do it now. */
result = usb_stor_bulk_msg (us, fst, ipipe,
result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
FCM_PACKET_LENGTH, &partial);
US_DEBUGP("foo Status result %d %d\n", result, partial);
US_DEBUGP("foo Status result %d %u\n", result, partial);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
......@@ -256,24 +250,23 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
memset (fcb->Filler, 0, sizeof (fcb->Filler));
/* Send it out. */
result = usb_stor_bulk_msg (us, fcb, opipe,
FCM_PACKET_LENGTH, &partial);
result = usb_stor_bulk_transfer_buf (us, opipe, fcb,
FCM_PACKET_LENGTH, NULL);
/* The Freecom device will only fail if there is something
* wrong in USB land. It returns the status in its own
* registers, which come back in the bulk pipe.
*/
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP ("freecom xport failure: r=%d, p=%d\n",
result, partial);
US_DEBUGP ("freecom transport error\n");
return USB_STOR_TRANSPORT_ERROR;
}
/* get the data */
result = usb_stor_bulk_msg (us, fst, ipipe,
result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
FCM_PACKET_LENGTH, &partial);
US_DEBUGP("bar Status result %d %d\n", result, partial);
US_DEBUGP("bar Status result %d %u\n", result, partial);
if (result > USB_STOR_XFER_SHORT)
return USB_STOR_TRANSPORT_ERROR;
......@@ -328,7 +321,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
return result;
US_DEBUGP("FCM: Waiting for status\n");
result = usb_stor_bulk_msg (us, fst, ipipe,
result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
FCM_PACKET_LENGTH, &partial);
US_DEBUG(pdump ((void *) fst, partial));
......@@ -354,7 +347,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
return result;
US_DEBUGP("FCM: Waiting for status\n");
result = usb_stor_bulk_msg (us, fst, ipipe,
result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
FCM_PACKET_LENGTH, &partial);
if (partial != 4 || result > USB_STOR_XFER_SHORT)
......@@ -385,13 +378,6 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
}
return USB_STOR_TRANSPORT_GOOD;
US_DEBUGP("Freecom: transfer_length = %d\n",
usb_stor_transfer_length (srb));
US_DEBUGP("Freecom: direction = %d\n", srb->sc_data_direction);
return USB_STOR_TRANSPORT_ERROR;
}
int
......
......@@ -668,7 +668,7 @@ int isd200_write_config( struct us_data *us )
#endif
/* let's send the command via the control pipe */
result = usb_stor_control_msg(
result = usb_stor_ctrl_transfer(
us,
us->send_ctrl_pipe,
0x01,
......@@ -709,7 +709,7 @@ int isd200_read_config( struct us_data *us )
/* read the configuration information from ISD200. Use this to */
/* determine what the special ATA CDB bytes are. */
result = usb_stor_control_msg(
result = usb_stor_ctrl_transfer(
us,
us->recv_ctrl_pipe,
0x02,
......
......@@ -479,7 +479,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
usb_stor_blocking_completion, NULL);
status = usb_stor_msg_common(us);
/* return the actual length of the data transferred if no error*/
/* return the actual length of the data transferred if no error */
if (status >= 0)
status = us->current_urb->actual_length;
return status;
......@@ -543,47 +543,91 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
return 0;
}
/*
* Transfer one control message
* Interpret the results of a URB transfer
*
* This function does basically the same thing as usb_stor_control_msg()
* above, except that return codes are USB_STOR_XFER_xxx rather than the
* urb status or transfer length.
* This function prints appropriate debugging messages, clears halts on
* bulk endpoints, and translates the status to the corresponding
* USB_STOR_XFER_xxx return code.
*/
int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
u8 request, u8 requesttype, u16 value, u16 index,
void *data, u16 size) {
int result;
static int interpret_urb_result(struct us_data *us, unsigned int pipe,
unsigned int length, int result, unsigned int partial) {
US_DEBUGP("usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x "
"value=%04x index=%02x len=%d\n",
request, requesttype, value, index, size);
result = usb_stor_control_msg(us, pipe, request, requesttype,
value, index, data, size);
US_DEBUGP("usb_stor_control_msg returned %d\n", result);
US_DEBUGP("Status code %d; transferred %u/%u\n",
result, partial, length);
/* a stall indicates a protocol error */
/* stalled */
if (result == -EPIPE) {
US_DEBUGP("-- stall on control pipe\n");
/* for non-bulk (i.e., control) endpoints, a stall indicates
* a protocol error */
if (!usb_pipebulk(pipe)) {
US_DEBUGP("-- stall on control pipe\n");
return USB_STOR_XFER_ERROR;
}
/* for a bulk endpoint, clear the stall */
US_DEBUGP("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;
}
/* NAK - that means we've retried this a few times already */
if (result == -ETIMEDOUT) {
US_DEBUGP("-- device NAKed\n");
return USB_STOR_XFER_ERROR;
}
/* the transfer was cancelled, presumably by an abort */
if (result == -ENODEV) {
US_DEBUGP("-- transfer cancelled\n");
return USB_STOR_XFER_ERROR;
}
/* some other serious problem here */
/* the catch-all error case */
if (result < 0) {
US_DEBUGP("-- unknown error\n");
return USB_STOR_XFER_ERROR;
}
/* was the entire command transferred? */
if (result < size) {
US_DEBUGP("-- transferred only %d bytes\n", result);
/* no error code; did we send all the data? */
if (partial != length) {
US_DEBUGP("-- transferred only %u bytes\n", partial);
return USB_STOR_XFER_SHORT;
}
US_DEBUGP("-- transfer completed successfully\n");
US_DEBUGP("-- transfer complete\n");
return USB_STOR_XFER_GOOD;
}
/*
* Transfer one control message
*
* This function does basically the same thing as usb_stor_control_msg()
* above, except that return codes are USB_STOR_XFER_xxx rather than the
* urb status or transfer length.
*/
int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
u8 request, u8 requesttype, u16 value, u16 index,
void *data, u16 size) {
int result;
unsigned int partial = 0;
US_DEBUGP("usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x "
"value=%04x index=%02x len=%u\n",
request, requesttype, value, index, size);
result = usb_stor_control_msg(us, pipe, request, requesttype,
value, index, data, size);
if (result > 0) { /* Separate out the amount transferred */
partial = result;
result = 0;
}
return interpret_urb_result(us, pipe, size, result, partial);
}
/*
* Transfer one buffer via bulk transfer
*
......@@ -596,50 +640,17 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
* urb status or transfer length.
*/
int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
char *buf, unsigned int length, unsigned int *act_len)
void *buf, unsigned int length, unsigned int *act_len)
{
int result;
int partial;
unsigned int partial;
/* transfer the data */
US_DEBUGP("usb_stor_bulk_transfer_buf(): xfer %d bytes\n", length);
US_DEBUGP("usb_stor_bulk_transfer_buf(): xfer %u bytes\n", length);
result = usb_stor_bulk_msg(us, buf, pipe, length, &partial);
US_DEBUGP("usb_stor_bulk_msg() returned %d xferred %d/%d\n",
result, partial, length);
if (act_len)
*act_len = partial;
/* if we stall, we need to clear it before we go on */
if (result == -EPIPE) {
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;
}
/* NAK - that means we've retried a few times already */
if (result == -ETIMEDOUT) {
US_DEBUGP("-- device NAKed\n");
return USB_STOR_XFER_ERROR;
}
/* the catch-all error case */
if (result) {
US_DEBUGP("-- unknown error\n");
return USB_STOR_XFER_ERROR;
}
/* did we send all the data? */
if (partial == length) {
US_DEBUGP("-- transfer complete\n");
return USB_STOR_XFER_GOOD;
}
/* no error code, so we must have transferred some data,
* just not all of it */
US_DEBUGP("-- transferred only %d bytes\n", partial);
return USB_STOR_XFER_SHORT;
return interpret_urb_result(us, pipe, length, result, partial);
}
/*
......@@ -653,10 +664,10 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
unsigned int *act_len)
{
int result;
int partial;
unsigned int partial;
/* initialize the scatter-gather request block */
US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %d bytes, "
US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %u bytes, "
"%d entries\n", length, num_sg);
result = usb_sg_init(us->current_sg, us->pusb_dev, pipe, 0,
sg, num_sg, length, SLAB_NOIO);
......@@ -685,55 +696,22 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
result = us->current_sg->status;
partial = us->current_sg->bytes;
US_DEBUGP("usb_sg_wait() returned %d xferred %d/%d\n",
result, partial, length);
if (act_len)
*act_len = partial;
/* if we stall, we need to clear it before we go on */
if (result == -EPIPE) {
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;
}
/* NAK - that means we've retried this a few times already */
if (result == -ETIMEDOUT) {
US_DEBUGP("-- device NAKed\n");
return USB_STOR_XFER_ERROR;
}
/* the catch-all error case */
if (result) {
US_DEBUGP("-- unknown error\n");
return USB_STOR_XFER_ERROR;
}
/* did we send all the data? */
if (partial == length) {
US_DEBUGP("-- transfer complete\n");
return USB_STOR_XFER_GOOD;
}
/* no error code, so we must have transferred some data,
* just not all of it */
US_DEBUGP("-- transferred only %d bytes\n", partial);
return USB_STOR_XFER_SHORT;
return interpret_urb_result(us, pipe, length, result, partial);
}
/*
* Transfer an entire SCSI command's worth of data payload over the bulk
* pipe.
*
* Nore that this uses usb_stor_bulk_transfer_buf() and
* Note that this uses usb_stor_bulk_transfer_buf() and
* usb_stor_bulk_transfer_sglist() to achieve its goals --
* this function simply determines whether we're going to use
* scatter-gather or not, and acts appropriately.
*/
int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe,
char *buf, unsigned int length_left, int use_sg, int *residual)
void *buf, unsigned int length_left, int use_sg, int *residual)
{
int result;
unsigned int partial;
......@@ -1278,7 +1256,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
(bcb.Lun >> 4), (bcb.Lun & 0x0F),
le32_to_cpu(bcb.DataTransferLength), bcb.Flags, bcb.Length);
result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
(char *) &bcb, US_BULK_CB_WRAP_LEN, NULL);
&bcb, US_BULK_CB_WRAP_LEN, NULL);
US_DEBUGP("Bulk command transfer result=%d\n", result);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
......@@ -1302,7 +1280,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* get CSW for device status */
US_DEBUGP("Attempting to get CSW...\n");
result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
(char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
&bcs, US_BULK_CS_WRAP_LEN, NULL);
/* did the attempt to read the CSW fail? */
if (result == USB_STOR_XFER_STALLED) {
......@@ -1310,7 +1288,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* get the status again */
US_DEBUGP("Attempting to get CSW (2nd try)...\n");
result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
(char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
&bcs, US_BULK_CS_WRAP_LEN, NULL);
}
/* if we still have a failure at this point, we're in trouble */
......
......@@ -117,6 +117,7 @@ struct bulk_cs_wrap {
/*
* usb_stor_bulk_transfer_xxx() return codes, in order of severity
*/
#define USB_STOR_XFER_GOOD 0 /* good transfer */
#define USB_STOR_XFER_SHORT 1 /* transfered less than expected */
#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
......@@ -129,7 +130,14 @@ struct bulk_cs_wrap {
#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */
#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */
#define USB_STOR_TRANSPORT_ERROR 2 /* Transport bad (i.e. device dead) */
#define USB_STOR_TRANSPORT_ABORTED 3 /* Transport aborted */
/*
* We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED
* return codes. But now the transport and low-level transfer routines
* treat an abort as just another error (-ENOENT for a cancelled URB).
* It is up to the invoke_transport() function to test for aborts and
* distinguish them from genuine communication errors.
*/
/*
* CBI accept device specific command
......@@ -162,12 +170,12 @@ extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
u8 request, u8 requesttype, u16 value, u16 index,
void *data, u16 size);
extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
char *buf, unsigned int length, unsigned int *act_len);
void *buf, unsigned int length, unsigned int *act_len);
extern 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);
extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
char *buf, unsigned int length, int use_sg, int *residual);
void *buf, unsigned int length, int use_sg, int *residual);
static __inline__ int usb_stor_bulk_transfer_srb(struct us_data *us,
unsigned int pipe, Scsi_Cmnd *srb, unsigned int length) {
......
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