Commit e1f015ee authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.5

into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents 201be7ab b75f41cf
...@@ -578,7 +578,9 @@ static int proc_control(struct dev_state *ps, void *arg) ...@@ -578,7 +578,9 @@ static int proc_control(struct dev_state *ps, void *arg)
} }
free_page((unsigned long)tbuf); free_page((unsigned long)tbuf);
if (i<0) { if (i<0) {
printk(KERN_DEBUG "usbfs: USBDEVFS_CONTROL failed dev %d rqt %u rq %u len %u ret %d\n", printk(KERN_DEBUG "usbfs: USBDEVFS_CONTROL failed "
"cmd %s dev %d rqt %u rq %u len %u ret %d\n",
current->comm,
dev->devnum, ctrl.bRequestType, ctrl.bRequest, ctrl.wLength, i); dev->devnum, ctrl.bRequestType, ctrl.bRequest, ctrl.wLength, i);
} }
return i; return i;
......
This diff is collapsed.
...@@ -174,7 +174,12 @@ struct usb_hub { ...@@ -174,7 +174,12 @@ struct usb_hub {
struct urb *urb; /* for interrupt polling pipe */ struct urb *urb; /* for interrupt polling pipe */
/* buffer for urb ... 1 bit each for hub and children, rounded up */ /* buffer for urb ... 1 bit each for hub and children, rounded up */
char buffer[(USB_MAXCHILDREN + 1 + 7) / 8]; char (*buffer)[(USB_MAXCHILDREN + 1 + 7) / 8];
dma_addr_t buffer_dma; /* DMA address for buffer */
union {
struct usb_hub_status hub;
struct usb_port_status port;
} *status; /* buffer for status reports */
int error; /* last reported error */ int error; /* last reported error */
int nerrors; /* track consecutive errors */ int nerrors; /* track consecutive errors */
......
...@@ -20,10 +20,12 @@ ...@@ -20,10 +20,12 @@
* short OUT transfers happen.) Drivers can use the req->no_interrupt * short OUT transfers happen.) Drivers can use the req->no_interrupt
* hint to completely eliminate some IRQs, if a later IRQ is guaranteed * hint to completely eliminate some IRQs, if a later IRQ is guaranteed
* and DMA chaining is enabled. * and DMA chaining is enabled.
*
* Note that almost all the errata workarounds here are only needed for
* rev1 chips. Rev1a silicon (0110) fixes almost all of them.
*/ */
// #define NET2280_DMA_OUT_WORKAROUND #define USE_DMA_CHAINING
// #define USE_DMA_CHAINING
/* /*
...@@ -180,6 +182,13 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) ...@@ -180,6 +182,13 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
* kicking in the "toggle-irrelevant" mode. * kicking in the "toggle-irrelevant" mode.
*/ */
tmp = USB_ENDPOINT_XFER_BULK; tmp = USB_ENDPOINT_XFER_BULK;
} else if (tmp == USB_ENDPOINT_XFER_BULK) {
/* catch some particularly blatant driver bugs */
if ((dev->gadget.speed == USB_SPEED_HIGH
&& max != 512)
|| (dev->gadget.speed == USB_SPEED_FULL
&& max > 64))
return -ERANGE;
} }
ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0; ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0;
tmp <<= ENDPOINT_TYPE; tmp <<= ENDPOINT_TYPE;
...@@ -252,9 +261,6 @@ static int handshake (u32 *ptr, u32 mask, u32 done, int usec) ...@@ -252,9 +261,6 @@ static int handshake (u32 *ptr, u32 mask, u32 done, int usec)
udelay (1); udelay (1);
usec--; usec--;
} while (usec > 0); } while (usec > 0);
#ifdef DEBUG
if (done == 0) dump_stack (); /* ignore out_flush timeout */
#endif
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -917,6 +923,8 @@ net2280_queue (struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) ...@@ -917,6 +923,8 @@ net2280_queue (struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
*/ */
if (read_fifo (ep, req)) { if (read_fifo (ep, req)) {
done (ep, req, 0); done (ep, req, 0);
if (ep->num == 0)
allow_status (ep);
/* don't queue it */ /* don't queue it */
req = 0; req = 0;
} else } else
...@@ -1194,9 +1202,12 @@ net2280_set_halt (struct usb_ep *_ep, int value) ...@@ -1194,9 +1202,12 @@ net2280_set_halt (struct usb_ep *_ep, int value)
VDEBUG (ep->dev, "%s %s halt\n", _ep->name, value ? "set" : "clear"); VDEBUG (ep->dev, "%s %s halt\n", _ep->name, value ? "set" : "clear");
/* set/clear, then synch memory views with the device */ /* set/clear, then synch memory views with the device */
if (value) if (value) {
set_halt (ep); if (ep->num == 0)
else ep->dev->protocol_stall = 1;
else
set_halt (ep);
} else
clear_halt (ep); clear_halt (ep);
(void) readl (&ep->regs->ep_rsp); (void) readl (&ep->regs->ep_rsp);
...@@ -2042,7 +2053,8 @@ static void handle_ep_small (struct net2280_ep *ep) ...@@ -2042,7 +2053,8 @@ static void handle_ep_small (struct net2280_ep *ep)
* can decide to stall ep0 after that done() returns, * can decide to stall ep0 after that done() returns,
* from non-irq context * from non-irq context
*/ */
allow_status (ep); if (!ep->stopped)
allow_status (ep);
req = 0; req = 0;
} else { } else {
if (!list_empty (&ep->queue) && !ep->stopped) if (!list_empty (&ep->queue) && !ep->stopped)
......
...@@ -377,12 +377,8 @@ static struct ed *ed_get ( ...@@ -377,12 +377,8 @@ static struct ed *ed_get (
ed->type = type; ed->type = type;
} }
/* FIXME: Don't do this without knowing it's safe to clobber this /* NOTE: only ep0 currently needs this "re"init logic, during
* state/mode info. Currently the upper layers don't support such * enumeration (after set_address, or if ep0 maxpacket >8).
* guarantees; we're lucky changing config/altsetting is rare.
* The state/mode info also changes during enumeration: set_address
* uses the 'wrong' device address, and ep0 maxpacketsize will often
* improve on the initial value.
*/ */
if (ed->state == ED_IDLE) { if (ed->state == ED_IDLE) {
u32 info; u32 info;
......
...@@ -45,7 +45,7 @@ hpusbscsi_usb_probe(struct usb_interface *intf, ...@@ -45,7 +45,7 @@ hpusbscsi_usb_probe(struct usb_interface *intf,
struct usb_host_interface *altsetting = intf->altsetting; struct usb_host_interface *altsetting = intf->altsetting;
struct hpusbscsi *new; struct hpusbscsi *new;
int error = -ENOMEM; int error = -ENOMEM;
int i, result; int i;
if (altsetting->desc.bNumEndpoints != 3) { if (altsetting->desc.bNumEndpoints != 3) {
printk (KERN_ERR "Wrong number of endpoints\n"); printk (KERN_ERR "Wrong number of endpoints\n");
......
...@@ -1101,6 +1101,52 @@ static int vicam_read_proc_gain(char *page, char **start, off_t off, ...@@ -1101,6 +1101,52 @@ static int vicam_read_proc_gain(char *page, char **start, off_t off,
((struct vicam_camera *)data)->gain); ((struct vicam_camera *)data)->gain);
} }
static int
vicam_write_proc_shutter(struct file *file, const char *buffer,
unsigned long count, void *data)
{
u16 stmp;
char kbuf[8];
struct vicam_camera *cam = (struct vicam_camera *) data;
if (count > 6)
return -EINVAL;
if (copy_from_user(kbuf, buffer, count))
return -EFAULT;
stmp = (u16) simple_strtoul(kbuf, NULL, 10);
if (stmp < 4 || stmp > 32000)
return -EINVAL;
cam->shutter_speed = stmp;
return count;
}
static int
vicam_write_proc_gain(struct file *file, const char *buffer,
unsigned long count, void *data)
{
u16 gtmp;
char kbuf[8];
struct vicam_camera *cam = (struct vicam_camera *) data;
if (count > 4)
return -EINVAL;
if (copy_from_user(kbuf, buffer, count))
return -EFAULT;
gtmp = (u16) simple_strtoul(kbuf, NULL, 10);
if (gtmp > 255)
return -EINVAL;
cam->gain = gtmp;
return count;
}
static void static void
vicam_create_proc_root(void) vicam_create_proc_root(void)
{ {
...@@ -1142,18 +1188,21 @@ vicam_create_proc_entry(struct vicam_camera *cam) ...@@ -1142,18 +1188,21 @@ vicam_create_proc_entry(struct vicam_camera *cam)
if ( !cam->proc_dir ) if ( !cam->proc_dir )
return; // FIXME: We should probably return an error here return; // FIXME: We should probably return an error here
ent = ent = create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR,
create_proc_entry("shutter", S_IFREG | S_IRUGO, cam->proc_dir); cam->proc_dir);
if (ent) { if (ent) {
ent->data = cam; ent->data = cam;
ent->read_proc = vicam_read_proc_shutter; ent->read_proc = vicam_read_proc_shutter;
ent->write_proc = vicam_write_proc_shutter;
ent->size = 64; ent->size = 64;
} }
ent = create_proc_entry("gain", S_IFREG | S_IRUGO , cam->proc_dir); ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR,
if ( ent ) { cam->proc_dir);
if (ent) {
ent->data = cam; ent->data = cam;
ent->read_proc = vicam_read_proc_gain; ent->read_proc = vicam_read_proc_gain;
ent->write_proc = vicam_write_proc_gain;
ent->size = 64; ent->size = 64;
} }
} }
......
...@@ -63,6 +63,8 @@ MODULE_AUTHOR(DRIVER_AUTHOR); ...@@ -63,6 +63,8 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC); MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static const char driver_name[] = "catc";
/* /*
* Some defines. * Some defines.
*/ */
...@@ -677,7 +679,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) ...@@ -677,7 +679,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
/* get driver info */ /* get driver info */
case ETHTOOL_GDRVINFO: { case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
strncpy(info.driver, SHORT_DRIVER_DESC, ETHTOOL_BUSINFO_LEN); strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN); strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
usb_make_path (catc->usbdev, info.bus_info, sizeof info.bus_info); usb_make_path (catc->usbdev, info.bus_info, sizeof info.bus_info);
if (copy_to_user(useraddr, &info, sizeof(info))) if (copy_to_user(useraddr, &info, sizeof(info)))
...@@ -978,7 +980,7 @@ MODULE_DEVICE_TABLE(usb, catc_id_table); ...@@ -978,7 +980,7 @@ MODULE_DEVICE_TABLE(usb, catc_id_table);
static struct usb_driver catc_driver = { static struct usb_driver catc_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "catc", .name = driver_name,
.probe = catc_probe, .probe = catc_probe,
.disconnect = catc_disconnect, .disconnect = catc_disconnect,
.id_table = catc_id_table, .id_table = catc_id_table,
......
...@@ -114,6 +114,8 @@ MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-p ...@@ -114,6 +114,8 @@ MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-p
MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver"); MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static const char driver_name[] = "kaweth";
static int kaweth_probe( static int kaweth_probe(
struct usb_interface *intf, struct usb_interface *intf,
const struct usb_device_id *id /* from id_table */ const struct usb_device_id *id /* from id_table */
...@@ -169,7 +171,7 @@ MODULE_DEVICE_TABLE (usb, usb_klsi_table); ...@@ -169,7 +171,7 @@ MODULE_DEVICE_TABLE (usb, usb_klsi_table);
****************************************************************/ ****************************************************************/
static struct usb_driver kaweth_driver = { static struct usb_driver kaweth_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "kaweth", .name = driver_name,
.probe = kaweth_probe, .probe = kaweth_probe,
.disconnect = kaweth_disconnect, .disconnect = kaweth_disconnect,
.id_table = usb_klsi_table, .id_table = usb_klsi_table,
...@@ -670,7 +672,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) ...@@ -670,7 +672,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
switch (ethcmd) { switch (ethcmd) {
case ETHTOOL_GDRVINFO: { case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
strlcpy(info.driver, "kaweth", sizeof(info.driver)); strlcpy(info.driver, driver_name, sizeof(info.driver));
if (copy_to_user(useraddr, &info, sizeof(info))) if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT; return -EFAULT;
return 0; return 0;
......
/* /*
* Copyright (c) 1999-2002 Petko Manolov (petkan@users.sourceforge.net) * Copyright (c) 1999-2003 Petko Manolov (petkan@users.sourceforge.net)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
/* /*
* Version Information * Version Information
*/ */
#define DRIVER_VERSION "v0.5.10 (2003/04/01)" #define DRIVER_VERSION "v0.5.12 (2003/06/06)"
#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"
...@@ -564,7 +564,14 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) ...@@ -564,7 +564,14 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
dbg("%s: reset MAC", net->name); dbg("%s: reset MAC", net->name);
pegasus->flags &= ~PEGASUS_RX_BUSY; pegasus->flags &= ~PEGASUS_RX_BUSY;
break; break;
case -EPIPE: /* stall, or disconnect from TT */
/* FIXME schedule work to clear the halt */
warn("%s: no rx stall recovery", net->name);
return;
case -ENOENT: case -ENOENT:
case -ECONNRESET:
case -ESHUTDOWN:
dbg("%s: rx unlink, %d", net->name, urb->status);
return; return;
default: default:
dbg("%s: RX status %d", net->name, urb->status); dbg("%s: RX status %d", net->name, urb->status);
...@@ -604,6 +611,9 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) ...@@ -604,6 +611,9 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
pegasus->stats.rx_packets++; pegasus->stats.rx_packets++;
pegasus->stats.rx_bytes += pkt_len; pegasus->stats.rx_bytes += pkt_len;
if (pegasus->flags & PEGASUS_UNPLUG)
return;
spin_lock(&pegasus->rx_pool_lock); spin_lock(&pegasus->rx_pool_lock);
pegasus->rx_skb = pull_skb(pegasus); pegasus->rx_skb = pull_skb(pegasus);
spin_unlock(&pegasus->rx_pool_lock); spin_unlock(&pegasus->rx_pool_lock);
...@@ -631,24 +641,24 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) ...@@ -631,24 +641,24 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
static void rx_fixup(unsigned long data) static void rx_fixup(unsigned long data)
{ {
pegasus_t *pegasus; pegasus_t *pegasus;
unsigned long flags;
pegasus = (pegasus_t *) data; pegasus = (pegasus_t *) data;
if (pegasus->flags & PEGASUS_UNPLUG)
return;
spin_lock_irq(&pegasus->rx_pool_lock); spin_lock_irqsave(&pegasus->rx_pool_lock, flags);
fill_skb_pool(pegasus); fill_skb_pool(pegasus);
spin_unlock_irq(&pegasus->rx_pool_lock);
if (pegasus->flags & PEGASUS_RX_URB_FAIL) if (pegasus->flags & PEGASUS_RX_URB_FAIL)
if (pegasus->rx_skb) if (pegasus->rx_skb)
goto try_again; goto try_again;
if (pegasus->rx_skb == NULL) { if (pegasus->rx_skb == NULL) {
spin_lock_irq(&pegasus->rx_pool_lock);
pegasus->rx_skb = pull_skb(pegasus); pegasus->rx_skb = pull_skb(pegasus);
spin_unlock_irq(&pegasus->rx_pool_lock);
} }
if (pegasus->rx_skb == NULL) { if (pegasus->rx_skb == NULL) {
warn("wow, low on memory"); warn("wow, low on memory");
tasklet_schedule(&pegasus->rx_tl); tasklet_schedule(&pegasus->rx_tl);
return; goto done;
} }
usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
usb_rcvbulkpipe(pegasus->usb, 1), usb_rcvbulkpipe(pegasus->usb, 1),
...@@ -661,23 +671,41 @@ static void rx_fixup(unsigned long data) ...@@ -661,23 +671,41 @@ static void rx_fixup(unsigned long data)
} else { } else {
pegasus->flags &= ~PEGASUS_RX_URB_FAIL; pegasus->flags &= ~PEGASUS_RX_URB_FAIL;
} }
done:
spin_unlock_irqrestore(&pegasus->rx_pool_lock, flags);
} }
static void write_bulk_callback(struct urb *urb, struct pt_regs *regs) static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
{ {
pegasus_t *pegasus = urb->context; pegasus_t *pegasus = urb->context;
struct net_device *net = pegasus->net;
if (!pegasus || !(pegasus->flags & PEGASUS_RUNNING)) if (!pegasus || !(pegasus->flags & PEGASUS_RUNNING))
return; return;
if (!netif_device_present(pegasus->net)) if (!netif_device_present(net))
return; return;
if (urb->status) switch (urb->status) {
info("%s: TX status %d", pegasus->net->name, urb->status); case -EPIPE:
/* FIXME schedule_work() to clear the tx halt */
netif_stop_queue(net);
warn("%s: no tx stall recovery", net->name);
return;
case -ENOENT:
case -ECONNRESET:
case -ESHUTDOWN:
dbg("%s: tx unlink, %d", net->name, urb->status);
return;
default:
info("%s: TX status %d", net->name, urb->status);
/* FALL THROUGH */
case 0:
break;
}
pegasus->net->trans_start = jiffies; net->trans_start = jiffies;
netif_wake_queue(pegasus->net); netif_wake_queue(net);
} }
static void intr_callback(struct urb *urb, struct pt_regs *regs) static void intr_callback(struct urb *urb, struct pt_regs *regs)
...@@ -754,8 +782,16 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net) ...@@ -754,8 +782,16 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
write_bulk_callback, pegasus); write_bulk_callback, pegasus);
if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) { if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) {
warn("failed tx_urb %d", res); warn("failed tx_urb %d", res);
pegasus->stats.tx_errors++; switch (res) {
netif_start_queue(net); case -EPIPE: /* stall, or disconnect from TT */
/* cleanup should already have been scheduled */
break;
case -ENODEV: /* disconnect() upcoming */
break;
default:
pegasus->stats.tx_errors++;
netif_start_queue(net);
}
} else { } else {
pegasus->stats.tx_packets++; pegasus->stats.tx_packets++;
pegasus->stats.tx_bytes += skb->len; pegasus->stats.tx_bytes += skb->len;
...@@ -903,6 +939,7 @@ static int pegasus_close(struct net_device *net) ...@@ -903,6 +939,7 @@ static int pegasus_close(struct net_device *net)
netif_stop_queue(net); netif_stop_queue(net);
if (!(pegasus->flags & PEGASUS_UNPLUG)) if (!(pegasus->flags & PEGASUS_UNPLUG))
disable_net_traffic(pegasus); disable_net_traffic(pegasus);
tasklet_kill(&pegasus->rx_tl);
unlink_all_urbs(pegasus); unlink_all_urbs(pegasus);
return 0; return 0;
...@@ -920,11 +957,15 @@ static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr) ...@@ -920,11 +957,15 @@ static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr)
switch (ethcmd) { switch (ethcmd) {
/* get driver-specific version/etc. info */ /* get driver-specific version/etc. info */
case ETHTOOL_GDRVINFO:{ case ETHTOOL_GDRVINFO:{
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; struct ethtool_drvinfo info;
strlcpy(info.driver, driver_name, memset (&info, 0, sizeof (info));
sizeof (info.driver)); info.cmd = ETHTOOL_GDRVINFO;
strlcpy(info.version, DRIVER_VERSION, strncpy(info.driver, driver_name,
sizeof (info.version)); sizeof (info.driver) - 1);
strncpy(info.version, DRIVER_VERSION,
sizeof (info.version) - 1);
usb_make_path(pegasus->usb, info.bus_info,
sizeof (info.bus_info));
if (copy_to_user(useraddr, &info, sizeof (info))) if (copy_to_user(useraddr, &info, sizeof (info)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -993,12 +1034,15 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) ...@@ -993,12 +1034,15 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
return -EFAULT; return -EFAULT;
switch (cmd) { switch (cmd) {
case ETHTOOL_GDRVINFO:{ case ETHTOOL_GDRVINFO:{
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; struct ethtool_drvinfo info;
strncpy(info.driver, driver_name, sizeof info.driver); memset (&info, 0, sizeof (info));
info.cmd = ETHTOOL_GDRVINFO;
strncpy(info.driver, driver_name,
sizeof (info.driver) - 1);
strncpy(info.version, DRIVER_VERSION, strncpy(info.version, DRIVER_VERSION,
ETHTOOL_BUSINFO_LEN); sizeof (info.version) - 1);
usb_make_path(pegasus->usb, info.bus_info, usb_make_path(pegasus->usb, info.bus_info,
sizeof info.bus_info); sizeof (info.bus_info));
if (copy_to_user(uaddr, &info, sizeof (info))) if (copy_to_user(uaddr, &info, sizeof (info)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -1006,15 +1050,20 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) ...@@ -1006,15 +1050,20 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
case ETHTOOL_GSET:{ case ETHTOOL_GSET:{
struct ethtool_cmd ecmd; struct ethtool_cmd ecmd;
short lpa, bmcr; short lpa, bmcr;
u8 port;
memset(&ecmd, 0, sizeof ecmd); memset(&ecmd, 0, sizeof (ecmd));
ecmd.supported = (SUPPORTED_10baseT_Half | ecmd.supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full | SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg | SUPPORTED_Autoneg |
SUPPORTED_TP | SUPPORTED_MII); SUPPORTED_TP | SUPPORTED_MII);
ecmd.port = PORT_TP; get_registers(pegasus, Reg7b, 1, &port);
if (port == 0)
ecmd.port = PORT_MII;
else
ecmd.port = PORT_TP;
ecmd.transceiver = XCVR_INTERNAL; ecmd.transceiver = XCVR_INTERNAL;
ecmd.phy_address = pegasus->phy; ecmd.phy_address = pegasus->phy;
read_mii_word(pegasus, pegasus->phy, MII_BMCR, &bmcr); read_mii_word(pegasus, pegasus->phy, MII_BMCR, &bmcr);
...@@ -1132,7 +1181,10 @@ static inline void setup_pegasus_II(pegasus_t * pegasus) ...@@ -1132,7 +1181,10 @@ static inline void setup_pegasus_II(pegasus_t * pegasus)
set_register(pegasus, Reg1d, 0); set_register(pegasus, Reg1d, 0);
set_register(pegasus, Reg7b, 1); set_register(pegasus, Reg7b, 1);
mdelay(100); mdelay(100);
set_register(pegasus, Reg7b, 2); if ((pegasus->features & HAS_HOME_PNA) && mii_mode)
set_register(pegasus, Reg7b, 0);
else
set_register(pegasus, Reg7b, 2);
set_register(pegasus, 0x83, data); set_register(pegasus, 0x83, data);
get_registers(pegasus, 0x83, 1, &data); get_registers(pegasus, 0x83, 1, &data);
...@@ -1253,7 +1305,6 @@ static void pegasus_disconnect(struct usb_interface *intf) ...@@ -1253,7 +1305,6 @@ static void pegasus_disconnect(struct usb_interface *intf)
pegasus->flags |= PEGASUS_UNPLUG; pegasus->flags |= PEGASUS_UNPLUG;
unregister_netdev(pegasus->net); unregister_netdev(pegasus->net);
usb_put_dev(interface_to_usbdev(intf)); usb_put_dev(interface_to_usbdev(intf));
unlink_all_urbs(pegasus);
free_all_urbs(pegasus); free_all_urbs(pegasus);
free_skb_pool(pegasus); free_skb_pool(pegasus);
if (pegasus->rx_skb) if (pegasus->rx_skb)
...@@ -1263,7 +1314,6 @@ static void pegasus_disconnect(struct usb_interface *intf) ...@@ -1263,7 +1314,6 @@ static void pegasus_disconnect(struct usb_interface *intf)
} }
static struct usb_driver pegasus_driver = { static struct usb_driver pegasus_driver = {
.owner = THIS_MODULE,
.name = driver_name, .name = driver_name,
.probe = pegasus_probe, .probe = pegasus_probe,
.disconnect = pegasus_disconnect, .disconnect = pegasus_disconnect,
......
/* /*
* Copyright (c) 1999-2002 Petko Manolov - Petkan (petkan@users.sourceforge.net) * Copyright (c) 1999-2003 Petko Manolov - Petkan (petkan@users.sourceforge.net)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published * it under the terms of the GNU General Public License version 2 as published
...@@ -129,6 +129,7 @@ struct usb_eth_dev { ...@@ -129,6 +129,7 @@ struct usb_eth_dev {
#define VENDOR_ELCON 0x0db7 #define VENDOR_ELCON 0x0db7
#define VENDOR_ELSA 0x05cc #define VENDOR_ELSA 0x05cc
#define VENDOR_HAWKING 0x0e66 #define VENDOR_HAWKING 0x0e66
#define VENDOR_HP 0x03f0
#define VENDOR_IODATA 0x04bb #define VENDOR_IODATA 0x04bb
#define VENDOR_KINGSTON 0x0951 #define VENDOR_KINGSTON 0x0951
#define VENDOR_LANEED 0x056e #define VENDOR_LANEED 0x056e
...@@ -223,6 +224,8 @@ PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000, ...@@ -223,6 +224,8 @@ PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c, PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913, PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
......
...@@ -113,9 +113,11 @@ static void rtl8150_disconnect(struct usb_interface *intf); ...@@ -113,9 +113,11 @@ static void rtl8150_disconnect(struct usb_interface *intf);
static int rtl8150_probe(struct usb_interface *intf, static int rtl8150_probe(struct usb_interface *intf,
const struct usb_device_id *id); const struct usb_device_id *id);
static const char driver_name [] = "rtl8150";
static struct usb_driver rtl8150_driver = { static struct usb_driver rtl8150_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "rtl8150", .name = driver_name,
.probe = rtl8150_probe, .probe = rtl8150_probe,
.disconnect = rtl8150_disconnect, .disconnect = rtl8150_disconnect,
.id_table = rtl8150_table, .id_table = rtl8150_table,
...@@ -684,7 +686,7 @@ static int rtl8150_ethtool_ioctl(struct net_device *netdev, void *uaddr) ...@@ -684,7 +686,7 @@ static int rtl8150_ethtool_ioctl(struct net_device *netdev, void *uaddr)
case ETHTOOL_GDRVINFO:{ case ETHTOOL_GDRVINFO:{
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strncpy(info.driver, DRIVER_DESC, ETHTOOL_BUSINFO_LEN); strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN); strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
usb_make_path(dev->udev, info.bus_info, sizeof info.bus_info); usb_make_path(dev->udev, info.bus_info, sizeof info.bus_info);
if (copy_to_user(uaddr, &info, sizeof(info))) if (copy_to_user(uaddr, &info, sizeof(info)))
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include <linux/config.h> #include <linux/config.h>
#include "transport.h" #include "transport.h"
#include "protocol.h" #include "protocol.h"
#include "scsiglue.h"
#include "usb.h" #include "usb.h"
#include "debug.h" #include "debug.h"
...@@ -303,6 +304,11 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe, ...@@ -303,6 +304,11 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe,
US_DEBUGP("-- device NAKed\n"); US_DEBUGP("-- device NAKed\n");
return USB_STOR_XFER_ERROR; return USB_STOR_XFER_ERROR;
/* babble - the device tried to send more than we wanted to read */
case -EOVERFLOW:
US_DEBUGP("-- Babble\n");
return USB_STOR_XFER_LONG;
/* the transfer was cancelled, presumably by an abort */ /* the transfer was cancelled, presumably by an abort */
case -ECONNRESET: case -ECONNRESET:
US_DEBUGP("-- transfer cancelled\n"); US_DEBUGP("-- transfer cancelled\n");
...@@ -525,6 +531,12 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -525,6 +531,12 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
return; return;
} }
/* if the transport provided its own sense data, don't auto-sense */
if (result == USB_STOR_TRANSPORT_NO_SENSE) {
srb->result = SAM_STAT_CHECK_CONDITION;
return;
}
/* Determine if we need to auto-sense /* Determine if we need to auto-sense
* *
* I normally don't use a flag like this, but it's almost impossible * I normally don't use a flag like this, but it's almost impossible
...@@ -764,7 +776,7 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -764,7 +776,7 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->request_buffer, transfer_length, srb->request_buffer, transfer_length,
srb->use_sg, &srb->resid); srb->use_sg, &srb->resid);
US_DEBUGP("CBI data stage result is 0x%x\n", result); US_DEBUGP("CBI data stage result is 0x%x\n", result);
if (result == USB_STOR_XFER_ERROR) if (result > USB_STOR_XFER_STALLED)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
} }
...@@ -854,7 +866,7 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -854,7 +866,7 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->request_buffer, transfer_length, srb->request_buffer, transfer_length,
srb->use_sg, &srb->resid); srb->use_sg, &srb->resid);
US_DEBUGP("CB data stage result is 0x%x\n", result); US_DEBUGP("CB data stage result is 0x%x\n", result);
if (result == USB_STOR_XFER_ERROR) if (result > USB_STOR_XFER_STALLED)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
} }
...@@ -899,6 +911,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -899,6 +911,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
struct bulk_cs_wrap bcs; struct bulk_cs_wrap bcs;
unsigned int transfer_length = srb->request_bufflen; unsigned int transfer_length = srb->request_bufflen;
int result; int result;
int fake_sense = 0;
/* set up the command wrapper */ /* set up the command wrapper */
bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
...@@ -936,6 +949,15 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -936,6 +949,15 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("Bulk data transfer result 0x%x\n", result); US_DEBUGP("Bulk data transfer result 0x%x\n", result);
if (result == USB_STOR_XFER_ERROR) if (result == USB_STOR_XFER_ERROR)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
/* If the device tried to send back more data than the
* amount requested, the spec requires us to transfer
* the CSW anyway. Since there's no point retrying the
* the command, we'll return fake sense data indicating
* Illegal Request, Invalid Field in CDB.
*/
if (result == USB_STOR_XFER_LONG)
fake_sense = 1;
} }
/* See flow chart on pg 15 of the Bulk Only Transport spec for /* See flow chart on pg 15 of the Bulk Only Transport spec for
...@@ -975,6 +997,14 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -975,6 +997,14 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* based on the status code, we report good or bad */ /* based on the status code, we report good or bad */
switch (bcs.Status) { switch (bcs.Status) {
case US_BULK_STAT_OK: case US_BULK_STAT_OK:
/* device babbled -- return fake sense data */
if (fake_sense) {
memcpy(srb->sense_buffer,
usb_stor_sense_invalidCDB,
sizeof(usb_stor_sense_invalidCDB));
return USB_STOR_TRANSPORT_NO_SENSE;
}
/* command good -- note that data could be short */ /* command good -- note that data could be short */
return USB_STOR_TRANSPORT_GOOD; return USB_STOR_TRANSPORT_GOOD;
......
...@@ -122,7 +122,8 @@ struct bulk_cs_wrap { ...@@ -122,7 +122,8 @@ struct bulk_cs_wrap {
#define USB_STOR_XFER_GOOD 0 /* good transfer */ #define USB_STOR_XFER_GOOD 0 /* good transfer */
#define USB_STOR_XFER_SHORT 1 /* transferred less than expected */ #define USB_STOR_XFER_SHORT 1 /* transferred less than expected */
#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */ #define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
#define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */ #define USB_STOR_XFER_LONG 3 /* device tried to send too much */
#define USB_STOR_XFER_ERROR 4 /* transfer died in the middle */
/* /*
* Transport return codes * Transport return codes
...@@ -130,7 +131,8 @@ struct bulk_cs_wrap { ...@@ -130,7 +131,8 @@ 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_NO_SENSE 2 /* Command failed, no auto-sense */
#define USB_STOR_TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */
/* /*
* We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED * We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED
......
This diff is collapsed.
...@@ -107,6 +107,7 @@ struct us_data { ...@@ -107,6 +107,7 @@ struct us_data {
*/ */
struct semaphore dev_semaphore; /* protect pusb_dev */ struct semaphore dev_semaphore; /* protect pusb_dev */
struct usb_device *pusb_dev; /* this usb_device */ struct usb_device *pusb_dev; /* this usb_device */
struct usb_interface *pusb_intf; /* this interface */
unsigned long flags; /* from filter initially */ unsigned long flags; /* from filter initially */
unsigned int send_bulk_pipe; /* cached pipe values */ unsigned int send_bulk_pipe; /* cached pipe values */
unsigned int recv_bulk_pipe; unsigned int recv_bulk_pipe;
...@@ -114,7 +115,7 @@ struct us_data { ...@@ -114,7 +115,7 @@ struct us_data {
unsigned int recv_ctrl_pipe; unsigned int recv_ctrl_pipe;
unsigned int recv_intr_pipe; unsigned int recv_intr_pipe;
/* information about the device -- always good */ /* information about the device */
char vendor[USB_STOR_STRING_LEN]; char vendor[USB_STOR_STRING_LEN];
char product[USB_STOR_STRING_LEN]; char product[USB_STOR_STRING_LEN];
char serial[USB_STOR_STRING_LEN]; char serial[USB_STOR_STRING_LEN];
...@@ -124,11 +125,7 @@ struct us_data { ...@@ -124,11 +125,7 @@ struct us_data {
u8 protocol; u8 protocol;
u8 max_lun; u8 max_lun;
/* information about the device -- only good if device is attached */
u8 ifnum; /* interface number */ u8 ifnum; /* interface number */
u8 ep_in; /* bulk in endpoint */
u8 ep_out; /* bulk out endpoint */
u8 ep_int; /* interrupt endpoint */
u8 ep_bInterval; /* interrupt interval */ u8 ep_bInterval; /* interrupt interval */
/* function pointers for this device */ /* function pointers for this device */
......
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