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