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

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

into kroah.com:/home/greg/linux/BK/usb-2.6
parents 7b51a623 86cfdf3a
...@@ -2239,8 +2239,8 @@ W: http://www.linux-usb.org ...@@ -2239,8 +2239,8 @@ W: http://www.linux-usb.org
S: Supported S: Supported
USB UHCI DRIVER USB UHCI DRIVER
P: Johannes Erdfelt P: Alan Stern
M: johannes@erdfelt.com M: stern@rowland.harvard.edu
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
......
...@@ -204,12 +204,23 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, ...@@ -204,12 +204,23 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
int *result_length, u8 cmd_result[]) int *result_length, u8 cmd_result[])
{ {
int result, actual_len, i; int result, actual_len, i;
u8 b[COMMAND_PACKET_SIZE + 4]; u8 *b;
u8 c[COMMAND_PACKET_SIZE + 4]; u8 *c;
b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
if (!b)
return -ENOMEM;
c = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
if (!c) {
kfree(b);
return -ENOMEM;
}
dprintk("%s\n", __FUNCTION__); dprintk("%s\n", __FUNCTION__);
if ((result = down_interruptible(&dec->usb_sem))) { if ((result = down_interruptible(&dec->usb_sem))) {
kfree(b);
kfree(c);
printk("%s: Failed to down usb semaphore.\n", __FUNCTION__); printk("%s: Failed to down usb semaphore.\n", __FUNCTION__);
return result; return result;
} }
...@@ -230,22 +241,26 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, ...@@ -230,22 +241,26 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
} }
result = usb_bulk_msg(dec->udev, dec->command_pipe, b, result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
sizeof(b), &actual_len, HZ); COMMAND_PACKET_SIZE + 4, &actual_len, HZ);
if (result) { if (result) {
printk("%s: command bulk message failed: error %d\n", printk("%s: command bulk message failed: error %d\n",
__FUNCTION__, result); __FUNCTION__, result);
up(&dec->usb_sem); up(&dec->usb_sem);
kfree(b);
kfree(c);
return result; return result;
} }
result = usb_bulk_msg(dec->udev, dec->result_pipe, c, result = usb_bulk_msg(dec->udev, dec->result_pipe, c,
sizeof(c), &actual_len, HZ); COMMAND_PACKET_SIZE + 4, &actual_len, HZ);
if (result) { if (result) {
printk("%s: result bulk message failed: error %d\n", printk("%s: result bulk message failed: error %d\n",
__FUNCTION__, result); __FUNCTION__, result);
up(&dec->usb_sem); up(&dec->usb_sem);
kfree(b);
kfree(c);
return result; return result;
} else { } else {
if (debug) { if (debug) {
...@@ -262,6 +277,8 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, ...@@ -262,6 +277,8 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
up(&dec->usb_sem); up(&dec->usb_sem);
kfree(b);
kfree(c);
return 0; return 0;
} }
} }
......
...@@ -46,7 +46,6 @@ obj-$(CONFIG_USB_DC2XX) += image/ ...@@ -46,7 +46,6 @@ obj-$(CONFIG_USB_DC2XX) += image/
obj-$(CONFIG_USB_HPUSBSCSI) += image/ obj-$(CONFIG_USB_HPUSBSCSI) += image/
obj-$(CONFIG_USB_MDC800) += image/ obj-$(CONFIG_USB_MDC800) += image/
obj-$(CONFIG_USB_MICROTEK) += image/ obj-$(CONFIG_USB_MICROTEK) += image/
obj-$(CONFIG_USB_SCANNER) += image/
obj-$(CONFIG_USB_SERIAL) += serial/ obj-$(CONFIG_USB_SERIAL) += serial/
......
...@@ -399,6 +399,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) ...@@ -399,6 +399,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count) static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
{ {
struct acm *acm = tty->driver_data; struct acm *acm = tty->driver_data;
int stat;
if (!ACM_READY(acm)) if (!ACM_READY(acm))
return -EINVAL; return -EINVAL;
...@@ -418,8 +419,12 @@ static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned c ...@@ -418,8 +419,12 @@ static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned c
acm->writeurb->transfer_buffer_length = count; acm->writeurb->transfer_buffer_length = count;
acm->writeurb->dev = acm->dev; acm->writeurb->dev = acm->dev;
if (usb_submit_urb(acm->writeurb, GFP_KERNEL)) /* GFP_KERNEL probably works if from_user */
stat = usb_submit_urb(acm->writeurb, GFP_ATOMIC);
if (stat < 0) {
dbg("usb_submit_urb(write bulk) failed"); dbg("usb_submit_urb(write bulk) failed");
return stat;
}
return count; return count;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for USB Core files and filesystem # Makefile for USB Core files and filesystem
# #
usbcore-objs := usb.o usb-debug.o hub.o hcd.o urb.o message.o \ usbcore-objs := usb.o hub.o hcd.o urb.o message.o \
config.o file.o buffer.o driverfs.o config.o file.o buffer.o driverfs.o
ifeq ($(CONFIG_PCI),y) ifeq ($(CONFIG_PCI),y)
......
...@@ -34,7 +34,10 @@ ...@@ -34,7 +34,10 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/uts.h> /* for UTS_SYSNAME */ #include <linux/uts.h> /* for UTS_SYSNAME */
#include <linux/pci.h> /* for hcd->pdev and dma addressing */ #include <linux/mm.h>
#include <asm/io.h>
#include <asm/scatterlist.h>
#include <linux/device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
...@@ -735,7 +738,7 @@ EXPORT_SYMBOL (usb_deregister_bus); ...@@ -735,7 +738,7 @@ EXPORT_SYMBOL (usb_deregister_bus);
* *
* The USB host controller calls this function to register the root hub * The USB host controller calls this function to register the root hub
* properly with the USB subsystem. It sets up the device properly in * properly with the USB subsystem. It sets up the device properly in
* the driverfs tree, and then calls usb_new_device() to register the * the device model tree, and then calls usb_new_device() to register the
* usb device. It also assigns the root hub's USB address (always 1). * usb device. It also assigns the root hub's USB address (always 1).
*/ */
int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev) int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev)
...@@ -743,14 +746,14 @@ int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev ...@@ -743,14 +746,14 @@ int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev
const int devnum = 1; const int devnum = 1;
int retval; int retval;
sprintf (&usb_dev->dev.bus_id[0], "usb%d", usb_dev->bus->busnum);
usb_dev->state = USB_STATE_DEFAULT;
usb_dev->devnum = devnum; usb_dev->devnum = devnum;
usb_dev->bus->devnum_next = devnum + 1; usb_dev->bus->devnum_next = devnum + 1;
memset (&usb_dev->bus->devmap.devicemap, 0,
sizeof usb_dev->bus->devmap.devicemap);
set_bit (devnum, usb_dev->bus->devmap.devicemap); set_bit (devnum, usb_dev->bus->devmap.devicemap);
usb_dev->state = USB_STATE_ADDRESS;
retval = usb_new_device (usb_dev, parent_dev); retval = usb_new_device (usb_dev);
if (retval) if (retval)
dev_err (parent_dev, "can't register root hub for %s, %d\n", dev_err (parent_dev, "can't register root hub for %s, %d\n",
usb_dev->dev.bus_id, retval); usb_dev->dev.bus_id, retval);
...@@ -1474,16 +1477,16 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs ...@@ -1474,16 +1477,16 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs
if (hcd->controller->dma_mask) { if (hcd->controller->dma_mask) {
if (usb_pipecontrol (urb->pipe) if (usb_pipecontrol (urb->pipe)
&& !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
pci_unmap_single (hcd->pdev, urb->setup_dma, dma_unmap_single (hcd->controller, urb->setup_dma,
sizeof (struct usb_ctrlrequest), sizeof (struct usb_ctrlrequest),
PCI_DMA_TODEVICE); DMA_TO_DEVICE);
if (urb->transfer_buffer_length != 0 if (urb->transfer_buffer_length != 0
&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
pci_unmap_single (hcd->pdev, urb->transfer_dma, dma_unmap_single (hcd->controller, urb->transfer_dma,
urb->transfer_buffer_length, urb->transfer_buffer_length,
usb_pipein (urb->pipe) usb_pipein (urb->pipe)
? PCI_DMA_FROMDEVICE ? DMA_FROM_DEVICE
: PCI_DMA_TODEVICE); : DMA_TO_DEVICE);
} }
/* pass ownership to the completion handler */ /* pass ownership to the completion handler */
...@@ -1513,7 +1516,9 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r) ...@@ -1513,7 +1516,9 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r)
return IRQ_NONE; return IRQ_NONE;
hcd->saw_irq = 1; hcd->saw_irq = 1;
hcd->driver->irq (hcd, r); if (hcd->driver->irq (hcd, r) == IRQ_NONE)
return IRQ_NONE;
if (hcd->state != start && hcd->state == USB_STATE_HALT) if (hcd->state != start && hcd->state == USB_STATE_HALT)
usb_hc_died (hcd); usb_hc_died (hcd);
return IRQ_HANDLED; return IRQ_HANDLED;
......
...@@ -163,7 +163,7 @@ struct hc_driver { ...@@ -163,7 +163,7 @@ struct hc_driver {
const char *description; /* "ehci-hcd" etc */ const char *description; /* "ehci-hcd" etc */
/* irq handler */ /* irq handler */
void (*irq) (struct usb_hcd *hcd, struct pt_regs *regs); irqreturn_t (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
int flags; int flags;
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
...@@ -241,7 +241,9 @@ extern void usb_hc_died (struct usb_hcd *hcd); ...@@ -241,7 +241,9 @@ extern void usb_hc_died (struct usb_hcd *hcd);
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Enumeration is only for the hub driver, or HCD virtual root hubs */ /* Enumeration is only for the hub driver, or HCD virtual root hubs */
extern int usb_new_device(struct usb_device *dev, struct device *parent); extern struct usb_device *usb_alloc_dev(struct usb_device *parent,
struct usb_bus *, unsigned port);
extern int usb_new_device(struct usb_device *dev);
extern void usb_choose_address(struct usb_device *dev); extern void usb_choose_address(struct usb_device *dev);
extern void usb_disconnect(struct usb_device **); extern void usb_disconnect(struct usb_device **);
......
...@@ -179,7 +179,7 @@ static inline int ...@@ -179,7 +179,7 @@ static inline int
hub_clear_tt_buffer (struct usb_device *hub, u16 devinfo, u16 tt) hub_clear_tt_buffer (struct usb_device *hub, u16 devinfo, u16 tt)
{ {
return usb_control_msg (hub, usb_rcvctrlpipe (hub, 0), return usb_control_msg (hub, usb_rcvctrlpipe (hub, 0),
HUB_CLEAR_TT_BUFFER, USB_DIR_IN | USB_RECIP_OTHER, HUB_CLEAR_TT_BUFFER, USB_RT_PORT,
devinfo, tt, 0, 0, HZ); devinfo, tt, 0, 0, HZ);
} }
...@@ -930,11 +930,9 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port, ...@@ -930,11 +930,9 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
down(&usb_address0_sem); down(&usb_address0_sem);
for (i = 0; i < HUB_PROBE_TRIES; i++) { for (i = 0; i < HUB_PROBE_TRIES; i++) {
struct usb_device *pdev;
int len;
/* Allocate a new device struct */ /* Allocate a new device struct */
dev = usb_alloc_dev(hub, hub->bus); dev = usb_alloc_dev(hub, hub->bus, port);
if (!dev) { if (!dev) {
dev_err (&hubstate->intf->dev, dev_err (&hubstate->intf->dev,
"couldn't allocate usb_device\n"); "couldn't allocate usb_device\n");
...@@ -962,38 +960,18 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port, ...@@ -962,38 +960,18 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
dev->ttport = port + 1; dev->ttport = port + 1;
} }
/* Save readable and stable topology id, distinguishing dev_info (&dev->dev,
* devices by location for diagnostics, tools, etc. The "new %s speed USB device using address %d\n",
* string is a path along hub ports, from the root. Each ({ char *speed; switch (dev->speed) {
* device's id will be stable until USB is re-cabled, and case USB_SPEED_LOW: speed = "low"; break;
* hubs are often labeled with these port numbers. case USB_SPEED_FULL: speed = "full"; break;
* case USB_SPEED_HIGH: speed = "high"; break;
* Initial size: ".NN" times five hubs + NUL = 16 bytes max default: speed = "?"; break;
* (quite rare, since most hubs have 4-6 ports). }; speed;}),
*/ dev->devnum);
pdev = dev->parent;
if (pdev->devpath [0] != '0') /* parent not root? */
len = snprintf (dev->devpath, sizeof dev->devpath,
"%s.%d", pdev->devpath, port + 1);
/* root == "0", root port 2 == "2", port 3 that hub "2.3" */
else
len = snprintf (dev->devpath, sizeof dev->devpath,
"%d", port + 1);
if (len == sizeof dev->devpath)
dev_err (&hubstate->intf->dev,
"devpath size! usb/%03d/%03d path %s\n",
dev->bus->busnum, dev->devnum, dev->devpath);
dev_info (&hubstate->intf->dev,
"new USB device on port %d, assigned address %d\n",
port + 1, dev->devnum);
/* put the device in the global device tree. the hub port
* is the "bus_id"; hubs show in hierarchy like bridges
*/
dev->dev.parent = dev->parent->dev.parent->parent;
/* Run it through the hoops (find a driver, etc) */ /* Run it through the hoops (find a driver, etc) */
if (!usb_new_device(dev, &hub->dev)) { if (usb_new_device(dev) == 0) {
hub->children[port] = dev; hub->children[port] = dev;
goto done; goto done;
} }
......
/*
* debug.c - USB debug helper routines.
*
* I just want these out of the way where they aren't in your
* face, but so that you can still use them..
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/usb.h>
static void usb_show_endpoint(struct usb_host_endpoint *endpoint)
{
usb_show_endpoint_descriptor(&endpoint->desc);
}
static void usb_show_interface(struct usb_host_interface *altsetting)
{
int i;
usb_show_interface_descriptor(&altsetting->desc);
for (i = 0; i < altsetting->desc.bNumEndpoints; i++)
usb_show_endpoint(altsetting->endpoint + i);
}
static void usb_show_config(struct usb_host_config *config)
{
int i, j;
struct usb_interface *ifp;
usb_show_config_descriptor(&config->desc);
for (i = 0; i < config->desc.bNumInterfaces; i++) {
ifp = config->interface[i];
if (!ifp)
break;
printk("\n Interface: %d\n", i);
for (j = 0; j < ifp->num_altsetting; j++)
usb_show_interface(ifp->altsetting + j);
}
}
void usb_show_device(struct usb_device *dev)
{
int i;
usb_show_device_descriptor(&dev->descriptor);
for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
usb_show_config(dev->config + i);
}
/*
* Parse and show the different USB descriptors.
*/
void usb_show_device_descriptor(struct usb_device_descriptor *desc)
{
if (!desc)
{
printk("Invalid USB device descriptor (NULL POINTER)\n");
return;
}
printk(" Length = %2d%s\n", desc->bLength,
desc->bLength == USB_DT_DEVICE_SIZE ? "" : " (!!!)");
printk(" DescriptorType = %02x\n", desc->bDescriptorType);
printk(" USB version = %x.%02x\n",
desc->bcdUSB >> 8, desc->bcdUSB & 0xff);
printk(" Vendor:Product = %04x:%04x\n",
desc->idVendor, desc->idProduct);
printk(" MaxPacketSize0 = %d\n", desc->bMaxPacketSize0);
printk(" NumConfigurations = %d\n", desc->bNumConfigurations);
printk(" Device version = %x.%02x\n",
desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
printk(" Device Class:SubClass:Protocol = %02x:%02x:%02x\n",
desc->bDeviceClass, desc->bDeviceSubClass, desc->bDeviceProtocol);
switch (desc->bDeviceClass) {
case 0:
printk(" Per-interface classes\n");
break;
case USB_CLASS_AUDIO:
printk(" Audio device class\n");
break;
case USB_CLASS_COMM:
printk(" Communications class\n");
break;
case USB_CLASS_HID:
printk(" Human Interface Devices class\n");
break;
case USB_CLASS_PRINTER:
printk(" Printer device class\n");
break;
case USB_CLASS_MASS_STORAGE:
printk(" Mass Storage device class\n");
break;
case USB_CLASS_HUB:
printk(" Hub device class\n");
break;
case USB_CLASS_VENDOR_SPEC:
printk(" Vendor class\n");
break;
default:
printk(" Unknown class\n");
}
}
void usb_show_config_descriptor(struct usb_config_descriptor *desc)
{
printk("Configuration:\n");
printk(" bLength = %4d%s\n", desc->bLength,
desc->bLength == USB_DT_CONFIG_SIZE ? "" : " (!!!)");
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" wTotalLength = %04x\n", desc->wTotalLength);
printk(" bNumInterfaces = %02x\n", desc->bNumInterfaces);
printk(" bConfigurationValue = %02x\n", desc->bConfigurationValue);
printk(" iConfiguration = %02x\n", desc->iConfiguration);
printk(" bmAttributes = %02x\n", desc->bmAttributes);
printk(" bMaxPower = %4dmA\n", desc->bMaxPower * 2);
}
void usb_show_interface_descriptor(struct usb_interface_descriptor *desc)
{
printk(" Alternate Setting: %2d\n", desc->bAlternateSetting);
printk(" bLength = %4d%s\n", desc->bLength,
desc->bLength == USB_DT_INTERFACE_SIZE ? "" : " (!!!)");
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" bInterfaceNumber = %02x\n", desc->bInterfaceNumber);
printk(" bAlternateSetting = %02x\n", desc->bAlternateSetting);
printk(" bNumEndpoints = %02x\n", desc->bNumEndpoints);
printk(" bInterface Class:SubClass:Protocol = %02x:%02x:%02x\n",
desc->bInterfaceClass, desc->bInterfaceSubClass, desc->bInterfaceProtocol);
printk(" iInterface = %02x\n", desc->iInterface);
}
void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *desc)
{
char *LengthCommentString = (desc->bLength ==
USB_DT_ENDPOINT_AUDIO_SIZE) ? " (Audio)" : (desc->bLength ==
USB_DT_ENDPOINT_SIZE) ? "" : " (!!!)";
char *EndpointType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" };
printk(" Endpoint:\n");
printk(" bLength = %4d%s\n",
desc->bLength, LengthCommentString);
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" bEndpointAddress = %02x (%s)\n", desc->bEndpointAddress,
(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_CONTROL ? "i/o" :
(desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? "in" : "out");
printk(" bmAttributes = %02x (%s)\n", desc->bmAttributes,
EndpointType[USB_ENDPOINT_XFERTYPE_MASK & desc->bmAttributes]);
printk(" wMaxPacketSize = %04x\n", desc->wMaxPacketSize);
printk(" bInterval = %02x\n", desc->bInterval);
/* Audio extensions to the endpoint descriptor */
if (desc->bLength == USB_DT_ENDPOINT_AUDIO_SIZE) {
printk(" bRefresh = %02x\n", desc->bRefresh);
printk(" bSynchAddress = %02x\n", desc->bSynchAddress);
}
}
void usb_show_string(struct usb_device *dev, char *id, int index)
{
char *buf;
if (!index)
return;
if (!(buf = kmalloc(256, GFP_KERNEL)))
return;
if (usb_string(dev, index, buf, 256) > 0)
dev_printk(KERN_INFO, &dev->dev, "%s: %s\n", id, buf);
kfree(buf);
}
void usb_dump_urb (struct urb *urb)
{
printk ("urb :%p\n", urb);
printk ("dev :%p\n", urb->dev);
printk ("pipe :%08X\n", urb->pipe);
printk ("status :%d\n", urb->status);
printk ("transfer_flags :%08X\n", urb->transfer_flags);
printk ("transfer_buffer :%p\n", urb->transfer_buffer);
printk ("transfer_buffer_length:%d\n", urb->transfer_buffer_length);
printk ("actual_length :%d\n", urb->actual_length);
printk ("setup_packet :%p\n", urb->setup_packet);
printk ("start_frame :%d\n", urb->start_frame);
printk ("number_of_packets :%d\n", urb->number_of_packets);
printk ("interval :%d\n", urb->interval);
printk ("error_count :%d\n", urb->error_count);
printk ("context :%p\n", urb->context);
printk ("complete :%p\n", urb->complete);
}
...@@ -678,17 +678,19 @@ static void usb_release_dev(struct device *dev) ...@@ -678,17 +678,19 @@ static void usb_release_dev(struct device *dev)
} }
/** /**
* usb_alloc_dev - allocate a usb device structure (usbcore-internal) * usb_alloc_dev - usb device constructor (usbcore-internal)
* @parent: hub to which device is connected * @parent: hub to which device is connected; null to allocate a root hub
* @bus: bus used to access the device * @bus: bus used to access the device
* @port: zero based index of port; ignored for root hubs
* Context: !in_interrupt () * Context: !in_interrupt ()
* *
* 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.
* *
* This call is synchronous, and may not be used in an interrupt context. * This call may not be used in a non-sleeping context.
*/ */
struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus) struct usb_device *
usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port)
{ {
struct usb_device *dev; struct usb_device *dev;
...@@ -705,11 +707,42 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus) ...@@ -705,11 +707,42 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus)
} }
device_initialize(&dev->dev); device_initialize(&dev->dev);
dev->dev.bus = &usb_bus_type;
dev->dev.dma_mask = bus->controller->dma_mask;
dev->dev.driver_data = &usb_generic_driver_data;
dev->dev.driver = &usb_generic_driver;
dev->dev.release = usb_release_dev; dev->dev.release = usb_release_dev;
dev->state = USB_STATE_ATTACHED; dev->state = USB_STATE_ATTACHED;
if (!parent) /* Save readable and stable topology id, distinguishing devices
* by location for diagnostics, tools, driver model, etc. The
* string is a path along hub ports, from the root. Each device's
* dev->devpath will be stable until USB is re-cabled, and hubs
* are often labeled with these port numbers. The bus_id isn't
* as stable: bus->busnum changes easily from modprobe order,
* cardbus or pci hotplugging, and so on.
*/
if (unlikely (!parent)) {
dev->devpath [0] = '0'; dev->devpath [0] = '0';
dev->dev.parent = bus->controller;
sprintf (&dev->dev.bus_id[0], "usb%d", bus->busnum);
} else {
/* match any labeling on the hubs; it's one-based */
if (parent->devpath [0] == '0')
snprintf (dev->devpath, sizeof dev->devpath,
"%d", port + 1);
else
snprintf (dev->devpath, sizeof dev->devpath,
"%s.%d", parent->devpath, port + 1);
dev->dev.parent = &parent->dev;
sprintf (&dev->dev.bus_id[0], "%d-%s",
bus->busnum, dev->devpath);
/* hub driver sets up TT records */
}
dev->bus = bus; dev->bus = bus;
dev->parent = parent; dev->parent = parent;
INIT_LIST_HEAD(&dev->filelist); INIT_LIST_HEAD(&dev->filelist);
...@@ -984,6 +1017,19 @@ int usb_set_address(struct usb_device *dev) ...@@ -984,6 +1017,19 @@ int usb_set_address(struct usb_device *dev)
return retval; return retval;
} }
static inline void usb_show_string(struct usb_device *dev, char *id, int index)
{
char *buf;
if (!index)
return;
if (!(buf = kmalloc(256, GFP_KERNEL)))
return;
if (usb_string(dev, index, buf, 256) > 0)
dev_printk(KERN_INFO, &dev->dev, "%s: %s\n", id, buf);
kfree(buf);
}
/* /*
* By the time we get here, we chose a new device address * 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
...@@ -998,33 +1044,13 @@ int usb_set_address(struct usb_device *dev) ...@@ -998,33 +1044,13 @@ int usb_set_address(struct usb_device *dev)
*/ */
#define NEW_DEVICE_RETRYS 2 #define NEW_DEVICE_RETRYS 2
#define SET_ADDRESS_RETRYS 2 #define SET_ADDRESS_RETRYS 2
int usb_new_device(struct usb_device *dev, struct device *parent) int usb_new_device(struct usb_device *dev)
{ {
int err = -EINVAL; int err = -EINVAL;
int i; int i;
int j; int j;
int config; int config;
/*
* Set the driver for the usb device to point to the "generic" driver.
* This prevents the main usb device from being sent to the usb bus
* probe function. Yes, it's a hack, but a nice one :)
*
* Do it asap, so more driver model stuff (like the device.h message
* utilities) can be used in hcd submit/unlink code paths.
*/
usb_generic_driver.bus = &usb_bus_type;
dev->dev.parent = parent;
dev->dev.driver = &usb_generic_driver;
dev->dev.bus = &usb_bus_type;
dev->dev.driver_data = &usb_generic_driver_data;
if (dev->dev.bus_id[0] == 0)
sprintf (&dev->dev.bus_id[0], "%d-%s",
dev->bus->busnum, dev->devpath);
/* dma masks come from the controller; readonly, except to hcd */
dev->dev.dma_mask = parent->dma_mask;
/* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
* it's fixed size except for full speed devices. * it's fixed size except for full speed devices.
*/ */
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
*/ */
#define DEBUG 1 // #define DEBUG 1
// #define VERBOSE // #define VERBOSE
#include <linux/config.h> #include <linux/config.h>
...@@ -885,8 +885,11 @@ set_ether_config (struct eth_dev *dev, int gfp_flags) ...@@ -885,8 +885,11 @@ set_ether_config (struct eth_dev *dev, int gfp_flags)
#ifndef DEV_CONFIG_CDC #ifndef DEV_CONFIG_CDC
if (result == 0) { if (result == 0) {
netif_carrier_on (dev->net); netif_carrier_on (dev->net);
if (netif_running (dev->net)) if (netif_running (dev->net)) {
spin_unlock (&dev->lock);
eth_start (dev, GFP_ATOMIC); eth_start (dev, GFP_ATOMIC);
spin_lock (&dev->lock);
}
} else { } else {
(void) usb_ep_disable (dev->in_ep); (void) usb_ep_disable (dev->in_ep);
dev->in_ep = 0; dev->in_ep = 0;
...@@ -1246,8 +1249,11 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1246,8 +1249,11 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
#ifdef EP_STATUS_NUM #ifdef EP_STATUS_NUM
issue_start_status (dev); issue_start_status (dev);
#endif #endif
if (netif_running (dev->net)) if (netif_running (dev->net)) {
spin_unlock (&dev->lock);
eth_start (dev, GFP_ATOMIC); eth_start (dev, GFP_ATOMIC);
spin_lock (&dev->lock);
}
} else { } else {
netif_stop_queue (dev->net); netif_stop_queue (dev->net);
netif_carrier_off (dev->net); netif_carrier_off (dev->net);
...@@ -1414,16 +1420,14 @@ static int ...@@ -1414,16 +1420,14 @@ static int
rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags) rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags)
{ {
struct sk_buff *skb; struct sk_buff *skb;
int retval = 0; int retval = -ENOMEM;
size_t size; size_t size;
size = (sizeof (struct ethhdr) + dev->net->mtu + RX_EXTRA); size = (sizeof (struct ethhdr) + dev->net->mtu + RX_EXTRA);
if ((skb = alloc_skb (size, gfp_flags)) == 0) { if ((skb = alloc_skb (size, gfp_flags)) == 0) {
DEBUG (dev, "no rx skb\n"); DEBUG (dev, "no rx skb\n");
defer_kevent (dev, WORK_RX_MEMORY); goto enomem;
list_add (&req->list, &dev->rx_reqs);
return -ENOMEM;
} }
req->buf = skb->data; req->buf = skb->data;
...@@ -1433,11 +1437,14 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags) ...@@ -1433,11 +1437,14 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags)
retval = usb_ep_queue (dev->out_ep, req, gfp_flags); retval = usb_ep_queue (dev->out_ep, req, gfp_flags);
if (retval == -ENOMEM) if (retval == -ENOMEM)
enomem:
defer_kevent (dev, WORK_RX_MEMORY); defer_kevent (dev, WORK_RX_MEMORY);
if (retval) { if (retval) {
DEBUG (dev, "rx submit --> %d\n", retval); DEBUG (dev, "rx submit --> %d\n", retval);
dev_kfree_skb_any (skb); dev_kfree_skb_any (skb);
spin_lock (&dev->lock);
list_add (&req->list, &dev->rx_reqs); list_add (&req->list, &dev->rx_reqs);
spin_unlock (&dev->lock);
} }
return retval; return retval;
} }
...@@ -1502,6 +1509,7 @@ static void rx_complete (struct usb_ep *ep, struct usb_request *req) ...@@ -1502,6 +1509,7 @@ static void rx_complete (struct usb_ep *ep, struct usb_request *req)
dev_kfree_skb_any (skb); dev_kfree_skb_any (skb);
if (!netif_running (dev->net)) { if (!netif_running (dev->net)) {
clean: clean:
/* nobody reading rx_reqs, so no dev->lock */
list_add (&req->list, &dev->rx_reqs); list_add (&req->list, &dev->rx_reqs);
req = 0; req = 0;
} }
...@@ -1568,19 +1576,26 @@ static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags) ...@@ -1568,19 +1576,26 @@ static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags)
static void rx_fill (struct eth_dev *dev, int gfp_flags) static void rx_fill (struct eth_dev *dev, int gfp_flags)
{ {
struct usb_request *req; struct usb_request *req;
unsigned long flags;
clear_bit (WORK_RX_MEMORY, &dev->todo); clear_bit (WORK_RX_MEMORY, &dev->todo);
/* fill unused rxq slots with some skb */ /* fill unused rxq slots with some skb */
spin_lock_irqsave (&dev->lock, flags);
while (!list_empty (&dev->rx_reqs)) { while (!list_empty (&dev->rx_reqs)) {
req = container_of (dev->rx_reqs.next, req = container_of (dev->rx_reqs.next,
struct usb_request, list); struct usb_request, list);
list_del_init (&req->list); list_del_init (&req->list);
spin_unlock_irqrestore (&dev->lock, flags);
if (rx_submit (dev, req, gfp_flags) < 0) { if (rx_submit (dev, req, gfp_flags) < 0) {
defer_kevent (dev, WORK_RX_MEMORY); defer_kevent (dev, WORK_RX_MEMORY);
return; return;
} }
spin_lock_irqsave (&dev->lock, flags);
} }
spin_unlock_irqrestore (&dev->lock, flags);
} }
static void eth_work (void *_dev) static void eth_work (void *_dev)
...@@ -1616,7 +1631,9 @@ static void tx_complete (struct usb_ep *ep, struct usb_request *req) ...@@ -1616,7 +1631,9 @@ static void tx_complete (struct usb_ep *ep, struct usb_request *req)
} }
dev->stats.tx_packets++; dev->stats.tx_packets++;
spin_lock (&dev->lock);
list_add (&req->list, &dev->tx_reqs); list_add (&req->list, &dev->tx_reqs);
spin_unlock (&dev->lock);
dev_kfree_skb_any (skb); dev_kfree_skb_any (skb);
atomic_dec (&dev->tx_qlen); atomic_dec (&dev->tx_qlen);
...@@ -1630,11 +1647,14 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) ...@@ -1630,11 +1647,14 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
int length = skb->len; int length = skb->len;
int retval; int retval;
struct usb_request *req = 0; struct usb_request *req = 0;
unsigned long flags;
spin_lock_irqsave (&dev->lock, flags);
req = container_of (dev->tx_reqs.next, struct usb_request, list); req = container_of (dev->tx_reqs.next, struct usb_request, list);
list_del (&req->list); list_del (&req->list);
if (list_empty (&dev->tx_reqs)) if (list_empty (&dev->tx_reqs))
netif_stop_queue (net); netif_stop_queue (net);
spin_unlock_irqrestore (&dev->lock, flags);
/* no buffer copies needed, unless the network stack did it /* no buffer copies needed, unless the network stack did it
* or the hardware can't use skb buffers. * or the hardware can't use skb buffers.
...@@ -1675,9 +1695,11 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) ...@@ -1675,9 +1695,11 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
if (retval) { if (retval) {
dev->stats.tx_dropped++; dev->stats.tx_dropped++;
dev_kfree_skb_any (skb); dev_kfree_skb_any (skb);
spin_lock_irqsave (&dev->lock, flags);
if (list_empty (&dev->tx_reqs)) if (list_empty (&dev->tx_reqs))
netif_start_queue (net); netif_start_queue (net);
list_add (&req->list, &dev->tx_reqs); list_add (&req->list, &dev->tx_reqs);
spin_unlock_irqrestore (&dev->lock, flags);
} }
return 0; return 0;
} }
......
/* /*
* file_storage.c -- File-backed USB Storage Gadget, for USB development * file_storage.c -- File-backed USB Storage Gadget, for USB development
* *
* Copyright (C) 2003 Alan Stern * Copyright (C) 2003, 2004 Alan Stern
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -244,7 +244,7 @@ ...@@ -244,7 +244,7 @@
#define DRIVER_DESC "File-backed Storage Gadget" #define DRIVER_DESC "File-backed Storage Gadget"
#define DRIVER_NAME "g_file_storage" #define DRIVER_NAME "g_file_storage"
#define DRIVER_VERSION "14 January 2004" #define DRIVER_VERSION "26 January 2004"
static const char longname[] = DRIVER_DESC; static const char longname[] = DRIVER_DESC;
static const char shortname[] = DRIVER_NAME; static const char shortname[] = DRIVER_NAME;
...@@ -435,7 +435,7 @@ static const char EP_INTR_IN_NAME [] = "ep3-bulk"; ...@@ -435,7 +435,7 @@ static const char EP_INTR_IN_NAME [] = "ep3-bulk";
#define LDBG(lun,fmt,args...) \ #define LDBG(lun,fmt,args...) \
yprintk(lun , KERN_DEBUG , fmt , ## args) yprintk(lun , KERN_DEBUG , fmt , ## args)
#define MDBG(fmt,args...) \ #define MDBG(fmt,args...) \
printk(KERN_DEBUG DRIVER_NAME ": " fmt, ## args) printk(KERN_DEBUG DRIVER_NAME ": " fmt , ## args)
#else #else
#define DBG(fsg,fmt,args...) \ #define DBG(fsg,fmt,args...) \
do { } while (0) do { } while (0)
...@@ -473,7 +473,7 @@ static const char EP_INTR_IN_NAME [] = "ep3-bulk"; ...@@ -473,7 +473,7 @@ static const char EP_INTR_IN_NAME [] = "ep3-bulk";
yprintk(lun , KERN_INFO , fmt , ## args) yprintk(lun , KERN_INFO , fmt , ## args)
#define MINFO(fmt,args...) \ #define MINFO(fmt,args...) \
printk(KERN_INFO DRIVER_NAME ": " fmt, ## args) printk(KERN_INFO DRIVER_NAME ": " fmt , ## args)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -848,6 +848,7 @@ struct fsg_dev { ...@@ -848,6 +848,7 @@ struct fsg_dev {
unsigned int nluns; unsigned int nluns;
struct lun *luns; struct lun *luns;
struct lun *curlun; struct lun *curlun;
struct completion lun_released;
}; };
typedef void (*fsg_routine_t)(struct fsg_dev *); typedef void (*fsg_routine_t)(struct fsg_dev *);
...@@ -3771,6 +3772,13 @@ static DEVICE_ATTR(file, 0444, show_file, NULL); ...@@ -3771,6 +3772,13 @@ static DEVICE_ATTR(file, 0444, show_file, NULL);
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static void lun_release(struct device *dev)
{
struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
complete(&fsg->lun_released);
}
static void fsg_unbind(struct usb_gadget *gadget) static void fsg_unbind(struct usb_gadget *gadget)
{ {
struct fsg_dev *fsg = get_gadget_data(gadget); struct fsg_dev *fsg = get_gadget_data(gadget);
...@@ -3782,12 +3790,14 @@ static void fsg_unbind(struct usb_gadget *gadget) ...@@ -3782,12 +3790,14 @@ static void fsg_unbind(struct usb_gadget *gadget)
clear_bit(REGISTERED, &fsg->atomic_bitflags); clear_bit(REGISTERED, &fsg->atomic_bitflags);
/* Unregister the sysfs attribute files and the LUNs */ /* Unregister the sysfs attribute files and the LUNs */
init_completion(&fsg->lun_released);
for (i = 0; i < fsg->nluns; ++i) { for (i = 0; i < fsg->nluns; ++i) {
curlun = &fsg->luns[i]; curlun = &fsg->luns[i];
if (curlun->registered) { if (curlun->registered) {
device_remove_file(&curlun->dev, &dev_attr_ro); device_remove_file(&curlun->dev, &dev_attr_ro);
device_remove_file(&curlun->dev, &dev_attr_file); device_remove_file(&curlun->dev, &dev_attr_file);
device_unregister_wait(&curlun->dev); device_unregister(&curlun->dev);
wait_for_completion(&fsg->lun_released);
curlun->registered = 0; curlun->registered = 0;
} }
} }
...@@ -4140,6 +4150,7 @@ static int __init fsg_init(void) ...@@ -4140,6 +4150,7 @@ static int __init fsg_init(void)
INFO(fsg, "failed to register LUN%d: %d\n", i, rc); INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
else { else {
curlun->registered = 1; curlun->registered = 1;
curlun->dev.release = lun_release;
device_create_file(&curlun->dev, &dev_attr_ro); device_create_file(&curlun->dev, &dev_attr_ro);
device_create_file(&curlun->dev, &dev_attr_file); device_create_file(&curlun->dev, &dev_attr_file);
} }
......
...@@ -534,7 +534,10 @@ write_fifo (struct net2280_ep *ep, struct usb_request *req) ...@@ -534,7 +534,10 @@ write_fifo (struct net2280_ep *ep, struct usb_request *req)
} }
/* write just one packet at a time */ /* write just one packet at a time */
count = min (ep->ep.maxpacket, total); count = ep->ep.maxpacket;
if (count > total) /* min() cannot be used on a bitfield */
count = total;
VDEBUG (ep->dev, "write %s fifo (IN) %d bytes%s req %p\n", VDEBUG (ep->dev, "write %s fifo (IN) %d bytes%s req %p\n",
ep->ep.name, count, ep->ep.name, count,
(count != ep->ep.maxpacket) ? " (short)" : "", (count != ep->ep.maxpacket) ? " (short)" : "",
...@@ -2197,7 +2200,8 @@ static void handle_ep_small (struct net2280_ep *ep) ...@@ -2197,7 +2200,8 @@ static void handle_ep_small (struct net2280_ep *ep)
unsigned len; unsigned len;
len = req->req.length - req->req.actual; len = req->req.length - req->req.actual;
len = min (ep->ep.maxpacket, len); if (len > ep->ep.maxpacket)
len = ep->ep.maxpacket;
req->req.actual += len; req->req.actual += len;
/* if we wrote it all, we're usually done */ /* if we wrote it all, we're usually done */
......
This diff is collapsed.
...@@ -52,14 +52,15 @@ struct pxa2xx_ep { ...@@ -52,14 +52,15 @@ struct pxa2xx_ep {
struct list_head queue; struct list_head queue;
unsigned long pio_irqs; unsigned long pio_irqs;
unsigned long dma_irqs; unsigned long dma_irqs;
int dma; short dma;
unsigned short fifo_size;
u8 bEndpointAddress; u8 bEndpointAddress;
u8 bmAttributes; u8 bmAttributes;
unsigned stopped : 1; unsigned stopped : 1;
unsigned dma_fixup : 1; unsigned dma_fixup : 1;
/* UDCCS = UDC Control/Status for this EP /* UDCCS = UDC Control/Status for this EP
* UBCR = UDC Byte Count Remaining (contents of OUT fifo) * UBCR = UDC Byte Count Remaining (contents of OUT fifo)
* UDDR = UDC Endpoint Data Register (the fifo) * UDDR = UDC Endpoint Data Register (the fifo)
...@@ -68,7 +69,12 @@ struct pxa2xx_ep { ...@@ -68,7 +69,12 @@ struct pxa2xx_ep {
volatile u32 *reg_udccs; volatile u32 *reg_udccs;
volatile u32 *reg_ubcr; volatile u32 *reg_ubcr;
volatile u32 *reg_uddr; volatile u32 *reg_uddr;
#ifdef USE_DMA
volatile u32 *reg_drcmr; volatile u32 *reg_drcmr;
#define drcmr(n) .reg_drcmr = & DRCMR ## n ,
#else
#define drcmr(n)
#endif
}; };
struct pxa2xx_request { struct pxa2xx_request {
...@@ -76,7 +82,7 @@ struct pxa2xx_request { ...@@ -76,7 +82,7 @@ struct pxa2xx_request {
struct list_head queue; struct list_head queue;
}; };
enum ep0_state { enum ep0_state {
EP0_IDLE, EP0_IDLE,
EP0_IN_DATA_PHASE, EP0_IN_DATA_PHASE,
EP0_OUT_DATA_PHASE, EP0_OUT_DATA_PHASE,
...@@ -181,14 +187,14 @@ static inline void make_usb_disappear(void) ...@@ -181,14 +187,14 @@ static inline void make_usb_disappear(void)
{ {
if (!the_controller->mach->udc_command) if (!the_controller->mach->udc_command)
return; return;
the_controller->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); the_controller->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
} }
static inline void let_usb_appear(void) static inline void let_usb_appear(void)
{ {
if (!the_controller->mach->udc_command) if (!the_controller->mach->udc_command)
return; return;
the_controller->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); the_controller->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -305,7 +311,7 @@ dump_state(struct pxa2xx_udc *dev) ...@@ -305,7 +311,7 @@ dump_state(struct pxa2xx_udc *dev)
#define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0) #define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0)
#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) #define WARN(stuff...) printk(KERN_WARNING "udc: " stuff)
#define INFO(stuff...) printk(KERN_INFO "udc: " stuff)
#endif /* __LINUX_USB_GADGET_PXA2XX_H */ #endif /* __LINUX_USB_GADGET_PXA2XX_H */
...@@ -473,7 +473,7 @@ static int ehci_start (struct usb_hcd *hcd) ...@@ -473,7 +473,7 @@ static int ehci_start (struct usb_hcd *hcd)
/* wire up the root hub */ /* wire up the root hub */
bus = hcd_to_bus (hcd); bus = hcd_to_bus (hcd);
bus->root_hub = udev = usb_alloc_dev (NULL, bus); bus->root_hub = udev = usb_alloc_dev (NULL, bus, 0);
if (!udev) { if (!udev) {
done2: done2:
ehci_mem_cleanup (ehci); ehci_mem_cleanup (ehci);
...@@ -680,7 +680,7 @@ static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) ...@@ -680,7 +680,7 @@ static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static void ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
{ {
struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_hcd *ehci = hcd_to_ehci (hcd);
u32 status; u32 status;
...@@ -690,6 +690,12 @@ static void ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) ...@@ -690,6 +690,12 @@ static void ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
status = readl (&ehci->regs->status); status = readl (&ehci->regs->status);
/* shared irq */
if (status == 0) {
spin_unlock (&ehci->lock);
return IRQ_NONE;
}
/* e.g. cardbus physical eject */ /* e.g. cardbus physical eject */
if (status == ~(u32) 0) { if (status == ~(u32) 0) {
ehci_dbg (ehci, "device removed\n"); ehci_dbg (ehci, "device removed\n");
...@@ -743,6 +749,7 @@ static void ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) ...@@ -743,6 +749,7 @@ static void ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
ehci_work (ehci, regs); ehci_work (ehci, regs);
done: done:
spin_unlock (&ehci->lock); spin_unlock (&ehci->lock);
return IRQ_HANDLED;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -559,7 +559,7 @@ static int rh_connect_rh (hci_t * hci) ...@@ -559,7 +559,7 @@ static int rh_connect_rh (hci_t * hci)
struct usb_device *usb_dev; struct usb_device *usb_dev;
hci->rh.devnum = 0; hci->rh.devnum = 0;
usb_dev = usb_alloc_dev (NULL, hci->bus); usb_dev = usb_alloc_dev (NULL, hci->bus, 0);
if (!usb_dev) if (!usb_dev)
return -ENOMEM; return -ENOMEM;
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
#endif #endif
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -103,7 +104,7 @@ ...@@ -103,7 +104,7 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
#define DRIVER_VERSION "2003 Oct 13" #define DRIVER_VERSION "2004 Feb 02"
#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell" #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
...@@ -112,8 +113,7 @@ ...@@ -112,8 +113,7 @@
// #define OHCI_VERBOSE_DEBUG /* not always helpful */ // #define OHCI_VERBOSE_DEBUG /* not always helpful */
/* For initializing controller (mask in an HCFS mode too) */ /* For initializing controller (mask in an HCFS mode too) */
#define OHCI_CONTROL_INIT \ #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
(OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
#define OHCI_UNLINK_TIMEOUT (HZ / 10) #define OHCI_UNLINK_TIMEOUT (HZ / 10)
...@@ -133,6 +133,12 @@ static inline void disable (struct ohci_hcd *ohci) ...@@ -133,6 +133,12 @@ static inline void disable (struct ohci_hcd *ohci)
#include "ohci-mem.c" #include "ohci-mem.c"
#include "ohci-q.c" #include "ohci-q.c"
/* Some boards don't support per-port power switching */
static int power_switching = 0;
module_param (power_switching, bool, 0);
MODULE_PARM_DESC (power_switching, "true (not default) to switch port power");
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/* /*
...@@ -288,11 +294,8 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) ...@@ -288,11 +294,8 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
* with HC dead, we won't respect hc queue pointers * with HC dead, we won't respect hc queue pointers
* any more ... just clean up every urb's memory. * any more ... just clean up every urb's memory.
*/ */
if (urb->hcpriv) { if (urb->hcpriv)
spin_unlock (&ohci->lock);
finish_urb (ohci, urb, NULL); finish_urb (ohci, urb, NULL);
spin_lock (&ohci->lock);
}
} }
spin_unlock_irqrestore (&ohci->lock, flags); spin_unlock_irqrestore (&ohci->lock, flags);
return 0; return 0;
...@@ -413,6 +416,14 @@ static int hc_reset (struct ohci_hcd *ohci) ...@@ -413,6 +416,14 @@ static int hc_reset (struct ohci_hcd *ohci)
ohci->hc_control = readl (&ohci->regs->control); ohci->hc_control = readl (&ohci->regs->control);
ohci->hc_control &= OHCI_CTRL_RWC; /* hcfs 0 = RESET */ ohci->hc_control &= OHCI_CTRL_RWC; /* hcfs 0 = RESET */
writel (ohci->hc_control, &ohci->regs->control); writel (ohci->hc_control, &ohci->regs->control);
if (power_switching) {
unsigned ports = roothub_a (ohci) & RH_A_NDP;
/* power down each port */
for (temp = 0; temp < ports; temp++)
writel (RH_PS_LSDA,
&ohci->regs->roothub.portstatus [temp]);
}
// flush those pci writes // flush those pci writes
(void) readl (&ohci->regs->control); (void) readl (&ohci->regs->control);
wait_ms (50); wait_ms (50);
...@@ -502,15 +513,21 @@ static int hc_start (struct ohci_hcd *ohci) ...@@ -502,15 +513,21 @@ static int hc_start (struct ohci_hcd *ohci)
/* NSC 87560 and maybe others */ /* NSC 87560 and maybe others */
tmp |= RH_A_NOCP; tmp |= RH_A_NOCP;
tmp &= ~(RH_A_POTPGT | RH_A_NPS); tmp &= ~(RH_A_POTPGT | RH_A_NPS);
} else if (power_switching) {
/* act like most external hubs: use per-port power
* switching and overcurrent reporting.
*/
tmp &= ~(RH_A_NPS | RH_A_NOCP);
tmp |= RH_A_PSM | RH_A_OCPM;
} else { } else {
/* hub power always on; required for AMD-756 and some /* hub power always on; required for AMD-756 and some
* Mac platforms, use this mode everywhere by default * Mac platforms. ganged overcurrent reporting, if any.
*/ */
tmp |= RH_A_NPS; tmp |= RH_A_NPS;
} }
writel (tmp, &ohci->regs->roothub.a); writel (tmp, &ohci->regs->roothub.a);
writel (RH_HS_LPSC, &ohci->regs->roothub.status); writel (RH_HS_LPSC, &ohci->regs->roothub.status);
writel (0, &ohci->regs->roothub.b); writel (power_switching ? RH_B_PPCM : 0, &ohci->regs->roothub.b);
// flush those pci writes // flush those pci writes
(void) readl (&ohci->regs->control); (void) readl (&ohci->regs->control);
...@@ -519,7 +536,7 @@ static int hc_start (struct ohci_hcd *ohci) ...@@ -519,7 +536,7 @@ static int hc_start (struct ohci_hcd *ohci)
/* connect the virtual root hub */ /* connect the virtual root hub */
bus = hcd_to_bus (&ohci->hcd); bus = hcd_to_bus (&ohci->hcd);
bus->root_hub = udev = usb_alloc_dev (NULL, bus); bus->root_hub = udev = usb_alloc_dev (NULL, bus, 0);
ohci->hcd.state = USB_STATE_RUNNING; ohci->hcd.state = USB_STATE_RUNNING;
if (!udev) { if (!udev) {
disable (ohci); disable (ohci);
...@@ -545,7 +562,7 @@ static int hc_start (struct ohci_hcd *ohci) ...@@ -545,7 +562,7 @@ static int hc_start (struct ohci_hcd *ohci)
/* an interrupt happens */ /* an interrupt happens */
static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
{ {
struct ohci_hcd *ohci = hcd_to_ohci (hcd); struct ohci_hcd *ohci = hcd_to_ohci (hcd);
struct ohci_regs *regs = ohci->regs; struct ohci_regs *regs = ohci->regs;
...@@ -560,11 +577,11 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) ...@@ -560,11 +577,11 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
} else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) { } else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
disable (ohci); disable (ohci);
ohci_dbg (ohci, "device removed!\n"); ohci_dbg (ohci, "device removed!\n");
return; return IRQ_HANDLED;
/* interrupt for some other device? */ /* interrupt for some other device? */
} else if ((ints &= readl (&regs->intrenable)) == 0) { } else if ((ints &= readl (&regs->intrenable)) == 0) {
return; return IRQ_NONE;
} }
if (ints & OHCI_INTR_UE) { if (ints & OHCI_INTR_UE) {
...@@ -604,6 +621,8 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) ...@@ -604,6 +621,8 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
// flush those pci writes // flush those pci writes
(void) readl (&ohci->regs->control); (void) readl (&ohci->regs->control);
} }
return IRQ_HANDLED;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -128,6 +128,8 @@ ohci_hub_descriptor ( ...@@ -128,6 +128,8 @@ ohci_hub_descriptor (
desc->bDescLength = 7 + 2 * temp; desc->bDescLength = 7 + 2 * temp;
temp = 0; temp = 0;
if (rh & RH_A_NPS) /* no power switching? */
temp |= 0x0002;
if (rh & RH_A_PSM) /* per-port power switching? */ if (rh & RH_A_PSM) /* per-port power switching? */
temp |= 0x0001; temp |= 0x0001;
if (rh & RH_A_NOCP) /* no overcurrent reporting? */ if (rh & RH_A_NOCP) /* no overcurrent reporting? */
......
...@@ -134,7 +134,7 @@ static int omap_ohci_clock_power(int on) ...@@ -134,7 +134,7 @@ static int omap_ohci_clock_power(int on)
writel(readl(ULPD_SOFT_REQ_REG) | SOFT_USB_REQ, writel(readl(ULPD_SOFT_REQ_REG) | SOFT_USB_REQ,
ULPD_SOFT_REQ_REG); ULPD_SOFT_REQ_REG);
outl(inl(ULPD_STATUS_REQ_REG) | USB_HOST_DPLL_REQ, writel(readl(ULPD_STATUS_REQ_REG) | USB_HOST_DPLL_REQ,
ULPD_STATUS_REQ_REG); ULPD_STATUS_REQ_REG);
} }
...@@ -248,7 +248,7 @@ static int omap_1610_usb_init(int mode) ...@@ -248,7 +248,7 @@ static int omap_1610_usb_init(int mode)
val |= (1 << 2); /* Disable pulldown on integrated transceiver DM */ val |= (1 << 2); /* Disable pulldown on integrated transceiver DM */
val |= (1 << 1); /* Disable pulldown on integraded transceiver DP */ val |= (1 << 1); /* Disable pulldown on integraded transceiver DP */
outl(val, USB_TRANSCEIVER_CTRL); writel(val, USB_TRANSCEIVER_CTRL);
/* Set the USB0_TRX_MODE */ /* Set the USB0_TRX_MODE */
val = 0; val = 0;
...@@ -256,7 +256,7 @@ static int omap_1610_usb_init(int mode) ...@@ -256,7 +256,7 @@ static int omap_1610_usb_init(int mode)
val &= ~DEV_IDLE_EN; val &= ~DEV_IDLE_EN;
val &= ~(7 << 16); /* Clear USB0_TRX_MODE */ val &= ~(7 << 16); /* Clear USB0_TRX_MODE */
val |= (3 << 16); /* 0 or 3, 6-wire DAT/SE0, TRM p 15-159 */ val |= (3 << 16); /* 0 or 3, 6-wire DAT/SE0, TRM p 15-159 */
outl(val, OTG_SYSCON_1); writel(val, OTG_SYSCON_1);
/* /*
* Control via OTG, see TRM p 15-163 * Control via OTG, see TRM p 15-163
...@@ -275,10 +275,10 @@ static int omap_1610_usb_init(int mode) ...@@ -275,10 +275,10 @@ static int omap_1610_usb_init(int mode)
val |= (4 << 16); /* Must be 4 */ val |= (4 << 16); /* Must be 4 */
val |= USBX_SYNCHRO; /* Must be set */ val |= USBX_SYNCHRO; /* Must be set */
val |= SRP_VBUS; val |= SRP_VBUS;
outl(val, OTG_SYSCON_2); writel(val, OTG_SYSCON_2);
/* Enable OTG idle */ /* Enable OTG idle */
//outl(inl(OTG_SYSCON_1) | OTG_IDLE_EN, OTG_SYSCON_1); //writel(readl(OTG_SYSCON_1) | OTG_IDLE_EN, OTG_SYSCON_1);
return 0; return 0;
} }
...@@ -631,7 +631,7 @@ static struct omap_dev ohci_hcd_omap_device = { ...@@ -631,7 +631,7 @@ static struct omap_dev ohci_hcd_omap_device = {
.end = OMAP_OHCI_BASE + OMAP_OHCI_SIZE, .end = OMAP_OHCI_BASE + OMAP_OHCI_SIZE,
}, },
.irq = { .irq = {
INT_OHCI, INT_USB_HHC_1,
}, },
}; };
......
...@@ -266,6 +266,9 @@ static int ohci_pci_resume (struct usb_hcd *hcd) ...@@ -266,6 +266,9 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
if (ohci->ed_bulktail) if (ohci->ed_bulktail)
ohci->hc_control |= OHCI_CTRL_BLE; ohci->hc_control |= OHCI_CTRL_BLE;
} }
if (hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs
|| hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs)
ohci->hc_control |= OHCI_CTRL_PLE|OHCI_CTRL_IE;
hcd->state = USB_STATE_RUNNING; hcd->state = USB_STATE_RUNNING;
writel (ohci->hc_control, &ohci->regs->control); writel (ohci->hc_control, &ohci->regs->control);
......
...@@ -30,7 +30,7 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) ...@@ -30,7 +30,7 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
/* /*
* URB goes back to driver, and isn't reissued. * URB goes back to driver, and isn't reissued.
* It's completely gone from HC data structures. * It's completely gone from HC data structures.
* PRECONDITION: no locks held, irqs blocked (Giveback can call into HCD.) * PRECONDITION: ohci lock held, irqs blocked.
*/ */
static void static void
finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs) finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs)
...@@ -55,7 +55,6 @@ finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs) ...@@ -55,7 +55,6 @@ finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs)
} }
spin_unlock (&urb->lock); spin_unlock (&urb->lock);
// what lock protects these?
switch (usb_pipetype (urb->pipe)) { switch (usb_pipetype (urb->pipe)) {
case PIPE_ISOCHRONOUS: case PIPE_ISOCHRONOUS:
hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs--; hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs--;
...@@ -68,7 +67,18 @@ finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs) ...@@ -68,7 +67,18 @@ finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs)
#ifdef OHCI_VERBOSE_DEBUG #ifdef OHCI_VERBOSE_DEBUG
urb_print (urb, "RET", usb_pipeout (urb->pipe)); urb_print (urb, "RET", usb_pipeout (urb->pipe));
#endif #endif
/* urb->complete() can reenter this HCD */
spin_unlock (&ohci->lock);
usb_hcd_giveback_urb (&ohci->hcd, urb, regs); usb_hcd_giveback_urb (&ohci->hcd, urb, regs);
spin_lock (&ohci->lock);
/* stop periodic dma if it's not needed */
if (hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs == 0
&& hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs == 0) {
ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_IE);
writel (ohci->hc_control, &ohci->regs->control);
}
} }
...@@ -549,6 +559,7 @@ static void td_submit_urb ( ...@@ -549,6 +559,7 @@ static void td_submit_urb (
int cnt = 0; int cnt = 0;
u32 info = 0; u32 info = 0;
int is_out = usb_pipeout (urb->pipe); int is_out = usb_pipeout (urb->pipe);
int periodic = 0;
/* OHCI handles the bulk/interrupt data toggles itself. We just /* OHCI handles the bulk/interrupt data toggles itself. We just
* use the device toggle bits for resetting, and rely on the fact * use the device toggle bits for resetting, and rely on the fact
...@@ -578,7 +589,8 @@ static void td_submit_urb ( ...@@ -578,7 +589,8 @@ static void td_submit_urb (
*/ */
case PIPE_INTERRUPT: case PIPE_INTERRUPT:
/* ... and periodic urbs have extra accounting */ /* ... and periodic urbs have extra accounting */
hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs++; periodic = hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs++ == 0
&& hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs == 0;
/* FALLTHROUGH */ /* FALLTHROUGH */
case PIPE_BULK: case PIPE_BULK:
info = is_out info = is_out
...@@ -646,9 +658,17 @@ static void td_submit_urb ( ...@@ -646,9 +658,17 @@ static void td_submit_urb (
data + urb->iso_frame_desc [cnt].offset, data + urb->iso_frame_desc [cnt].offset,
urb->iso_frame_desc [cnt].length, urb, cnt); urb->iso_frame_desc [cnt].length, urb, cnt);
} }
hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs++; periodic = hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs++ == 0
&& hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs == 0;
break; break;
} }
/* start periodic dma if needed */
if (periodic) {
ohci->hc_control |= OHCI_CTRL_PLE|OHCI_CTRL_IE;
writel (ohci->hc_control, &ohci->regs->control);
}
// ASSERT (urb_priv->length == cnt); // ASSERT (urb_priv->length == cnt);
} }
...@@ -949,9 +969,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs) ...@@ -949,9 +969,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
/* if URB is done, clean up */ /* if URB is done, clean up */
if (urb_priv->td_cnt == urb_priv->length) { if (urb_priv->td_cnt == urb_priv->length) {
modified = completed = 1; modified = completed = 1;
spin_unlock (&ohci->lock);
finish_urb (ohci, urb, regs); finish_urb (ohci, urb, regs);
spin_lock (&ohci->lock);
} }
} }
if (completed && !list_empty (&ed->td_list)) if (completed && !list_empty (&ed->td_list))
...@@ -1030,11 +1048,8 @@ dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs *regs) ...@@ -1030,11 +1048,8 @@ dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs *regs)
urb_priv->td_cnt++; urb_priv->td_cnt++;
/* If all this urb's TDs are done, call complete() */ /* If all this urb's TDs are done, call complete() */
if (urb_priv->td_cnt == urb_priv->length) { if (urb_priv->td_cnt == urb_priv->length)
spin_unlock (&ohci->lock);
finish_urb (ohci, urb, regs); finish_urb (ohci, urb, regs);
spin_lock (&ohci->lock);
}
/* clean schedule: unlink EDs that are no longer busy */ /* clean schedule: unlink EDs that are no longer busy */
if (list_empty (&ed->td_list)) if (list_empty (&ed->td_list))
......
...@@ -254,8 +254,6 @@ void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev) ...@@ -254,8 +254,6 @@ void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev)
hcd_buffer_destroy (hcd); hcd_buffer_destroy (hcd);
usb_deregister_bus (&hcd->self); usb_deregister_bus (&hcd->self);
if (atomic_read (&hcd->self.refcnt) != 1)
err ("%s: %s, count != 1", __FUNCTION__, hcd->self.bus_name);
base = hcd->regs; base = hcd->regs;
hcd->driver->hcd_free (hcd); hcd->driver->hcd_free (hcd);
......
/* /*
* Universal Host Controller Interface driver for USB. * Universal Host Controller Interface driver for USB.
* *
* Maintainer: Johannes Erdfelt <johannes@erdfelt.com> * Maintainer: Alan Stern <stern@rowland.harvard.edu>
* *
* (C) Copyright 1999 Linus Torvalds * (C) Copyright 1999 Linus Torvalds
* (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com
...@@ -668,7 +668,6 @@ static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *u ...@@ -668,7 +668,6 @@ static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *u
urbp->inserttime = jiffies; urbp->inserttime = jiffies;
urbp->fsbrtime = jiffies; urbp->fsbrtime = jiffies;
urbp->urb = urb; urbp->urb = urb;
urbp->dev = urb->dev;
INIT_LIST_HEAD(&urbp->td_list); INIT_LIST_HEAD(&urbp->td_list);
INIT_LIST_HEAD(&urbp->queue_list); INIT_LIST_HEAD(&urbp->queue_list);
...@@ -1909,7 +1908,7 @@ static void uhci_remove_pending_qhs(struct uhci_hcd *uhci) ...@@ -1909,7 +1908,7 @@ static void uhci_remove_pending_qhs(struct uhci_hcd *uhci)
spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags); spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags);
} }
static void uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
{ {
struct uhci_hcd *uhci = hcd_to_uhci(hcd); struct uhci_hcd *uhci = hcd_to_uhci(hcd);
unsigned int io_addr = uhci->io_addr; unsigned int io_addr = uhci->io_addr;
...@@ -1922,7 +1921,7 @@ static void uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) ...@@ -1922,7 +1921,7 @@ static void uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
*/ */
status = inw(io_addr + USBSTS); status = inw(io_addr + USBSTS);
if (!status) /* shared interrupt, not mine */ if (!status) /* shared interrupt, not mine */
return; return IRQ_NONE;
outw(status, io_addr + USBSTS); /* Clear it */ outw(status, io_addr + USBSTS); /* Clear it */
if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
...@@ -1963,6 +1962,7 @@ static void uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) ...@@ -1963,6 +1962,7 @@ static void uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
spin_unlock(&uhci->urb_list_lock); spin_unlock(&uhci->urb_list_lock);
uhci_finish_completion(hcd, regs); uhci_finish_completion(hcd, regs);
return IRQ_HANDLED;
} }
static void reset_hc(struct uhci_hcd *uhci) static void reset_hc(struct uhci_hcd *uhci)
...@@ -2315,7 +2315,7 @@ static int uhci_start(struct usb_hcd *hcd) ...@@ -2315,7 +2315,7 @@ static int uhci_start(struct usb_hcd *hcd)
uhci->rh_numports = port; uhci->rh_numports = port;
hcd->self.root_hub = udev = usb_alloc_dev(NULL, &hcd->self); hcd->self.root_hub = udev = usb_alloc_dev(NULL, &hcd->self, 0);
if (!udev) { if (!udev) {
err("unable to allocate root hub"); err("unable to allocate root hub");
goto err_alloc_root_hub; goto err_alloc_root_hub;
......
...@@ -372,7 +372,6 @@ struct urb_priv { ...@@ -372,7 +372,6 @@ struct urb_priv {
struct list_head urb_list; struct list_head urb_list;
struct urb *urb; struct urb *urb;
struct usb_device *dev;
struct uhci_qh *qh; /* QH for this URB */ struct uhci_qh *qh; /* QH for this URB */
struct list_head td_list; /* P: urb->lock */ struct list_head td_list; /* P: urb->lock */
......
...@@ -17,19 +17,6 @@ config USB_MDC800 ...@@ -17,19 +17,6 @@ config USB_MDC800
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called mdc800. module will be called mdc800.
config USB_SCANNER
tristate "USB Scanner support (OBSOLETE)"
depends on USB
help
Say Y here if you want to connect a USB scanner to your computer's
USB port. Please read <file:Documentation/usb/scanner.txt> for more
information.
This driver has been obsoleted by support via libusb.
To compile this driver as a module, choose M here: the
module will be called scanner.
config USB_MICROTEK config USB_MICROTEK
tristate "Microtek X6USB scanner support" tristate "Microtek X6USB scanner support"
depends on USB && SCSI depends on USB && SCSI
......
...@@ -5,4 +5,3 @@ ...@@ -5,4 +5,3 @@
obj-$(CONFIG_USB_MDC800) += mdc800.o obj-$(CONFIG_USB_MDC800) += mdc800.o
obj-$(CONFIG_USB_HPUSBSCSI) += hpusbscsi.o obj-$(CONFIG_USB_HPUSBSCSI) += hpusbscsi.o
obj-$(CONFIG_USB_MICROTEK) += microtek.o obj-$(CONFIG_USB_MICROTEK) += microtek.o
obj-$(CONFIG_USB_SCANNER) += scanner.o
This diff is collapsed.
This diff is collapsed.
...@@ -41,9 +41,11 @@ config HID_FF ...@@ -41,9 +41,11 @@ config HID_FF
bool "Force feedback support (EXPERIMENTAL)" bool "Force feedback support (EXPERIMENTAL)"
depends on USB_HIDINPUT && EXPERIMENTAL depends on USB_HIDINPUT && EXPERIMENTAL
help help
Say Y here is you want force feedback support for a few HID devices. See Say Y here is you want force feedback support for a few HID devices.
below for a list of supported devices. See below for a list of supported devices.
See Documentation/input/ff.txt for a description of the force feedback API.
See <file:Documentation/input/ff.txt> for a description of the force
feedback API.
If unsure, say N. If unsure, say N.
...@@ -171,7 +173,8 @@ config USB_POWERMATE ...@@ -171,7 +173,8 @@ config USB_POWERMATE
rotation. The dial also acts as a pushbutton. The base contains an LED rotation. The dial also acts as a pushbutton. The base contains an LED
which can be instructed to pulse or to switch to a particular intensity. which can be instructed to pulse or to switch to a particular intensity.
You can download userspace tools from http://sowerbutts.com/powermate/ You can download userspace tools from
<http://sowerbutts.com/powermate/>.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called powermate. module will be called powermate.
...@@ -185,7 +188,7 @@ config USB_XPAD ...@@ -185,7 +188,7 @@ config USB_XPAD
and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well. and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
For information about how to connect the X-Box pad to USB, see For information about how to connect the X-Box pad to USB, see
Documentation/input/xpad.txt. <file:Documentation/input/xpad.txt>.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called xpad. module will be called xpad.
...@@ -602,14 +602,16 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) ...@@ -602,14 +602,16 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
case 2: case 2:
if ((end - start) < 2) if ((end - start) < 2)
return NULL; return NULL;
item->data.u16 = le16_to_cpu(get_unaligned(((__u16*)start)++)); item->data.u16 = le16_to_cpu(get_unaligned((__u16*)start));
start = (__u8 *)((__u16 *)start + 1);
return start; return start;
case 3: case 3:
item->size++; item->size++;
if ((end - start) < 4) if ((end - start) < 4)
return NULL; return NULL;
item->data.u32 = le32_to_cpu(get_unaligned(((__u32*)start)++)); item->data.u32 = le32_to_cpu(get_unaligned((__u32*)start));
start = (__u8 *)((__u32 *)start + 1);
return start; return start;
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
You might find some interesting stuff about this module at You might find some interesting stuff about this module at
http://unimut.fsk.uni-heidelberg.de/unimut/demi/dsbr http://unimut.fsk.uni-heidelberg.de/unimut/demi/dsbr
Copyright (c) 2000 Markus Demleitner <msdemlei@tucana.harvard.edu> Copyright (c) 2000 Markus Demleitner <msdemlei@cl.uni-heidelberg.de>
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 as published by it under the terms of the GNU General Public License as published by
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
History: History:
Version 0.30: Version 0.30:
Markus: Updates for 2.5.x kernel and more ISO compiant source Markus: Updates for 2.5.x kernel and more ISO compliant source
Version 0.25: Version 0.25:
PSL and Markus: Cleanup, radio now doesn't stop on device close PSL and Markus: Cleanup, radio now doesn't stop on device close
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
/* /*
* Version Information * Version Information
*/ */
#define DRIVER_VERSION "v0.25" #define DRIVER_VERSION "v0.30"
#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>" #define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver" #define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
......
...@@ -17,7 +17,7 @@ config USB_EMI62 ...@@ -17,7 +17,7 @@ config USB_EMI62
This code is also available as a module ( = code which can be This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want). inserted in and removed from the running kernel whenever you want).
The module will be called audio. If you want to compile it as a The module will be called audio. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. module, say M here and read <file:Documentation/kbuild/modules.txt>.
config USB_EMI26 config USB_EMI26
tristate "EMI 2|6 USB Audio interface support" tristate "EMI 2|6 USB Audio interface support"
...@@ -83,7 +83,8 @@ config USB_LEGOTOWER ...@@ -83,7 +83,8 @@ config USB_LEGOTOWER
This code is also available as a module ( = code which can be This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want). inserted in and removed from the running kernel whenever you want).
The module will be called legousbtower. If you want to compile it as The module will be called legousbtower. If you want to compile it as
a module, say M here and read <file:Documentation/modules.txt>. a module, say M here and read
<file:Documentation/kbuild/modules.txt>.
config USB_BRLVGER config USB_BRLVGER
tristate "Tieman Voyager USB Braille display support (EXPERIMENTAL)" tristate "Tieman Voyager USB Braille display support (EXPERIMENTAL)"
...@@ -102,7 +103,7 @@ config USB_LCD ...@@ -102,7 +103,7 @@ config USB_LCD
help help
Say Y here if you want to connect an USBLCD to your computer's Say Y here if you want to connect an USBLCD to your computer's
USB port. The USBLCD is a small USB interface board for USB port. The USBLCD is a small USB interface board for
alphanumeric LCD modules. See <http://www.usblcd.de> for more alphanumeric LCD modules. See <http://www.usblcd.de/> for more
information. information.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
...@@ -139,6 +140,6 @@ config USB_TEST ...@@ -139,6 +140,6 @@ config USB_TEST
with specialized device firmware for regression and stress testing, with specialized device firmware for regression and stress testing,
to help prevent problems from cropping up with "real" drivers. to help prevent problems from cropping up with "real" drivers.
See <http://www.linux-usb.org/usbtest> for more information, See <http://www.linux-usb.org/usbtest/> for more information,
including sample test device firmware and "how to use it". including sample test device firmware and "how to use it".
This diff is collapsed.
...@@ -333,7 +333,7 @@ static size_t parport_uss720_epp_read_data(struct parport *pp, void *buf, size_t ...@@ -333,7 +333,7 @@ static size_t parport_uss720_epp_read_data(struct parport *pp, void *buf, size_t
for (; got < length; got++) { for (; got < length; got++) {
if (get_1284_register(pp, 4, (char *)buf)) if (get_1284_register(pp, 4, (char *)buf))
break; break;
((char*)buf)++; buf++;
if (priv->reg[0] & 0x01) { if (priv->reg[0] & 0x01) {
clear_epp_timeout(pp); clear_epp_timeout(pp);
break; break;
...@@ -392,7 +392,7 @@ static size_t parport_uss720_epp_read_addr(struct parport *pp, void *buf, size_t ...@@ -392,7 +392,7 @@ static size_t parport_uss720_epp_read_addr(struct parport *pp, void *buf, size_t
for (; got < length; got++) { for (; got < length; got++) {
if (get_1284_register(pp, 3, (char *)buf)) if (get_1284_register(pp, 3, (char *)buf))
break; break;
((char*)buf)++; buf++;
if (priv->reg[0] & 0x01) { if (priv->reg[0] & 0x01) {
clear_epp_timeout(pp); clear_epp_timeout(pp);
break; break;
...@@ -412,7 +412,7 @@ static size_t parport_uss720_epp_write_addr(struct parport *pp, const void *buf, ...@@ -412,7 +412,7 @@ static size_t parport_uss720_epp_write_addr(struct parport *pp, const void *buf,
for (; written < length; written++) { for (; written < length; written++) {
if (set_1284_register(pp, 3, *(char *)buf)) if (set_1284_register(pp, 3, *(char *)buf))
break; break;
((char*)buf)++; buf++;
if (get_1284_register(pp, 1, NULL)) if (get_1284_register(pp, 1, NULL))
break; break;
if (priv->reg[0] & 0x01) { if (priv->reg[0] & 0x01) {
...@@ -469,7 +469,7 @@ static size_t parport_uss720_ecp_write_addr(struct parport *pp, const void *buff ...@@ -469,7 +469,7 @@ static size_t parport_uss720_ecp_write_addr(struct parport *pp, const void *buff
for (; written < len; written++) { for (; written < len; written++) {
if (set_1284_register(pp, 5, *(char *)buffer)) if (set_1284_register(pp, 5, *(char *)buffer))
break; break;
((char*)buffer)++; buffer++;
} }
change_mode(pp, ECR_PS2); change_mode(pp, ECR_PS2);
return written; return written;
......
...@@ -73,11 +73,12 @@ config USB_PEGASUS ...@@ -73,11 +73,12 @@ config USB_PEGASUS
select MII select MII
---help--- ---help---
Say Y here if you know you have Pegasus or Pegasus-II based adapter. Say Y here if you know you have Pegasus or Pegasus-II based adapter.
If in doubt then look at linux/drivers/usb/pegasus.h for the complete If in doubt then look at <file:drivers/usb/net/pegasus.h> for the
list of supported devices. complete list of supported devices.
If your particular adapter is not in the list and you are _sure_ it If your particular adapter is not in the list and you are _sure_ it
is Pegasus or Pegasus II based then send me (petkan@users.sourceforge.net) is Pegasus or Pegasus II based then send me
vendor and device IDs. <petkan@users.sourceforge.net> vendor and device IDs.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called pegasus. module will be called pegasus.
...@@ -87,8 +88,8 @@ config USB_RTL8150 ...@@ -87,8 +88,8 @@ config USB_RTL8150
depends on USB && NET && EXPERIMENTAL depends on USB && NET && EXPERIMENTAL
help help
Say Y here if you have RTL8150 based usb-ethernet adapter. Say Y here if you have RTL8150 based usb-ethernet adapter.
Send me (petkan@users.sourceforge.net) any comments you may have. Send me <petkan@users.sourceforge.net> any comments you may have.
You can also check for updates at http://pegasus2.sourceforge.net/ You can also check for updates at <http://pegasus2.sourceforge.net/>.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called rtl8150. module will be called rtl8150.
...@@ -254,13 +255,14 @@ config USB_AX8817X ...@@ -254,13 +255,14 @@ config USB_AX8817X
10/100 Ethernet devices. 10/100 Ethernet devices.
This driver should work with at least the following devices: This driver should work with at least the following devices:
* Aten UC210T
* ASIX AX88172 * ASIX AX88172
* D-Link DUB-E100 * D-Link DUB-E100
* Hawking UF200 * Hawking UF200
* Linksys USB200M * Linksys USB200M
* Netgear FA120 * Netgear FA120
* Intellinet * Intellinet USB 2.0 Ethernet
* ST Lab USB Ethernet * ST Lab USB 2.0 Ethernet
* TrendNet TU2-ET100 * TrendNet TU2-ET100
This driver creates an interface named "ethX", where X depends on This driver creates an interface named "ethX", where X depends on
......
This diff is collapsed.
...@@ -232,8 +232,10 @@ static int belkin_sa_open (struct usb_serial_port *port, struct file *filp) ...@@ -232,8 +232,10 @@ static int belkin_sa_open (struct usb_serial_port *port, struct file *filp)
port->interrupt_in_urb->dev = port->serial->dev; port->interrupt_in_urb->dev = port->serial->dev;
retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (retval) if (retval) {
usb_unlink_urb(port->read_urb);
err(" usb_submit_urb(read int) failed"); err(" usb_submit_urb(read int) failed");
}
exit: exit:
return retval; return retval;
......
...@@ -534,6 +534,7 @@ static struct usb_device_id keyspan_1port_ids[] = { ...@@ -534,6 +534,7 @@ static struct usb_device_id keyspan_1port_ids[] = {
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) },
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_product_id) },
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_product_id) },
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19hs_product_id) },
{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_pre_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_pre_product_id) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -409,8 +409,6 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) ...@@ -409,8 +409,6 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
// someone sets the dev to 0 if the close method has been called // someone sets the dev to 0 if the close method has been called
port->interrupt_in_urb->dev = port->serial->dev; port->interrupt_in_urb->dev = port->serial->dev;
// usb_dump_urb(port->interrupt_in_urb);
result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC );
dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result); dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
} }
...@@ -496,8 +494,6 @@ static int kobil_write (struct usb_serial_port *port, int from_user, ...@@ -496,8 +494,6 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
port->interrupt_in_urb->dev = port->serial->dev; port->interrupt_in_urb->dev = port->serial->dev;
// start reading // start reading
//usb_dump_urb(port->interrupt_in_urb);
result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC );
dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result); dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
} }
......
...@@ -241,6 +241,8 @@ static struct usb_device_id id_table [] = { ...@@ -241,6 +241,8 @@ static struct usb_device_id id_table [] = {
.driver_info = (kernel_ulong_t)&palm_os_4_probe }, .driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID), { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe }, .driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ }, /* optional parameter entry */ { }, /* optional parameter entry */
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
...@@ -274,6 +276,7 @@ static struct usb_device_id id_table_combined [] = { ...@@ -274,6 +276,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) },
{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) },
{ USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) }, { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) },
{ USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) },
{ }, /* optional parameter entry */ { }, /* optional parameter entry */
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -50,6 +50,9 @@ ...@@ -50,6 +50,9 @@
#define GARMIN_VENDOR_ID 0x091E #define GARMIN_VENDOR_ID 0x091E
#define GARMIN_IQUE_3600_ID 0x0004 #define GARMIN_IQUE_3600_ID 0x0004
#define ACEECA_VENDOR_ID 0x4766
#define ACEECA_MEZ1000_ID 0x0001
/**************************************************************************** /****************************************************************************
* Handspring Visor Vendor specific request codes (bRequest values) * Handspring Visor Vendor specific request codes (bRequest values)
* A big thank you to Handspring for providing the following information. * A big thank you to Handspring for providing the following information.
......
...@@ -56,11 +56,11 @@ config USB_STORAGE_ISD200 ...@@ -56,11 +56,11 @@ config USB_STORAGE_ISD200
- Planex eXtreme Drive RX-25HU USB-IDE cable (not model RX-25U) - Planex eXtreme Drive RX-25HU USB-IDE cable (not model RX-25U)
config USB_STORAGE_DPCM config USB_STORAGE_DPCM
bool "Microtech CompactFlash/SmartMedia support" bool "Microtech/ZiO! CompactFlash/SmartMedia support"
depends on USB_STORAGE depends on USB_STORAGE
help help
Say Y here to support the Microtech ZiO! CompactFlash reader. Say Y here to support the Microtech/ZiO! CompactFlash reader.
There is a web page at <http://www.microtechint.com/zio/index.html>. There is a web page at <http://www.ziocorp.com/products/>.
config USB_STORAGE_HP8200e config USB_STORAGE_HP8200e
bool "HP CD-Writer 82xx support (EXPERIMENTAL)" bool "HP CD-Writer 82xx support (EXPERIMENTAL)"
......
...@@ -29,7 +29,7 @@ extern int datafab_transport(Scsi_Cmnd *srb, struct us_data *us); ...@@ -29,7 +29,7 @@ extern int datafab_transport(Scsi_Cmnd *srb, struct us_data *us);
struct datafab_info { struct datafab_info {
unsigned long sectors; // total sector count unsigned long sectors; // total sector count
unsigned long ssize; // sector size in bytes unsigned long ssize; // sector size in bytes
char lun; // used for dual-slot readers signed char lun; // used for dual-slot readers
// the following aren't used yet // the following aren't used yet
unsigned char sense_key; unsigned char sense_key;
......
...@@ -377,7 +377,7 @@ UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0xffff, ...@@ -377,7 +377,7 @@ UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0xffff,
UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff, UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff,
"", "",
"USB TO IDE", "USB TO IDE",
US_SC_SCSI, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_MODE_XLATE ), US_FL_MODE_XLATE ),
/* Reported by Peter Marks <peter.marks@turner.com> /* Reported by Peter Marks <peter.marks@turner.com>
...@@ -604,7 +604,14 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff, ...@@ -604,7 +604,14 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff,
* - They don't like the INQUIRY command. So we must handle this command * - They don't like the INQUIRY command. So we must handle this command
* of the SCSI layer ourselves. * of the SCSI layer ourselves.
*/ */
UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009,
"Casio",
"QV DigitalCamera",
US_SC_8070, US_PR_CB, NULL,
US_FL_FIX_INQUIRY ),
/* Later Casio cameras apparently tell the truth */
UNUSUAL_DEV( 0x07cf, 0x1001, 0x9010, 0x9999,
"Casio", "Casio",
"QV DigitalCamera", "QV DigitalCamera",
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
......
...@@ -834,7 +834,7 @@ void usb_stor_release_resources(struct us_data *us) ...@@ -834,7 +834,7 @@ void usb_stor_release_resources(struct us_data *us)
/* Finish the SCSI host removal sequence */ /* Finish the SCSI host removal sequence */
if (us->host) { if (us->host) {
(struct us_data *) us->host->hostdata[0] = NULL; us->host->hostdata[0] = 0;
scsi_host_put(us->host); scsi_host_put(us->host);
} }
......
...@@ -274,7 +274,6 @@ struct usb_device { ...@@ -274,7 +274,6 @@ struct usb_device {
}; };
#define to_usb_device(d) container_of(d, struct usb_device, dev) #define to_usb_device(d) container_of(d, struct usb_device, dev)
extern struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *);
extern struct usb_device *usb_get_dev(struct usb_device *dev); extern struct usb_device *usb_get_dev(struct usb_device *dev);
extern void usb_put_dev(struct usb_device *dev); extern void usb_put_dev(struct usb_device *dev);
...@@ -1016,16 +1015,6 @@ static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int en ...@@ -1016,16 +1015,6 @@ static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int en
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/*
* Debugging and troubleshooting/diagnostic helpers.
*/
void usb_show_device_descriptor(struct usb_device_descriptor *);
void usb_show_config_descriptor(struct usb_config_descriptor *);
void usb_show_interface_descriptor(struct usb_interface_descriptor *);
void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *);
void usb_show_device(struct usb_device *);
void usb_show_string(struct usb_device *dev, char *id, int index);
#ifdef DEBUG #ifdef DEBUG
#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg) #define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg)
#else #else
......
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