Commit ead584e3 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 b4f6270e e74f55d6
...@@ -1210,6 +1210,10 @@ S: 25360 Georgia Tech Station ...@@ -1210,6 +1210,10 @@ S: 25360 Georgia Tech Station
S: Atlanta, Georgia 30332 S: Atlanta, Georgia 30332
S: USA S: USA
N: Brad Hards
E: bradh@frogmouth.net
D: Various USB bits, other minor patches
N: Angelo Haritsis N: Angelo Haritsis
E: ah@computer.org E: ah@computer.org
D: kernel patches (serial, watchdog) D: kernel patches (serial, watchdog)
......
...@@ -1869,11 +1869,12 @@ S: Maintained ...@@ -1869,11 +1869,12 @@ S: Maintained
W: http://www.kroah.com/linux-usb/ W: http://www.kroah.com/linux-usb/
USB CDC ETHERNET DRIVER USB CDC ETHERNET DRIVER
P: Brad Hards P: Greg Kroah-Hartman
M: bradh@frogmouth.net M: greg@kroah.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
W: http://www.kroah.com/linux-usb/
USB EHCI DRIVER USB EHCI DRIVER
P: David Brownell P: David Brownell
......
...@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_SL811HS) += host/ ...@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_SL811HS) += host/
obj-$(CONFIG_USB_ACM) += class/ obj-$(CONFIG_USB_ACM) += class/
obj-$(CONFIG_USB_AUDIO) += class/ obj-$(CONFIG_USB_AUDIO) += class/
obj-$(CONFIG_USB_BLUETOOTH_TTY) += class/ obj-$(CONFIG_USB_BLUETOOTH_TTY) += class/
obj-$(CONFIG_USB_MIDI) += class/
obj-$(CONFIG_USB_PRINTER) += class/ obj-$(CONFIG_USB_PRINTER) += class/
obj-$(CONFIG_USB_STORAGE) += storage/ obj-$(CONFIG_USB_STORAGE) += storage/
......
...@@ -172,7 +172,6 @@ ...@@ -172,7 +172,6 @@
/*****************************************************************************/ /*****************************************************************************/
#include <linux/version.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
......
...@@ -538,7 +538,7 @@ static int acm_probe (struct usb_interface *intf, ...@@ -538,7 +538,7 @@ static int acm_probe (struct usb_interface *intf,
cfacm = dev->config + i; cfacm = dev->config + i;
dbg("probing config %d", cfacm->bConfigurationValue); dbg("probing config %d", cfacm->desc.bConfigurationValue);
if (cfacm->desc.bNumInterfaces != 2 || if (cfacm->desc.bNumInterfaces != 2 ||
usb_interface_claimed(cfacm->interface + 0) || usb_interface_claimed(cfacm->interface + 0) ||
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pci.h> #include <linux/pci.h>
......
...@@ -1024,9 +1024,7 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) ...@@ -1024,9 +1024,7 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
*/ */
urb->transfer_flags |= URB_NO_DMA_MAP; urb->transfer_flags |= URB_NO_DMA_MAP;
status = rh_urb_enqueue (hcd, urb); status = rh_urb_enqueue (hcd, urb);
if (status) goto done;
urb_unlink (urb);
return status;
} }
/* lower level hcd code should use *_dma exclusively, /* lower level hcd code should use *_dma exclusively,
...@@ -1051,8 +1049,11 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) ...@@ -1051,8 +1049,11 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
} }
status = hcd->driver->urb_enqueue (hcd, urb, mem_flags); status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
if (status) done:
if (status) {
usb_put_urb (urb);
urb_unlink (urb); urb_unlink (urb);
}
return status; return status;
} }
......
...@@ -135,8 +135,7 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs) ...@@ -135,8 +135,7 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
default: /* presumably an error */ default: /* presumably an error */
/* Cause a hub reset after 10 consecutive errors */ /* Cause a hub reset after 10 consecutive errors */
dbg("hub '%s' status %d for interrupt transfer", dev_dbg (&hub->intf->dev, "transfer --> %d\n", urb->status);
urb->dev->devpath, urb->status);
if ((++hub->nerrors < 10) || hub->error) if ((++hub->nerrors < 10) || hub->error)
goto resubmit; goto resubmit;
hub->error = urb->status; hub->error = urb->status;
...@@ -158,10 +157,10 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs) ...@@ -158,10 +157,10 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
spin_unlock_irqrestore(&hub_event_lock, flags); spin_unlock_irqrestore(&hub_event_lock, flags);
resubmit: resubmit:
if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0) if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0
err ("hub '%s-%s' status %d for interrupt resubmit", /* ENODEV means we raced disconnect() */
urb->dev->bus->bus_name, urb->dev->devpath, && status != -ENODEV)
status); dev_err (&hub->intf->dev, "resubmit --> %d\n", urb->status);
} }
/* USB 2.0 spec Section 11.24.2.3 */ /* USB 2.0 spec Section 11.24.2.3 */
...@@ -648,12 +647,13 @@ static int usb_hub_port_status(struct usb_device *hub, int port, ...@@ -648,12 +647,13 @@ static int usb_hub_port_status(struct usb_device *hub, int port,
struct usb_port_status *portsts; struct usb_port_status *portsts;
int ret = -ENOMEM; int ret = -ENOMEM;
portsts = kmalloc(sizeof(*portsts), GFP_KERNEL); portsts = kmalloc(sizeof(*portsts), GFP_NOIO);
if (portsts) { if (portsts) {
ret = usb_get_port_status(hub, port + 1, portsts); ret = usb_get_port_status(hub, port + 1, portsts);
if (ret < 0) if (ret < 0)
err("%s(%s-%s) failed (err = %d)", __FUNCTION__, dev_err (hubdev (hub),
hub->bus->bus_name, hub->devpath, ret); "%s failed (err = %d)\n", __FUNCTION__,
ret);
else { else {
*status = le16_to_cpu(portsts->wPortStatus); *status = le16_to_cpu(portsts->wPortStatus);
*change = le16_to_cpu(portsts->wPortChange); *change = le16_to_cpu(portsts->wPortChange);
...@@ -759,8 +759,8 @@ void usb_hub_port_disable(struct usb_device *hub, int port) ...@@ -759,8 +759,8 @@ void usb_hub_port_disable(struct usb_device *hub, int port)
ret = usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_ENABLE); ret = usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_ENABLE);
if (ret) if (ret)
err("cannot disable port %d of hub %s (err = %d)", dev_err(hubdev(hub), "cannot disable port %d (err = %d)\n",
port + 1, hub->devpath, ret); port + 1, ret);
} }
/* USB 2.0 spec, 7.1.7.3 / fig 7-29: /* USB 2.0 spec, 7.1.7.3 / fig 7-29:
...@@ -983,12 +983,12 @@ static void usb_hub_events(void) ...@@ -983,12 +983,12 @@ static void usb_hub_events(void)
spin_unlock_irqrestore(&hub_event_lock, flags); spin_unlock_irqrestore(&hub_event_lock, flags);
if (hub->error) { if (hub->error) {
dbg("resetting hub %s for error %d", dev_dbg (&hub->intf->dev, "resetting for error %d\n",
dev->devpath, hub->error); hub->error);
if (usb_hub_reset(hub)) { if (usb_hub_reset(hub)) {
err("error resetting hub %s - disconnecting", dev_dbg (&hub->intf->dev,
dev->devpath); "can't reset; disconnecting\n");
up(&hub->khubd_sem); up(&hub->khubd_sem);
usb_hub_disconnect(dev); usb_hub_disconnect(dev);
continue; continue;
...@@ -1022,33 +1022,37 @@ static void usb_hub_events(void) ...@@ -1022,33 +1022,37 @@ static void usb_hub_events(void)
if (!(portstatus & USB_PORT_STAT_ENABLE) if (!(portstatus & USB_PORT_STAT_ENABLE)
&& (portstatus & USB_PORT_STAT_CONNECTION) && (portstatus & USB_PORT_STAT_CONNECTION)
&& (dev->children[i])) { && (dev->children[i])) {
err("already running hub %s port %i " dev_err (&hub->intf->dev,
"port %i "
"disabled by hub (EMI?), " "disabled by hub (EMI?), "
"re-enabling...", "re-enabling...",
dev->devpath, i + 1); i + 1);
usb_hub_port_connect_change(hub, usb_hub_port_connect_change(hub,
i, portstatus, portchange); i, portstatus, portchange);
} }
} }
if (portchange & USB_PORT_STAT_C_SUSPEND) { if (portchange & USB_PORT_STAT_C_SUSPEND) {
dbg("hub %s port %d suspend change", dev_dbg (&hub->intf->dev,
dev->devpath, i + 1); "suspend change on port %d\n",
i + 1);
usb_clear_port_feature(dev, usb_clear_port_feature(dev,
i + 1, USB_PORT_FEAT_C_SUSPEND); i + 1, USB_PORT_FEAT_C_SUSPEND);
} }
if (portchange & USB_PORT_STAT_C_OVERCURRENT) { if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
err("hub %s port %d over-current change", dev_err (&hub->intf->dev,
dev->devpath, i + 1); "over-current change on port %d\n",
i + 1);
usb_clear_port_feature(dev, usb_clear_port_feature(dev,
i + 1, USB_PORT_FEAT_C_OVER_CURRENT); i + 1, USB_PORT_FEAT_C_OVER_CURRENT);
usb_hub_power_on(hub); usb_hub_power_on(hub);
} }
if (portchange & USB_PORT_STAT_C_RESET) { if (portchange & USB_PORT_STAT_C_RESET) {
dbg("hub %s port %d reset change", dev_dbg (&hub->intf->dev,
dev->devpath, i + 1); "reset change on port %d\n",
i + 1);
usb_clear_port_feature(dev, usb_clear_port_feature(dev,
i + 1, USB_PORT_FEAT_C_RESET); i + 1, USB_PORT_FEAT_C_RESET);
} }
...@@ -1056,16 +1060,16 @@ static void usb_hub_events(void) ...@@ -1056,16 +1060,16 @@ static void usb_hub_events(void)
/* deal with hub status changes */ /* deal with hub status changes */
if (usb_get_hub_status(dev, &hubsts) < 0) if (usb_get_hub_status(dev, &hubsts) < 0)
err("get_hub_status %s failed", dev->devpath); dev_err (&hub->intf->dev, "get_hub_status failed\n");
else { else {
hubstatus = le16_to_cpup(&hubsts.wHubStatus); hubstatus = le16_to_cpup(&hubsts.wHubStatus);
hubchange = le16_to_cpup(&hubsts.wHubChange); hubchange = le16_to_cpup(&hubsts.wHubChange);
if (hubchange & HUB_CHANGE_LOCAL_POWER) { if (hubchange & HUB_CHANGE_LOCAL_POWER) {
dbg("hub %s power change", dev->devpath); dev_dbg (&hub->intf->dev, "power change\n");
usb_clear_hub_feature(dev, C_HUB_LOCAL_POWER); usb_clear_hub_feature(dev, C_HUB_LOCAL_POWER);
} }
if (hubchange & HUB_CHANGE_OVERCURRENT) { if (hubchange & HUB_CHANGE_OVERCURRENT) {
dbg("hub %s overcurrent change", dev->devpath); dev_dbg (&hub->intf->dev, "overcurrent change\n");
wait_ms(500); /* Cool down */ wait_ms(500); /* Cool down */
usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT); usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
usb_hub_power_on(hub); usb_hub_power_on(hub);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/mm.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include "hcd.h" /* for usbcore internals */ #include "hcd.h" /* for usbcore internals */
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
* face, but so that you can still use them.. * face, but so that you can still use them..
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/version.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/slab.h> #include <linux/slab.h>
......
...@@ -866,14 +866,11 @@ void usb_disconnect(struct usb_device **pdev) ...@@ -866,14 +866,11 @@ void usb_disconnect(struct usb_device **pdev)
} }
/** /**
* usb_connect - connects a new device during enumeration (usbcore-internal) * usb_connect - pick device address (usbcore-internal)
* @dev: partially enumerated device * @dev: newly detected device (in DEFAULT state)
*
* Connect a new USB device. This basically just initializes
* the USB device information and sets up the topology - it's
* up to the low-level driver to reset the port and actually
* do the setup (the upper levels don't know how to do that).
* *
* Picks a device address. It's up to the hub (or root hub) driver
* to handle and manage enumeration, starting from the DEFAULT state.
* Only hub drivers (including virtual root hub drivers for host * Only hub drivers (including virtual root hub drivers for host
* controllers) should ever call this. * controllers) should ever call this.
*/ */
...@@ -983,7 +980,7 @@ static void set_device_description (struct usb_device *dev) ...@@ -983,7 +980,7 @@ static void set_device_description (struct usb_device *dev)
} }
/* /*
* By the time we get here, the device has gotten a new device ID * By the time we get here, we chose a new device address
* and is in the default state. We need to identify the thing and * and is in the default state. We need to identify the thing and
* get the ball rolling.. * get the ball rolling..
* *
......
...@@ -94,7 +94,6 @@ ...@@ -94,7 +94,6 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/interrupt.h> /* for in_interrupt () */ #include <linux/interrupt.h> /* for in_interrupt () */
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/version.h>
#include "../core/hcd.h" #include "../core/hcd.h"
#include <asm/io.h> #include <asm/io.h>
......
...@@ -85,7 +85,6 @@ ...@@ -85,7 +85,6 @@
* (20/10/1999) * (20/10/1999)
*/ */
#include <linux/version.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/fs.h> #include <linux/fs.h>
......
...@@ -60,7 +60,6 @@ ...@@ -60,7 +60,6 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
......
...@@ -78,19 +78,28 @@ static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit) ...@@ -78,19 +78,28 @@ static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit)
return response; return response;
} }
#define FW_LOAD_SIZE 1023
static int emi26_load_firmware (struct usb_device *dev) static int emi26_load_firmware (struct usb_device *dev)
{ {
int err; int err;
int i; int i;
int pos = 0; /* Position in hex record */ int pos = 0; /* Position in hex record */
__u32 addr; /* Address to write */ __u32 addr; /* Address to write */
__u8 buf[1023]; __u8 *buf;
buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
if (!buf) {
err( "%s - error loading firmware: error = %d", __FUNCTION__, -ENOMEM);
err = -ENOMEM;
goto wraperr;
}
/* Assert reset (stop the CPU in the EMI) */ /* Assert reset (stop the CPU in the EMI) */
err = emi26_set_reset(dev,1); err = emi26_set_reset(dev,1);
if (err < 0) { if (err < 0) {
err( "%s - error loading firmware: error = %d", __FUNCTION__, err); err( "%s - error loading firmware: error = %d", __FUNCTION__, err);
return err; goto wraperr;
} }
/* 1. We need to put the loader for the FPGA into the EZ-USB */ /* 1. We need to put the loader for the FPGA into the EZ-USB */
...@@ -98,7 +107,7 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -98,7 +107,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL); err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL);
if (err < 0) { if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err); err("%s - error loading firmware: error = %d", __FUNCTION__, err);
return err; goto wraperr;
} }
} }
...@@ -113,7 +122,7 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -113,7 +122,7 @@ static int emi26_load_firmware (struct usb_device *dev)
addr = g_bitstream[pos].address; addr = g_bitstream[pos].address;
/* intel hex records are terminated with type 0 element */ /* intel hex records are terminated with type 0 element */
while ((g_bitstream[pos].type == 0) && (i + g_bitstream[pos].length < sizeof(buf))) { while ((g_bitstream[pos].type == 0) && (i + g_bitstream[pos].length < FW_LOAD_SIZE)) {
memcpy(buf + i, g_bitstream[pos].data, g_bitstream[pos].length); memcpy(buf + i, g_bitstream[pos].data, g_bitstream[pos].length);
i += g_bitstream[pos].length; i += g_bitstream[pos].length;
pos++; pos++;
...@@ -121,7 +130,7 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -121,7 +130,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA); err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
if (err < 0) { if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err); err("%s - error loading firmware: error = %d", __FUNCTION__, err);
return err; goto wraperr;
} }
} while (i > 0); } while (i > 0);
...@@ -129,7 +138,7 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -129,7 +138,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_set_reset(dev,1); err = emi26_set_reset(dev,1);
if (err < 0) { if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err); err("%s - error loading firmware: error = %d", __FUNCTION__, err);
return err; goto wraperr;
} }
/* 3. We need to put the loader for the firmware into the EZ-USB (again...) */ /* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
...@@ -137,7 +146,7 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -137,7 +146,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL); err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL);
if (err < 0) { if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err); err("%s - error loading firmware: error = %d", __FUNCTION__, err);
return err; goto wraperr;
} }
} }
...@@ -145,7 +154,7 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -145,7 +154,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_set_reset(dev,0); err = emi26_set_reset(dev,0);
if (err < 0) { if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err); err("%s - error loading firmware: error = %d", __FUNCTION__, err);
return err; goto wraperr;
} }
/* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */ /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
...@@ -154,7 +163,7 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -154,7 +163,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_EXTERNAL); err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_EXTERNAL);
if (err < 0) { if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err); err("%s - error loading firmware: error = %d", __FUNCTION__, err);
return err; goto wraperr;
} }
} }
} }
...@@ -163,7 +172,7 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -163,7 +172,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_set_reset(dev,1); err = emi26_set_reset(dev,1);
if (err < 0) { if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err); err("%s - error loading firmware: error = %d", __FUNCTION__, err);
return err; goto wraperr;
} }
for (i=0; g_Firmware[i].type == 0; i++) { for (i=0; g_Firmware[i].type == 0; i++) {
...@@ -171,7 +180,7 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -171,7 +180,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_INTERNAL); err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_INTERNAL);
if (err < 0) { if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err); err("%s - error loading firmware: error = %d", __FUNCTION__, err);
return err; goto wraperr;
} }
} }
} }
...@@ -180,12 +189,16 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -180,12 +189,16 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_set_reset(dev,0); err = emi26_set_reset(dev,0);
if (err < 0) { if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err); err("%s - error loading firmware: error = %d", __FUNCTION__, err);
return err; goto wraperr;
} }
/* return 1 to fail the driver inialization /* return 1 to fail the driver inialization
* and give real driver change to load */ * and give real driver change to load */
return 1; return 1;
wraperr:
kfree(buf);
return err;
} }
static __devinitdata struct usb_device_id id_table [] = { static __devinitdata struct usb_device_id id_table [] = {
......
...@@ -148,27 +148,15 @@ struct udsl_control { ...@@ -148,27 +148,15 @@ struct udsl_control {
#define UDSL_SKB(x) ((struct udsl_control *)(x)->cb) #define UDSL_SKB(x) ((struct udsl_control *)(x)->cb)
struct atmsar_vcc_data { struct udsl_vcc_data {
struct atmsar_vcc_data *next; /* vpi/vci lookup */
struct list_head list;
/* general atmsar flags, per connection */ short vpi;
int flags; int vci;
int type;
/* connection specific non-atmsar data */
struct atm_vcc *vcc; struct atm_vcc *vcc;
struct k_atm_aal_stats *stats;
unsigned short mtu; /* max is actually 65k for AAL5... */
/* cell data */
unsigned int vp;
unsigned int vc;
unsigned char gfc;
unsigned char pti;
unsigned int headerFlags;
unsigned long atmHeader;
/* raw cell reassembly */ /* raw cell reassembly */
unsigned short mtu;
struct sk_buff *reasBuffer; struct sk_buff *reasBuffer;
}; };
...@@ -186,7 +174,7 @@ struct udsl_instance_data { ...@@ -186,7 +174,7 @@ struct udsl_instance_data {
/* atm device part */ /* atm device part */
struct atm_dev *atm_dev; struct atm_dev *atm_dev;
struct atmsar_vcc_data *atmsar_vcc_list; struct list_head vcc_list;
/* receiving */ /* receiving */
struct udsl_receiver all_receivers [UDSL_NUMBER_RCV_URBS]; struct udsl_receiver all_receivers [UDSL_NUMBER_RCV_URBS];
...@@ -258,73 +246,46 @@ static struct usb_driver udsl_usb_driver = { ...@@ -258,73 +246,46 @@ static struct usb_driver udsl_usb_driver = {
** decode ** ** decode **
*************/ *************/
#define ATM_HDR_VPVC_MASK (ATM_HDR_VPI_MASK | ATM_HDR_VCI_MASK) static inline struct udsl_vcc_data *udsl_find_vcc (struct udsl_instance_data *instance, short vpi, int vci)
#define ATMSAR_USE_53BYTE_CELL 0x1L
struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_buff *skb,
struct atmsar_vcc_data **ctx)
{ {
while (skb->len) { struct udsl_vcc_data *vcc;
unsigned char *cell = skb->data;
unsigned char *cell_payload;
struct atmsar_vcc_data *vcc = list;
unsigned long atmHeader =
((unsigned long) (cell[0]) << 24) | ((unsigned long) (cell[1]) << 16) |
((unsigned long) (cell[2]) << 8) | (cell[3] & 0xff);
dbg ("atmsar_decode_rawcell (0x%p, 0x%p, 0x%p) called", list, skb, ctx); list_for_each_entry (vcc, &instance->vcc_list, list)
dbg ("atmsar_decode_rawcell skb->data %p, skb->tail %p", skb->data, skb->tail); if ((vcc->vpi == vpi) && (vcc->vci == vci))
return vcc;
return NULL;
}
if (!list || !skb || !ctx) static struct sk_buff *udsl_decode_rawcell (struct udsl_instance_data *instance, struct sk_buff *skb, struct udsl_vcc_data **ctx)
{
if (!instance || !skb || !ctx)
return NULL; return NULL;
if (!skb->data || !skb->tail) if (!skb->data || !skb->tail)
return NULL; return NULL;
/* here should the header CRC check be... */ while (skb->len) {
unsigned char *cell = skb->data;
/* look up correct vcc */ unsigned char *cell_payload;
for (; struct udsl_vcc_data *vcc;
vcc short vpi;
&& ((vcc->atmHeader & ATM_HDR_VPVC_MASK) != (atmHeader & ATM_HDR_VPVC_MASK)); int vci;
vcc = vcc->next);
dbg ("atmsar_decode_rawcell found vcc %p for packet on vp %d, vc %d", vcc, vpi = ((cell[0] & 0x0f) << 4) | (cell[1] >> 4);
(int) ((atmHeader & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT), vci = ((cell[1] & 0x0f) << 12) | (cell[2] << 4) | (cell[3] >> 4);
(int) ((atmHeader & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT));
if (vcc && (skb->len >= (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52))) { dbg ("udsl_decode_rawcell (0x%p, 0x%p, 0x%p) called", instance, skb, ctx);
cell_payload = cell + (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 5 : 4); dbg ("udsl_decode_rawcell skb->data %p, skb->tail %p", skb->data, skb->tail);
switch (vcc->type) { /* here should the header CRC check be... */
case ATM_AAL0:
/* case ATM_AAL1: when we have a decode AAL1 function... */
{
struct sk_buff *tmp = dev_alloc_skb (vcc->mtu);
if (tmp) { if (!(vcc = udsl_find_vcc (instance, vpi, vci)))
memcpy (tmp->tail, cell_payload, 48); dbg ("udsl_decode_rawcell: no vcc found for packet on vpi %d, vci %d", vpi, vci);
skb_put (tmp, 48); else {
dbg ("udsl_decode_rawcell found vcc %p for packet on vpi %d, vci %d", vcc, vpi, vci);
if (vcc->stats) if (skb->len >= 53) {
atomic_inc (&vcc->stats->rx); cell_payload = cell + 5;
skb_pull (skb,
(vcc->
flags & ATMSAR_USE_53BYTE_CELL ? 53 :
52));
dbg
("atmsar_decode_rawcell returns ATM_AAL0 pdu 0x%p with length %d",
tmp, tmp->len);
return tmp;
};
}
break;
case ATM_AAL1:
case ATM_AAL2:
case ATM_AAL34:
/* not supported */
break;
case ATM_AAL5:
if (!vcc->reasBuffer) if (!vcc->reasBuffer)
vcc->reasBuffer = dev_alloc_skb (vcc->mtu); vcc->reasBuffer = dev_alloc_skb (vcc->mtu);
...@@ -347,43 +308,36 @@ struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_b ...@@ -347,43 +308,36 @@ struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_b
/* the aal5 buffer ends here, cut the buffer. */ /* the aal5 buffer ends here, cut the buffer. */
/* buffer will always have at least one whole cell, so */ /* buffer will always have at least one whole cell, so */
/* don't need to check return from skb_pull */ /* don't need to check return from skb_pull */
skb_pull (skb, skb_pull (skb, 53);
(vcc->
flags & ATMSAR_USE_53BYTE_CELL ? 53 :
52));
*ctx = vcc; *ctx = vcc;
tmp = vcc->reasBuffer; tmp = vcc->reasBuffer;
vcc->reasBuffer = NULL; vcc->reasBuffer = NULL;
dbg dbg ("udsl_decode_rawcell returns ATM_AAL5 pdu 0x%p with length %d", tmp, tmp->len);
("atmsar_decode_rawcell returns ATM_AAL5 pdu 0x%p with length %d",
tmp, tmp->len);
return tmp; return tmp;
} }
} }
break;
};
/* flush the cell */ /* flush the cell */
/* buffer will always contain at least one whole cell, so don't */ /* buffer will always contain at least one whole cell, so don't */
/* need to check return value from skb_pull */ /* need to check return value from skb_pull */
skb_pull (skb, (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)); skb_pull (skb, 53);
} else { } else {
/* If data is corrupt and skb doesn't hold a whole cell, flush the lot */ /* If data is corrupt and skb doesn't hold a whole cell, flush the lot */
if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) == if (skb_pull (skb, 53) == NULL)
NULL)
return NULL; return NULL;
} }
} }
}
return NULL; return NULL;
}; }
struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb) static struct sk_buff *udsl_decode_aal5 (struct udsl_vcc_data *ctx, struct sk_buff *skb)
{ {
uint crc = 0xffffffff; uint crc = 0xffffffff;
uint length, pdu_crc, pdu_length; uint length, pdu_crc, pdu_length;
dbg ("atmsar_decode_aal5 (0x%p, 0x%p) called", ctx, skb); dbg ("udsl_decode_aal5 (0x%p, 0x%p) called", ctx, skb);
if (skb->len && (skb->len % 48)) if (skb->len && (skb->len % 48))
return NULL; return NULL;
...@@ -393,20 +347,18 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff ...@@ -393,20 +347,18 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff
(skb->tail[-4] << 24) + (skb->tail[-3] << 16) + (skb->tail[-2] << 8) + skb->tail[-1]; (skb->tail[-4] << 24) + (skb->tail[-3] << 16) + (skb->tail[-2] << 8) + skb->tail[-1];
pdu_length = ((length + 47 + 8) / 48) * 48; pdu_length = ((length + 47 + 8) / 48) * 48;
dbg ("atmsar_decode_aal5: skb->len = %d, length = %d, pdu_crc = 0x%x, pdu_length = %d", dbg ("udsl_decode_aal5: skb->len = %d, length = %d, pdu_crc = 0x%x, pdu_length = %d", skb->len, length, pdu_crc, pdu_length);
skb->len, length, pdu_crc, pdu_length);
/* is skb long enough ? */ /* is skb long enough ? */
if (skb->len < pdu_length) { if (skb->len < pdu_length) {
if (ctx->stats) if (ctx->vcc->stats)
atomic_inc (&ctx->stats->rx_err); atomic_inc (&ctx->vcc->stats->rx_err);
return NULL; return NULL;
} }
/* is skb too long ? */ /* is skb too long ? */
if (skb->len > pdu_length) { if (skb->len > pdu_length) {
dbg ("atmsar_decode_aal5: Warning: readjusting illeagl size %d -> %d", dbg ("udsl_decode_aal5: Warning: readjusting illegal size %d -> %d", skb->len, pdu_length);
skb->len, pdu_length);
/* buffer is too long. we can try to recover /* buffer is too long. we can try to recover
* if we discard the first part of the skb. * if we discard the first part of the skb.
* the crc will decide whether this was ok * the crc will decide whether this was ok
...@@ -418,9 +370,9 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff ...@@ -418,9 +370,9 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff
/* check crc */ /* check crc */
if (pdu_crc != crc) { if (pdu_crc != crc) {
dbg ("atmsar_decode_aal5: crc check failed!"); dbg ("udsl_decode_aal5: crc check failed!");
if (ctx->stats) if (ctx->vcc->stats)
atomic_inc (&ctx->stats->rx_err); atomic_inc (&ctx->vcc->stats->rx_err);
return NULL; return NULL;
} }
...@@ -428,19 +380,20 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff ...@@ -428,19 +380,20 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff
skb_trim (skb, length); skb_trim (skb, length);
/* update stats */ /* update stats */
if (ctx->stats) if (ctx->vcc->stats)
atomic_inc (&ctx->stats->rx); atomic_inc (&ctx->vcc->stats->rx);
dbg ("atmsar_decode_aal5 returns pdu 0x%p with length %d", skb, skb->len); dbg ("udsl_decode_aal5 returns pdu 0x%p with length %d", skb, skb->len);
return skb; return skb;
}; }
/************* /*************
** encode ** ** encode **
*************/ *************/
static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb) { static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb)
{
struct udsl_control *ctrl = UDSL_SKB (skb); struct udsl_control *ctrl = UDSL_SKB (skb);
unsigned int i, zero_padding; unsigned int i, zero_padding;
unsigned char zero = 0; unsigned char zero = 0;
...@@ -480,7 +433,8 @@ static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb) { ...@@ -480,7 +433,8 @@ static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb) {
ctrl->aal5_trailer [7] = crc; ctrl->aal5_trailer [7] = crc;
} }
unsigned int udsl_write_cells (unsigned int howmany, struct sk_buff *skb, unsigned char **target_p) { static unsigned int udsl_write_cells (unsigned int howmany, struct sk_buff *skb, unsigned char **target_p)
{
struct udsl_control *ctrl = UDSL_SKB (skb); struct udsl_control *ctrl = UDSL_SKB (skb);
unsigned char *target = *target_p; unsigned char *target = *target_p;
unsigned int nc, ne, i; unsigned int nc, ne, i;
...@@ -569,7 +523,7 @@ static void udsl_process_receive (unsigned long data) ...@@ -569,7 +523,7 @@ static void udsl_process_receive (unsigned long data)
unsigned char *data_start; unsigned char *data_start;
struct sk_buff *skb; struct sk_buff *skb;
struct urb *urb; struct urb *urb;
struct atmsar_vcc_data *atmsar_vcc = NULL; struct udsl_vcc_data *atmsar_vcc = NULL;
struct sk_buff *new = NULL, *tmp = NULL; struct sk_buff *new = NULL, *tmp = NULL;
int err; int err;
...@@ -597,15 +551,11 @@ static void udsl_process_receive (unsigned long data) ...@@ -597,15 +551,11 @@ static void udsl_process_receive (unsigned long data)
dbg ("skb->len = %d", skb->len); dbg ("skb->len = %d", skb->len);
PACKETDEBUG (skb->data, skb->len); PACKETDEBUG (skb->data, skb->len);
while ((new = while ((new = udsl_decode_rawcell (instance, skb, &atmsar_vcc))) {
atmsar_decode_rawcell (instance->atmsar_vcc_list, skb,
&atmsar_vcc)) != NULL) {
dbg ("(after cell processing)skb->len = %d", new->len); dbg ("(after cell processing)skb->len = %d", new->len);
switch (atmsar_vcc->type) {
case ATM_AAL5:
tmp = new; tmp = new;
new = atmsar_decode_aal5 (atmsar_vcc, new); new = udsl_decode_aal5 (atmsar_vcc, new);
/* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */ /* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */
if (new) { if (new) {
...@@ -621,17 +571,9 @@ static void udsl_process_receive (unsigned long data) ...@@ -621,17 +571,9 @@ static void udsl_process_receive (unsigned long data)
dev_kfree_skb (new); dev_kfree_skb (new);
} }
} else { } else {
dbg ("atmsar_decode_aal5 returned NULL!"); dbg ("udsl_decode_aal5 returned NULL!");
dev_kfree_skb (tmp); dev_kfree_skb (tmp);
} }
break;
default:
/* not supported. we delete the skb. */
printk (KERN_INFO
"SpeedTouch USB: illegal vcc type. Dropping packet.\n");
dev_kfree_skb (new);
break;
}
} }
/* restore skb */ /* restore skb */
...@@ -901,95 +843,6 @@ static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb) ...@@ -901,95 +843,6 @@ static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
** ATM ** ** ATM **
**********/ **********/
#define ATMSAR_DEF_MTU_AAL0 48
#define ATMSAR_DEF_MTU_AAL1 47
#define ATMSAR_DEF_MTU_AAL2 0 /* not supported */
#define ATMSAR_DEF_MTU_AAL34 0 /* not supported */
#define ATMSAR_DEF_MTU_AAL5 65535 /* max mtu .. */
struct atmsar_vcc_data *atmsar_open (struct atmsar_vcc_data **list, struct atm_vcc *vcc, uint type,
ushort vpi, ushort vci, unchar pti, unchar gfc, uint flags)
{
struct atmsar_vcc_data *new;
if (!vcc)
return NULL;
new = kmalloc (sizeof (struct atmsar_vcc_data), GFP_KERNEL);
if (!new)
return NULL;
memset (new, 0, sizeof (struct atmsar_vcc_data));
new->vcc = vcc;
new->stats = vcc->stats;
new->type = type;
new->next = NULL;
new->gfc = gfc;
new->vp = vpi;
new->vc = vci;
new->pti = pti;
switch (type) {
case ATM_AAL0:
new->mtu = ATMSAR_DEF_MTU_AAL0;
break;
case ATM_AAL1:
new->mtu = ATMSAR_DEF_MTU_AAL1;
break;
case ATM_AAL2:
new->mtu = ATMSAR_DEF_MTU_AAL2;
break;
case ATM_AAL34:
/* not supported */
new->mtu = ATMSAR_DEF_MTU_AAL34;
break;
case ATM_AAL5:
new->mtu = ATMSAR_DEF_MTU_AAL5;
break;
}
new->atmHeader = ((unsigned long) gfc << ATM_HDR_GFC_SHIFT)
| ((unsigned long) vpi << ATM_HDR_VPI_SHIFT)
| ((unsigned long) vci << ATM_HDR_VCI_SHIFT)
| ((unsigned long) pti << ATM_HDR_PTI_SHIFT);
new->flags = flags;
new->next = NULL;
new->reasBuffer = NULL;
new->next = *list;
*list = new;
dbg ("Allocated new SARLib vcc 0x%p with vp %d vc %d", new, vpi, vci);
return new;
}
void atmsar_close (struct atmsar_vcc_data **list, struct atmsar_vcc_data *vcc)
{
struct atmsar_vcc_data *work;
if (*list == vcc) {
*list = (*list)->next;
} else {
for (work = *list; work && work->next && (work->next != vcc); work = work->next);
/* return if not found */
if (work->next != vcc)
return;
work->next = work->next->next;
}
if (vcc->reasBuffer) {
dev_kfree_skb (vcc->reasBuffer);
}
dbg ("Allocated SARLib vcc 0x%p with vp %d vc %d", vcc, vcc->vp, vcc->vc);
kfree (vcc);
}
static void udsl_atm_dev_close (struct atm_dev *dev) static void udsl_atm_dev_close (struct atm_dev *dev)
{ {
struct udsl_instance_data *instance = dev->dev_data; struct udsl_instance_data *instance = dev->dev_data;
...@@ -1061,11 +914,10 @@ static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page) ...@@ -1061,11 +914,10 @@ static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page)
return 0; return 0;
} }
#define ATMSAR_SET_PTI 0x2L
static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
{ {
struct udsl_instance_data *instance = vcc->dev->dev_data; struct udsl_instance_data *instance = vcc->dev->dev_data;
struct udsl_vcc_data *new;
dbg ("udsl_atm_open called"); dbg ("udsl_atm_open called");
...@@ -1074,63 +926,97 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -1074,63 +926,97 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
return -ENODEV; return -ENODEV;
} }
/* at the moment only AAL5 support */ if ((vpi == ATM_VPI_ANY) || (vci == ATM_VCI_ANY))
return -EINVAL;
/* only support AAL5 */
if (vcc->qos.aal != ATM_AAL5) if (vcc->qos.aal != ATM_AAL5)
return -EINVAL; return -EINVAL;
MOD_INC_USE_COUNT; down (&instance->serialize); /* vs self, udsl_atm_close */
vcc->dev_data = if (udsl_find_vcc (instance, vpi, vci)) {
atmsar_open (&(instance->atmsar_vcc_list), vcc, ATM_AAL5, vpi, vci, 0, 0, up (&instance->serialize);
ATMSAR_USE_53BYTE_CELL | ATMSAR_SET_PTI); return -EADDRINUSE;
if (!vcc->dev_data) { }
MOD_DEC_USE_COUNT;
return -ENOMEM; /* this is the only reason atmsar_open can fail... */ if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) {
up (&instance->serialize);
return -ENOMEM;
} }
memset (new, 0, sizeof (struct udsl_vcc_data));
new->vcc = vcc;
new->vpi = vpi;
new->vci = vci;
new->mtu = UDSL_MAX_AAL5_MRU;
vcc->dev_data = new;
vcc->vpi = vpi; vcc->vpi = vpi;
vcc->vci = vci; vcc->vci = vci;
tasklet_disable (&instance->receive_tasklet);
list_add (&new->list, &instance->vcc_list);
tasklet_enable (&instance->receive_tasklet);
set_bit (ATM_VF_ADDR, &vcc->flags); set_bit (ATM_VF_ADDR, &vcc->flags);
set_bit (ATM_VF_PARTIAL, &vcc->flags); set_bit (ATM_VF_PARTIAL, &vcc->flags);
set_bit (ATM_VF_READY, &vcc->flags); set_bit (ATM_VF_READY, &vcc->flags);
((struct atmsar_vcc_data *)vcc->dev_data)->mtu = UDSL_MAX_AAL5_MRU; up (&instance->serialize);
dbg ("Allocated new SARLib vcc 0x%p with vpi %d vci %d", new, vpi, vci);
MOD_INC_USE_COUNT;
if (instance->firmware_loaded) if (instance->firmware_loaded)
udsl_fire_receivers (instance); udsl_fire_receivers (instance);
dbg ("udsl_atm_open successful"); dbg ("udsl_atm_open successful");
return 0; return 0;
} }
static void udsl_atm_close (struct atm_vcc *vcc) static void udsl_atm_close (struct atm_vcc *vcc)
{ {
struct udsl_instance_data *instance = vcc->dev->dev_data; struct udsl_instance_data *instance = vcc->dev->dev_data;
struct udsl_vcc_data *vcc_data = vcc->dev_data;
dbg ("udsl_atm_close called"); dbg ("udsl_atm_close called");
if (!instance) { if (!instance || !vcc_data) {
dbg ("NULL instance!"); dbg ("NULL data!");
return; return;
} }
/* freeing resources */ dbg ("Deallocating SARLib vcc 0x%p with vpi %d vci %d", vcc_data, vcc_data->vpi, vcc_data->vci);
/* cancel all sends on this vcc */
udsl_cancel_send (instance, vcc); udsl_cancel_send (instance, vcc);
atmsar_close (&(instance->atmsar_vcc_list), vcc->dev_data); down (&instance->serialize); /* vs self, udsl_atm_open */
tasklet_disable (&instance->receive_tasklet);
list_del (&vcc_data->list);
tasklet_enable (&instance->receive_tasklet);
if (vcc_data->reasBuffer)
kfree_skb (vcc_data->reasBuffer);
vcc_data->reasBuffer = NULL;
kfree (vcc_data);
vcc->dev_data = NULL; vcc->dev_data = NULL;
clear_bit (ATM_VF_PARTIAL, &vcc->flags);
/* freeing address */
vcc->vpi = ATM_VPI_UNSPEC; vcc->vpi = ATM_VPI_UNSPEC;
vcc->vci = ATM_VCI_UNSPEC; vcc->vci = ATM_VCI_UNSPEC;
clear_bit (ATM_VF_READY, &vcc->flags);
clear_bit (ATM_VF_PARTIAL, &vcc->flags);
clear_bit (ATM_VF_ADDR, &vcc->flags); clear_bit (ATM_VF_ADDR, &vcc->flags);
up (&instance->serialize);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
dbg ("udsl_atm_close successful"); dbg ("udsl_atm_close successful");
return;
} }
static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg) static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
...@@ -1209,6 +1095,8 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -1209,6 +1095,8 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
instance->usb_dev = dev; instance->usb_dev = dev;
INIT_LIST_HEAD (&instance->vcc_list);
spin_lock_init (&instance->spare_receivers_lock); spin_lock_init (&instance->spare_receivers_lock);
INIT_LIST_HEAD (&instance->spare_receivers); INIT_LIST_HEAD (&instance->spare_receivers);
......
...@@ -881,6 +881,8 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async) ...@@ -881,6 +881,8 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async)
init_completion (&completion); init_completion (&completion);
urb = simple_alloc_urb (testdev_to_usbdev (dev), pipe, size); urb = simple_alloc_urb (testdev_to_usbdev (dev), pipe, size);
if (!urb)
return -ENOMEM;
if (async) if (async)
urb->transfer_flags |= URB_ASYNC_UNLINK; urb->transfer_flags |= URB_ASYNC_UNLINK;
urb->context = &completion; urb->context = &completion;
...@@ -1407,6 +1409,11 @@ static struct usb_device_id id_table [] = { ...@@ -1407,6 +1409,11 @@ static struct usb_device_id id_table [] = {
.driver_info = (unsigned long) &fw_info, .driver_info = (unsigned long) &fw_info,
}, },
/* "Gadget Zero" firmware runs under Linux */
{ USB_DEVICE (0x0525, 0xa4a0),
.driver_info = (unsigned long) &fw_info,
},
#ifdef KEYSPAN_19Qi #ifdef KEYSPAN_19Qi
/* Keyspan 19qi uses an21xx (original EZ-USB) */ /* Keyspan 19qi uses an21xx (original EZ-USB) */
// this does not coexist with the real Keyspan 19qi driver! // this does not coexist with the real Keyspan 19qi driver!
......
...@@ -269,22 +269,8 @@ static void CDCEther_tx_timeout( struct net_device *net ) ...@@ -269,22 +269,8 @@ static void CDCEther_tx_timeout( struct net_device *net )
static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net ) static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net )
{ {
ether_dev_t *ether_dev = net->priv; ether_dev_t *ether_dev = net->priv;
int count;
int res; int res;
// If we are told to transmit an ethernet frame that fits EXACTLY
// into an integer number of USB packets, we force it to send one
// more byte so the device will get a runt USB packet signalling the
// end of the ethernet frame
if ( (skb->len) ^ (ether_dev->data_ep_out_size) ) {
// It was not an exact multiple
// no need to add anything extra
count = skb->len;
} else {
// Add one to make it NOT an exact multiple
count = skb->len + 1;
}
// Tell the kernel, "No more frames 'til we are done // Tell the kernel, "No more frames 'til we are done
// with this one.' // with this one.'
netif_stop_queue( net ); netif_stop_queue( net );
...@@ -299,7 +285,10 @@ static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net ) ...@@ -299,7 +285,10 @@ static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net )
write_bulk_callback, ether_dev ); write_bulk_callback, ether_dev );
// Tell the URB how much it will be transporting today // Tell the URB how much it will be transporting today
ether_dev->tx_urb->transfer_buffer_length = count; ether_dev->tx_urb->transfer_buffer_length = skb->len;
/* Deal with the zero length problem, I hope */
ether_dev->tx_urb->transfer_flags |= URB_ZERO_PACKET;
// Send the URB on its merry way. // Send the URB on its merry way.
if ((res = usb_submit_urb(ether_dev->tx_urb, GFP_ATOMIC))) { if ((res = usb_submit_urb(ether_dev->tx_urb, GFP_ATOMIC))) {
......
...@@ -406,8 +406,6 @@ static int kobil_write (struct usb_serial_port *port, int from_user, ...@@ -406,8 +406,6 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
int result = 0; int result = 0;
int todo = 0; int todo = 0;
struct kobil_private * priv; struct kobil_private * priv;
int i;
char *data;
if (count == 0) { if (count == 0) {
dbg("%s - port %d write request of 0 bytes", __FUNCTION__, port->number); dbg("%s - port %d write request of 0 bytes", __FUNCTION__, port->number);
...@@ -421,19 +419,6 @@ static int kobil_write (struct usb_serial_port *port, int from_user, ...@@ -421,19 +419,6 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
return -ENOMEM; return -ENOMEM;
} }
// BEGIN DEBUG
data = (unsigned char *) kmalloc((3 * count + 10) * sizeof(char), GFP_KERNEL);
if (! data) {
return (-1);
}
memset(data, 0, (3 * count + 10));
for (i = 0; i < count; i++) {
sprintf(data +3*i, "%02X ", buf[i]);
}
dbg(" %d --> %s", port->number, data );
kfree(data);
// END DEBUG
// Copy data to buffer // Copy data to buffer
if (from_user) { if (from_user) {
if (copy_from_user(priv->buf + priv->filled, buf, count)) { if (copy_from_user(priv->buf + priv->filled, buf, count)) {
...@@ -443,6 +428,8 @@ static int kobil_write (struct usb_serial_port *port, int from_user, ...@@ -443,6 +428,8 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
memcpy (priv->buf + priv->filled, buf, count); memcpy (priv->buf + priv->filled, buf, count);
} }
usb_serial_debug_data (__FILE__, __FUNCTION__, count, priv->buf + priv->filled);
priv->filled = priv->filled + count; priv->filled = priv->filled + count;
......
...@@ -405,11 +405,14 @@ static int isd200_action( struct us_data *us, int action, ...@@ -405,11 +405,14 @@ static int isd200_action( struct us_data *us, int action,
{ {
union ata_cdb ata; union ata_cdb ata;
struct scsi_cmnd srb; struct scsi_cmnd srb;
struct scsi_device srb_dev;
struct isd200_info *info = (struct isd200_info *)us->extra; struct isd200_info *info = (struct isd200_info *)us->extra;
int status; int status;
memset(&ata, 0, sizeof(ata)); memset(&ata, 0, sizeof(ata));
memset(&srb, 0, sizeof(srb)); memset(&srb, 0, sizeof(srb));
memset(&srb_dev, 0, sizeof(srb_dev));
srb.device = &srb_dev;
ata.generic.SignatureByte0 = info->ConfigData.ATAMajorCommand; ata.generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
ata.generic.SignatureByte1 = info->ConfigData.ATAMinorCommand; ata.generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
...@@ -479,6 +482,7 @@ static int isd200_action( struct us_data *us, int action, ...@@ -479,6 +482,7 @@ static int isd200_action( struct us_data *us, int action,
} }
memcpy(srb.cmnd, &ata, sizeof(ata.generic)); memcpy(srb.cmnd, &ata, sizeof(ata.generic));
srb.cmd_len = sizeof(ata.generic);
status = usb_stor_Bulk_transport(&srb, us); status = usb_stor_Bulk_transport(&srb, us);
if (status == USB_STOR_TRANSPORT_GOOD) if (status == USB_STOR_TRANSPORT_GOOD)
status = ISD200_GOOD; status = ISD200_GOOD;
...@@ -538,6 +542,7 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -538,6 +542,7 @@ void isd200_invoke_transport( struct us_data *us,
/* send the command to the transport layer */ /* send the command to the transport layer */
srb->resid = 0; srb->resid = 0;
memcpy(srb->cmnd, ataCdb, sizeof(ataCdb->generic)); memcpy(srb->cmnd, ataCdb, sizeof(ataCdb->generic));
srb->cmd_len = sizeof(ataCdb->generic);
transferStatus = usb_stor_Bulk_transport(srb, us); transferStatus = usb_stor_Bulk_transport(srb, us);
/* if the command gets aborted by the higher layers, we need to /* if the command gets aborted by the higher layers, we need to
......
...@@ -209,21 +209,14 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb ) ...@@ -209,21 +209,14 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb )
return result; return result;
} }
/* This resets the device port, and simulates the device /* This resets the device port */
* disconnect/reconnect for all drivers which have claimed /* It refuses to work if there's more than one interface in
* interfaces, including ourself. */ this device, so that other users are not affected. */
/* This is always called with scsi_lock(srb->host) held */ /* This is always called with scsi_lock(srb->host) held */
/* FIXME: This needs to be re-examined in the face of the new
* hotplug system -- this will implicitly cause a detach/reattach of
* usb-storage, which is not what we want now.
*
* Can we just skip over usb-storage in the while loop?
*/
static int usb_storage_bus_reset( Scsi_Cmnd *srb ) static int usb_storage_bus_reset( Scsi_Cmnd *srb )
{ {
struct us_data *us; struct us_data *us;
int i;
int result; int result;
/* we use the usb_reset_device() function to handle this for us */ /* we use the usb_reset_device() function to handle this for us */
...@@ -231,36 +224,25 @@ static int usb_storage_bus_reset( Scsi_Cmnd *srb ) ...@@ -231,36 +224,25 @@ static int usb_storage_bus_reset( Scsi_Cmnd *srb )
scsi_unlock(srb->device->host); scsi_unlock(srb->device->host);
us = (struct us_data *)srb->device->host->hostdata[0]; us = (struct us_data *)srb->device->host->hostdata[0];
/* The USB subsystem doesn't handle synchronisation between
a device's several drivers. Therefore we reset only devices
with one interface which we of course own.
*/
//FIXME: needs locking against config changes
if ( us->pusb_dev->actconfig->desc.bNumInterfaces == 1) {
/* attempt to reset the port */ /* attempt to reset the port */
result = usb_reset_device(us->pusb_dev); result = usb_reset_device(us->pusb_dev);
US_DEBUGP("usb_reset_device returns %d\n", result); US_DEBUGP("usb_reset_device returns %d\n", result);
if (result < 0) { } else {
scsi_lock(srb->device->host); result = -EBUSY;
return FAILED; US_DEBUGP("cannot reset a multiinterface device. failing to reset.\n");
} }
/* FIXME: This needs to lock out driver probing while it's working
* or we can have race conditions */
/* This functionality really should be provided by the khubd thread */
for (i = 0; i < us->pusb_dev->actconfig->desc.bNumInterfaces; i++) {
struct usb_interface *intf =
&us->pusb_dev->actconfig->interface[i];
/* if this is an unclaimed interface, skip it */
if (!intf->driver) {
continue;
}
US_DEBUGP("Examining driver %s...", intf->driver->name);
/* simulate a disconnect and reconnect for all interfaces */
US_DEBUGPX("simulating disconnect/reconnect.\n");
usb_device_remove (&intf->dev);
usb_device_probe (&intf->dev);
}
US_DEBUGP("bus_reset() complete\n"); US_DEBUGP("bus_reset() complete\n");
scsi_lock(srb->device->host); scsi_lock(srb->device->host);
return SUCCESS; return result < 0 ? FAILED : SUCCESS;
} }
/*********************************************************************** /***********************************************************************
......
...@@ -126,6 +126,7 @@ static int usb_stor_msg_common(struct us_data *us) ...@@ -126,6 +126,7 @@ static int usb_stor_msg_common(struct us_data *us)
us->current_urb->actual_length = 0; us->current_urb->actual_length = 0;
us->current_urb->error_count = 0; us->current_urb->error_count = 0;
us->current_urb->transfer_flags = URB_ASYNC_UNLINK; us->current_urb->transfer_flags = URB_ASYNC_UNLINK;
us->current_urb->status = 0;
/* submit the URB */ /* submit the URB */
status = usb_submit_urb(us->current_urb, GFP_NOIO); status = usb_submit_urb(us->current_urb, GFP_NOIO);
...@@ -900,7 +901,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -900,7 +901,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
bcb.DataTransferLength = cpu_to_le32(transfer_length); bcb.DataTransferLength = cpu_to_le32(transfer_length);
bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0; bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
bcb.Tag = srb->serial_number; bcb.Tag = srb->serial_number;
bcb.Lun = srb->cmnd[1] >> 5; bcb.Lun = srb->device->lun;
if (us->flags & US_FL_SCM_MULT_TARG) if (us->flags & US_FL_SCM_MULT_TARG)
bcb.Lun |= srb->device->id << 4; bcb.Lun |= srb->device->id << 4;
bcb.Length = srb->cmd_len; bcb.Length = srb->cmd_len;
......
...@@ -360,7 +360,7 @@ static int usb_stor_control_thread(void * __us) ...@@ -360,7 +360,7 @@ static int usb_stor_control_thread(void * __us)
} }
else if (us->srb->device->lun > us->max_lun) { else if (us->srb->device->lun > us->max_lun) {
US_DEBUGP("Bad LUN (%d/%d)\n", US_DEBUGP("Bad LUN (%d:%d)\n",
us->srb->device->id, us->srb->device->lun); us->srb->device->id, us->srb->device->lun);
us->srb->result = DID_BAD_TARGET << 16; us->srb->result = DID_BAD_TARGET << 16;
} }
...@@ -475,8 +475,6 @@ static int usb_stor_allocate_urbs(struct us_data *ss) ...@@ -475,8 +475,6 @@ static int usb_stor_allocate_urbs(struct us_data *ss)
*/ */
static void usb_stor_deallocate_urbs(struct us_data *ss) static void usb_stor_deallocate_urbs(struct us_data *ss)
{ {
int result;
/* free the scatter-gather request block */ /* free the scatter-gather request block */
if (ss->current_sg) { if (ss->current_sg) {
kfree(ss->current_sg); kfree(ss->current_sg);
...@@ -486,8 +484,6 @@ static void usb_stor_deallocate_urbs(struct us_data *ss) ...@@ -486,8 +484,6 @@ static void usb_stor_deallocate_urbs(struct us_data *ss)
/* free up the main URB for this device */ /* free up the main URB for this device */
if (ss->current_urb) { if (ss->current_urb) {
US_DEBUGP("-- releasing main URB\n"); US_DEBUGP("-- releasing main URB\n");
result = usb_unlink_urb(ss->current_urb);
US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);
usb_free_urb(ss->current_urb); usb_free_urb(ss->current_urb);
ss->current_urb = NULL; ss->current_urb = NULL;
} }
......
...@@ -72,13 +72,15 @@ MODULE_PARM(debug, "i"); ...@@ -72,13 +72,15 @@ MODULE_PARM(debug, "i");
MODULE_PARM_DESC(debug, "Debug enabled or not"); MODULE_PARM_DESC(debug, "Debug enabled or not");
/* Define these values to match your device */ /* Define these values to match your devices */
#define USB_SKEL_VENDOR_ID 0xfff0 #define USB_SKEL_VENDOR_ID 0xfff0
#define USB_SKEL_PRODUCT_ID 0xfff0 #define USB_SKEL_PRODUCT_ID 0xfff0
/* table of devices that work with this driver */ /* table of devices that work with this driver */
static struct usb_device_id skel_table [] = { static struct usb_device_id skel_table [] = {
{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
/* "Gadget Zero" firmware runs under Linux */
{ USB_DEVICE(0x0525, 0xa4a0) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
...@@ -707,7 +709,7 @@ static int __init usb_skel_init(void) ...@@ -707,7 +709,7 @@ static int __init usb_skel_init(void)
/* register this driver with the USB subsystem */ /* register this driver with the USB subsystem */
result = usb_register(&skel_driver); result = usb_register(&skel_driver);
if (result < 0) { if (result < 0) {
err("usb_register failed for the "__FILE__" driver. Error number %d", err("usb_register failed. Error number %d",
result); result);
return -1; return -1;
} }
......
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