Commit 7037193a authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/linux/linux/BK/bleeding-2.5

into kroah.com:/home/linux/linux/BK/gregkh-2.5
parents 4e375211 b874f98e
...@@ -278,7 +278,7 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) ...@@ -278,7 +278,7 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
urb->actual_length = 0; urb->actual_length = 0;
urb->dev = acm->dev; urb->dev = acm->dev;
if (usb_submit_urb(urb, GFP_KERNEL)) if (usb_submit_urb(urb, GFP_ATOMIC))
dbg("failed resubmitting read urb"); dbg("failed resubmitting read urb");
} }
......
...@@ -1022,7 +1022,10 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) ...@@ -1022,7 +1022,10 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
* they could clobber root hub response data. * they could clobber root hub response data.
*/ */
urb->transfer_flags |= URB_NO_DMA_MAP; urb->transfer_flags |= URB_NO_DMA_MAP;
return rh_urb_enqueue (hcd, urb); status = rh_urb_enqueue (hcd, urb);
if (status)
urb_unlink (urb);
return status;
} }
/* lower level hcd code should use *_dma exclusively */ /* lower level hcd code should use *_dma exclusively */
...@@ -1043,7 +1046,10 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) ...@@ -1043,7 +1046,10 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
: PCI_DMA_TODEVICE); : PCI_DMA_TODEVICE);
} }
return hcd->driver->urb_enqueue (hcd, urb, mem_flags); status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
if (status)
urb_unlink (urb);
return status;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -1137,7 +1143,7 @@ static int hcd_unlink_urb (struct urb *urb) ...@@ -1137,7 +1143,7 @@ static int hcd_unlink_urb (struct urb *urb)
* FIXME use better explicit urb state * FIXME use better explicit urb state
*/ */
if (urb->status != -EINPROGRESS) { if (urb->status != -EINPROGRESS) {
retval = -EINVAL; retval = -EBUSY;
goto done; goto done;
} }
......
...@@ -279,12 +279,13 @@ static int usb_hub_configure(struct usb_hub *hub, ...@@ -279,12 +279,13 @@ static int usb_hub_configure(struct usb_hub *hub,
struct usb_hub_status hubstatus; struct usb_hub_status hubstatus;
unsigned int pipe; unsigned int pipe;
int maxp, ret; int maxp, ret;
char *message;
hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
if (!hub->descriptor) { if (!hub->descriptor) {
err("Unable to kmalloc %Zd bytes for hub descriptor", message = "can't kmalloc hub descriptor";
sizeof(*hub->descriptor)); ret = -ENOMEM;
return -1; goto fail;
} }
/* Request the entire hub descriptor. /* Request the entire hub descriptor.
...@@ -294,13 +295,12 @@ static int usb_hub_configure(struct usb_hub *hub, ...@@ -294,13 +295,12 @@ static int usb_hub_configure(struct usb_hub *hub,
ret = usb_get_hub_descriptor(dev, hub->descriptor, ret = usb_get_hub_descriptor(dev, hub->descriptor,
sizeof(*hub->descriptor)); sizeof(*hub->descriptor));
if (ret < 0) { if (ret < 0) {
err("Unable to get hub descriptor (err = %d)", ret); message = "can't read hub descriptor";
kfree(hub->descriptor); goto fail;
return -1;
} else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) { } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {
err("Hub is too big! %d children", hub->descriptor->bNbrPorts); message = "hub has too many ports!";
kfree(hub->descriptor); ret = -ENODEV;
return -1; goto fail;
} }
dev->maxchild = hub->descriptor->bNbrPorts; dev->maxchild = hub->descriptor->bNbrPorts;
...@@ -396,9 +396,8 @@ static int usb_hub_configure(struct usb_hub *hub, ...@@ -396,9 +396,8 @@ static int usb_hub_configure(struct usb_hub *hub,
ret = usb_get_hub_status(dev, &hubstatus); ret = usb_get_hub_status(dev, &hubstatus);
if (ret < 0) { if (ret < 0) {
err("Unable to get hub status (err = %d)", ret); message = "can't get hub status";
kfree(hub->descriptor); goto fail;
return -1;
} }
le16_to_cpus(&hubstatus.wHubStatus); le16_to_cpus(&hubstatus.wHubStatus);
...@@ -419,18 +418,17 @@ static int usb_hub_configure(struct usb_hub *hub, ...@@ -419,18 +418,17 @@ static int usb_hub_configure(struct usb_hub *hub,
hub->urb = usb_alloc_urb(0, GFP_KERNEL); hub->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!hub->urb) { if (!hub->urb) {
err("couldn't allocate interrupt urb"); message = "couldn't allocate interrupt urb";
kfree(hub->descriptor); ret = -ENOMEM;
return -1; goto fail;
} }
usb_fill_int_urb(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq, usb_fill_int_urb(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
hub, endpoint->bInterval); hub, endpoint->bInterval);
ret = usb_submit_urb(hub->urb, GFP_KERNEL); ret = usb_submit_urb(hub->urb, GFP_KERNEL);
if (ret) { if (ret) {
err("usb_submit_urb failed (%d)", ret); message = "couldn't submit status urb";
kfree(hub->descriptor); goto fail;
return -1;
} }
/* Wake up khubd */ /* Wake up khubd */
...@@ -439,6 +437,12 @@ static int usb_hub_configure(struct usb_hub *hub, ...@@ -439,6 +437,12 @@ static int usb_hub_configure(struct usb_hub *hub,
usb_hub_power_on(hub); usb_hub_power_on(hub);
return 0; return 0;
fail:
dev_err (hub->intf->dev, "config failed, %s (err %d)\n",
message, ret);
/* hub_disconnect() frees urb and descriptor */
return ret;
} }
static void hub_disconnect(struct usb_interface *intf) static void hub_disconnect(struct usb_interface *intf)
...@@ -497,32 +501,27 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -497,32 +501,27 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* specs is not defined, but it works */ /* specs is not defined, but it works */
if ((desc->desc.bInterfaceSubClass != 0) && if ((desc->desc.bInterfaceSubClass != 0) &&
(desc->desc.bInterfaceSubClass != 1)) { (desc->desc.bInterfaceSubClass != 1)) {
err("invalid subclass (%d) for USB hub device #%d", descriptor_error:
desc->desc.bInterfaceSubClass, dev->devnum); dev_err (intf->dev, "bad descriptor, ignoring hub\n");
return -EIO; return -EIO;
} }
/* Multiple endpoints? What kind of mutant ninja-hub is this? */ /* Multiple endpoints? What kind of mutant ninja-hub is this? */
if (desc->desc.bNumEndpoints != 1) { if (desc->desc.bNumEndpoints != 1) {
err("invalid bNumEndpoints (%d) for USB hub device #%d", goto descriptor_error;
desc->desc.bNumEndpoints, dev->devnum);
return -EIO;
} }
endpoint = &desc->endpoint[0].desc; endpoint = &desc->endpoint[0].desc;
/* Output endpoint? Curiousier and curiousier.. */ /* Output endpoint? Curiousier and curiousier.. */
if (!(endpoint->bEndpointAddress & USB_DIR_IN)) { if (!(endpoint->bEndpointAddress & USB_DIR_IN)) {
err("Device #%d is hub class, but has output endpoint?", goto descriptor_error;
dev->devnum);
return -EIO;
} }
/* If it's not an interrupt endpoint, we'd better punt! */ /* If it's not an interrupt endpoint, we'd better punt! */
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
!= USB_ENDPOINT_XFER_INT) { != USB_ENDPOINT_XFER_INT) {
err("Device #%d is hub class, but endpoint is not interrupt?", goto descriptor_error;
dev->devnum);
return -EIO; return -EIO;
} }
...@@ -554,8 +553,6 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -554,8 +553,6 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
return 0; return 0;
} }
err("hub configuration failed for device at %s", dev->devpath);
hub_disconnect (intf); hub_disconnect (intf);
return -ENODEV; return -ENODEV;
} }
......
...@@ -494,7 +494,7 @@ static struct super_block *usb_get_sb(struct file_system_type *fs_type, ...@@ -494,7 +494,7 @@ static struct super_block *usb_get_sb(struct file_system_type *fs_type,
{ {
if (fs_type == &usbdevice_fs_type) if (fs_type == &usbdevice_fs_type)
printk (KERN_INFO "Please use the 'usbfs' filetype instead, " printk (KERN_INFO "Please use the 'usbfs' filetype instead, "
"the 'usbdevfs' name is depreciated.\n"); "the 'usbdevfs' name is deprecated.\n");
return get_sb_single(fs_type, flags, data, usbfs_fill_super); return get_sb_single(fs_type, flags, data, usbfs_fill_super);
} }
......
...@@ -58,7 +58,7 @@ static void ehci_hcd_free (struct usb_hcd *hcd) ...@@ -58,7 +58,7 @@ static void ehci_hcd_free (struct usb_hcd *hcd)
/* Allocate the key transfer structures from the previously allocated pool */ /* Allocate the key transfer structures from the previously allocated pool */
static void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma) static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
{ {
memset (qtd, 0, sizeof *qtd); memset (qtd, 0, sizeof *qtd);
qtd->qtd_dma = dma; qtd->qtd_dma = dma;
......
...@@ -80,7 +80,7 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token) ...@@ -80,7 +80,7 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token)
/* update halted (but potentially linked) qh */ /* update halted (but potentially linked) qh */
static void static inline void
qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
{ {
qh->hw_current = 0; qh->hw_current = 0;
...@@ -94,6 +94,8 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) ...@@ -94,6 +94,8 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
static inline void qtd_copy_status ( static inline void qtd_copy_status (
struct ehci_hcd *ehci, struct ehci_hcd *ehci,
struct urb *urb, struct urb *urb,
...@@ -106,7 +108,15 @@ static inline void qtd_copy_status ( ...@@ -106,7 +108,15 @@ static inline void qtd_copy_status (
urb->actual_length += length - QTD_LENGTH (token); urb->actual_length += length - QTD_LENGTH (token);
/* don't modify error codes */ /* don't modify error codes */
if (unlikely (urb->status == -EINPROGRESS && (token & QTD_STS_HALT))) { if (unlikely (urb->status != -EINPROGRESS))
return;
/* force cleanup after short read; not always an error */
if (unlikely (IS_SHORT_READ (token)))
urb->status = -EREMOTEIO;
/* serious "can't proceed" faults reported by the hardware */
if (token & QTD_STS_HALT) {
if (token & QTD_STS_BABBLE) { if (token & QTD_STS_BABBLE) {
/* FIXME "must" disable babbling device's port too */ /* FIXME "must" disable babbling device's port too */
urb->status = -EOVERFLOW; urb->status = -EOVERFLOW;
...@@ -158,13 +168,6 @@ static inline void qtd_copy_status ( ...@@ -158,13 +168,6 @@ static inline void qtd_copy_status (
} }
} }
} }
/* force cleanup after short read; not necessarily an error */
if (unlikely (urb->status == -EINPROGRESS
&& QTD_LENGTH (token) != 0
&& QTD_PID (token) == 1)) {
urb->status = -EREMOTEIO;
}
} }
static void static void
...@@ -215,26 +218,31 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs) ...@@ -215,26 +218,31 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
* Chases up to qh->hw_current. Returns number of completions called, * Chases up to qh->hw_current. Returns number of completions called,
* indicating how much "real" work we did. * indicating how much "real" work we did.
*/ */
#define HALT_BIT cpu_to_le32(QTD_STS_HALT)
static unsigned static unsigned
qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
{ {
struct ehci_qtd *qtd, *last; struct ehci_qtd *last = 0;
struct list_head *next, *qtd_list = &qh->qtd_list; struct list_head *entry, *tmp;
int unlink = 0, stopped = 0; int stopped = 0;
unsigned count = 0; unsigned count = 0;
if (unlikely (list_empty (&qh->qtd_list))) if (unlikely (list_empty (&qh->qtd_list)))
return count; return count;
/* scan QTDs till end of list, or we reach an active one */ /* remove de-activated QTDs from front of queue.
for (qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list), * after faults (including short reads), cleanup this urb
last = 0, next = 0; * then let the queue advance.
next != qtd_list; * if queue is stopped, handles unlinks.
last = qtd, qtd = list_entry (next, */
struct ehci_qtd, qtd_list)) { list_for_each_safe (entry, tmp, &qh->qtd_list) {
struct urb *urb = qtd->urb; struct ehci_qtd *qtd;
struct urb *urb;
u32 token = 0; u32 token = 0;
qtd = list_entry (entry, struct ehci_qtd, qtd_list);
urb = qtd->urb;
/* clean up any state from previous QTD ...*/ /* clean up any state from previous QTD ...*/
if (last) { if (last) {
if (likely (last->urb != urb)) { if (likely (last->urb != urb)) {
...@@ -244,74 +252,60 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) ...@@ -244,74 +252,60 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
ehci_qtd_free (ehci, last); ehci_qtd_free (ehci, last);
last = 0; last = 0;
} }
next = qtd->qtd_list.next;
/* QTDs at tail may be active if QH+HC are running, /* hardware copies qtd out of qh overlay */
* or when unlinking some urbs queued to this QH
*/
rmb (); rmb ();
token = le32_to_cpu (qtd->hw_token); token = le32_to_cpu (qtd->hw_token);
stopped = stopped stopped = stopped
|| (qh->qh_state == QH_STATE_IDLE) || (qh->qh_state == QH_STATE_IDLE)
|| (__constant_cpu_to_le32 (QTD_STS_HALT) || (HALT_BIT & qh->hw_token) != 0
& qh->hw_token) != 0 || (ehci->hcd.state == USB_STATE_HALT);
|| (ehci->hcd.state == USB_STATE_HALT)
|| (qh->hw_current == ehci->async->hw_alt_next);
// FIXME Remove the automagic unlink mode.
// Drivers can now clean up safely; it's their job.
//
// FIXME Removing it should fix the short read scenarios
// with "huge" urb data (more than one 16+KByte td) with
// the short read someplace other than the last data TD.
// Except the control case: 'retrigger' status ACKs.
/* fault: unlink the rest, since this qtd saw an error? */
if (unlikely ((token & QTD_STS_HALT) != 0)) {
unlink = 1;
/* status copied below */
/* QH halts only because of fault (above) or unlink (here). */
} else if (unlikely (stopped != 0)) {
/* unlinking everything because of HC shutdown? */
if (ehci->hcd.state == USB_STATE_HALT) {
unlink = 1;
/* explicit unlink, maybe starting here? */
} else if (qh->qh_state == QH_STATE_IDLE
&& (urb->status == -ECONNRESET
|| urb->status == -ESHUTDOWN
|| urb->status == -ENOENT)) {
unlink = 1;
/* QH halted to unlink urbs _after_ this? */
} else if (!unlink && (token & QTD_STS_ACTIVE) != 0) {
qtd = 0;
continue;
}
/* unlink the rest? once we start unlinking, after /* always clean up qtds the hc de-activated */
* a fault or explicit unlink, we unlink all later if ((token & QTD_STS_ACTIVE) == 0) {
* urbs. usb spec requires that for faults...
*/ /* magic dummy for short reads; won't advance */
if (unlink && urb->status == -EINPROGRESS) if (IS_SHORT_READ (token)
urb->status = -ECONNRESET; && !(token & QTD_STS_HALT)
&& ehci->async->hw_alt_next
== qh->hw_alt_next)
goto halt;
/* stop scanning when we reach qtds the hc is using */
} else if (likely (!stopped)) {
last = 0;
break;
/* Else QH is active, so we must not modify QTDs } else {
* that HC may be working on. No more qtds to check. /* ignore active qtds unless some previous qtd
* for the urb faulted (including short read) or
* its urb was canceled. we may patch qh or qtds.
*/ */
} else if (unlikely ((token & QTD_STS_ACTIVE) != 0)) { if ((token & QTD_STS_ACTIVE)
next = qtd_list; && urb->status == -EINPROGRESS) {
qtd = 0; last = 0;
continue; continue;
} }
if ((HALT_BIT & qh->hw_token) == 0) {
halt:
qh->hw_token |= HALT_BIT;
wmb ();
stopped = 1;
}
}
/* remove it from the queue */
spin_lock (&urb->lock); spin_lock (&urb->lock);
qtd_copy_status (ehci, urb, qtd->length, token); qtd_copy_status (ehci, urb, qtd->length, token);
spin_unlock (&urb->lock); spin_unlock (&urb->lock);
if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
last = list_entry (qtd->qtd_list.prev,
struct ehci_qtd, qtd_list);
last->hw_next = qtd->hw_next;
}
list_del (&qtd->qtd_list); list_del (&qtd->qtd_list);
last = qtd;
} }
/* last urb's completion might still need calling */ /* last urb's completion might still need calling */
...@@ -321,14 +315,18 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) ...@@ -321,14 +315,18 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
ehci_qtd_free (ehci, last); ehci_qtd_free (ehci, last);
} }
/* reactivate queue after error and driver's cleanup */ /* update qh after fault cleanup */
if (unlikely (stopped && !list_empty (&qh->qtd_list))) { if (unlikely ((HALT_BIT & qh->hw_token) != 0)) {
qh_update (ehci, qh, list_entry (qh->qtd_list.next, qh_update (ehci, qh,
list_empty (&qh->qtd_list)
? qh->dummy
: list_entry (qh->qtd_list.next,
struct ehci_qtd, qtd_list)); struct ehci_qtd, qtd_list));
} }
return count; return count;
} }
#undef HALT_BIT
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -536,10 +534,9 @@ clear_toggle (struct usb_device *udev, int ep, int is_out, struct ehci_qh *qh) ...@@ -536,10 +534,9 @@ clear_toggle (struct usb_device *udev, int ep, int is_out, struct ehci_qh *qh)
* there are additional complications: c-mask, maybe FSTNs. * there are additional complications: c-mask, maybe FSTNs.
*/ */
static struct ehci_qh * static struct ehci_qh *
ehci_qh_make ( qh_make (
struct ehci_hcd *ehci, struct ehci_hcd *ehci,
struct urb *urb, struct urb *urb,
struct list_head *qtd_list,
int flags int flags
) { ) {
struct ehci_qh *qh = ehci_qh_alloc (ehci, flags); struct ehci_qh *qh = ehci_qh_alloc (ehci, flags);
...@@ -649,27 +646,13 @@ ehci_qh_make ( ...@@ -649,27 +646,13 @@ ehci_qh_make (
/* NOTE: if (PIPE_INTERRUPT) { scheduler sets s-mask } */ /* NOTE: if (PIPE_INTERRUPT) { scheduler sets s-mask } */
/* init as halted, toggle clear, advance to dummy */
qh->qh_state = QH_STATE_IDLE; qh->qh_state = QH_STATE_IDLE;
qh->hw_info1 = cpu_to_le32 (info1); qh->hw_info1 = cpu_to_le32 (info1);
qh->hw_info2 = cpu_to_le32 (info2); qh->hw_info2 = cpu_to_le32 (info2);
qh_update (ehci, qh, qh->dummy);
/* initialize sw and hw queues with these qtds */ qh->hw_token = cpu_to_le32 (QTD_STS_HALT);
if (!list_empty (qtd_list)) { usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
struct ehci_qtd *qtd;
/* hc's list view ends with dummy td; we might update it */
qtd = list_entry (qtd_list->prev, struct ehci_qtd, qtd_list);
qtd->hw_next = QTD_NEXT (qh->dummy->qtd_dma);
list_splice (qtd_list, &qh->qtd_list);
qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list);
qh_update (ehci, qh, qtd);
} else {
qh->hw_qtd_next = qh->hw_alt_next = EHCI_LIST_END;
}
/* initialize data toggle state */
clear_toggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, qh);
return qh; return qh;
} }
#undef hb_mult #undef hb_mult
...@@ -736,6 +719,11 @@ static struct ehci_qh *qh_append_tds ( ...@@ -736,6 +719,11 @@ static struct ehci_qh *qh_append_tds (
struct ehci_qh *qh = 0; struct ehci_qh *qh = 0;
qh = (struct ehci_qh *) *ptr; qh = (struct ehci_qh *) *ptr;
if (unlikely (qh == 0)) {
/* can't sleep here, we have ehci->lock... */
qh = qh_make (ehci, urb, SLAB_ATOMIC);
*ptr = qh;
}
if (likely (qh != 0)) { if (likely (qh != 0)) {
struct ehci_qtd *qtd; struct ehci_qtd *qtd;
...@@ -766,8 +754,34 @@ static struct ehci_qh *qh_append_tds ( ...@@ -766,8 +754,34 @@ static struct ehci_qh *qh_append_tds (
} }
} }
/* append to tds already queued to this qh? */ /* FIXME: changing config or interface setting is not
if (unlikely (!list_empty (&qh->qtd_list) && qtd)) { * supported yet. preferred fix is for usbcore to tell
* us to clear out each endpoint's state, but...
*/
/* usb_clear_halt() means qh data toggle gets reset */
if (unlikely (!usb_gettoggle (urb->dev,
(epnum & 0x0f), !(epnum & 0x10)))
&& !usb_pipecontrol (urb->pipe)) {
/* "never happens": drivers do stall cleanup right */
if (qh->qh_state != QH_STATE_IDLE
&& (cpu_to_le32 (QTD_STS_HALT)
& qh->hw_token) == 0)
ehci_warn (ehci, "clear toggle dev%d "
"ep%d%s: not idle\n",
usb_pipedevice (urb->pipe),
epnum & 0x0f,
usb_pipein (urb->pipe)
? "in" : "out");
/* else we know this overlay write is safe */
clear_toggle (urb->dev,
epnum & 0x0f, !(epnum & 0x10), qh);
}
/* just one way to queue requests: swap with the dummy qtd.
* only hc or qh_completions() usually modify the overlay.
*/
if (likely (qtd != 0)) {
struct ehci_qtd *dummy; struct ehci_qtd *dummy;
dma_addr_t dma; dma_addr_t dma;
u32 token; u32 token;
...@@ -785,8 +799,10 @@ static struct ehci_qh *qh_append_tds ( ...@@ -785,8 +799,10 @@ static struct ehci_qh *qh_append_tds (
dma = dummy->qtd_dma; dma = dummy->qtd_dma;
*dummy = *qtd; *dummy = *qtd;
dummy->qtd_dma = dma; dummy->qtd_dma = dma;
list_del (&qtd->qtd_list); list_del (&qtd->qtd_list);
list_add (&dummy->qtd_list, qtd_list); list_add (&dummy->qtd_list, qtd_list);
__list_splice (qtd_list, qh->qtd_list.prev);
ehci_qtd_init (qtd, qtd->qtd_dma); ehci_qtd_init (qtd, qtd->qtd_dma);
qtd->hw_alt_next = ehci->async->hw_alt_next; qtd->hw_alt_next = ehci->async->hw_alt_next;
...@@ -802,36 +818,9 @@ static struct ehci_qh *qh_append_tds ( ...@@ -802,36 +818,9 @@ static struct ehci_qh *qh_append_tds (
wmb (); wmb ();
dummy->hw_token = token; dummy->hw_token = token;
/* no URB queued */ urb->hcpriv = qh_get (qh);
} else {
/* usb_clear_halt() means qh data toggle gets reset */
if (unlikely (!usb_gettoggle (urb->dev,
(epnum & 0x0f),
!(epnum & 0x10)))) {
clear_toggle (urb->dev,
epnum & 0x0f, !(epnum & 0x10), qh);
}
/* make sure hc sees current dummy at the end */
if (qtd) {
struct ehci_qtd *last_qtd;
last_qtd = list_entry (qtd_list->prev,
struct ehci_qtd, qtd_list);
last_qtd->hw_next = QTD_NEXT (
qh->dummy->qtd_dma);
qh_update (ehci, qh, qtd);
}
} }
list_splice (qtd_list, qh->qtd_list.prev);
} else {
/* can't sleep here, we have ehci->lock... */
qh = ehci_qh_make (ehci, urb, qtd_list, SLAB_ATOMIC);
*ptr = qh;
} }
if (qh)
urb->hcpriv = qh_get (qh);
return qh; return qh;
} }
......
/* -*- linux-c -*- */ /* -*- linux-c -*- */
/* /*
* Driver for USB Scanners (linux-2.4.18) * Driver for USB Scanners (linux-2.5.52)
* *
* Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
* *
...@@ -313,6 +313,19 @@ ...@@ -313,6 +313,19 @@
* - Changed maintainership from David E. Nelson to Brian * - Changed maintainership from David E. Nelson to Brian
* Beattie <beattie@beattie-home.net>. * Beattie <beattie@beattie-home.net>.
* *
* 0.4.9 12/19/2002
* - Added vendor/product ids for Nikon, Mustek, Plustek, Genius, Epson,
* Canon, Umax, Hewlett-Packard, Benq, Agfa, Minolta scanners.
* Thanks to Dieter Faulbaum <faulbaum@mail.bessy.de>, Stian Jordet
* <liste@jordet.nu>, "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>,
* "Jaeger, Gerhard" <gerhard@gjaeger.de>, Ira Childress
* <ichildress@mn.rr.com>, Till Kamppeter <till.kamppeter@gmx.net>,
* Ed Hamrick <EdHamrick@aol.com>, Oliver Schwartz
* <Oliver.Schwartz@gmx.de> and everyone else who sent ids.
* - Some Benq, Genius and Plustek ids are identified now.
* - Accept scanners with only one bulk (in) endpoint (thanks to Sergey
* Vlasov <vsu@mivlgu.murom.ru>).
*
* TODO * TODO
* - Remove the 2/3 endpoint limitation * - Remove the 2/3 endpoint limitation
* - Performance * - Performance
...@@ -502,6 +515,12 @@ write_scanner(struct file * file, const char * buffer, ...@@ -502,6 +515,12 @@ write_scanner(struct file * file, const char * buffer,
down(&(scn->sem)); down(&(scn->sem));
if (!scn->bulk_out_ep) {
/* This scanner does not have a bulk-out endpoint */
up(&(scn->sem));
return -EINVAL;
}
scn_minor = scn->scn_minor; scn_minor = scn->scn_minor;
obuf = scn->obuf; obuf = scn->obuf;
...@@ -896,15 +915,15 @@ probe_scanner(struct usb_interface *intf, ...@@ -896,15 +915,15 @@ probe_scanner(struct usb_interface *intf,
interface = intf->altsetting; interface = intf->altsetting;
/* /*
* Start checking for two bulk endpoints OR two bulk endpoints *and* one * Start checking for one or two bulk endpoints and an optional
* interrupt endpoint. If we have an interrupt endpoint go ahead and * interrupt endpoint. If we have an interrupt endpoint go ahead and
* setup the handler. FIXME: This is a future enhancement... * setup the handler. FIXME: This is a future enhancement...
*/ */
dbg("probe_scanner: Number of Endpoints:%d", (int) interface->desc.bNumEndpoints); dbg("probe_scanner: Number of Endpoints:%d", (int) interface->desc.bNumEndpoints);
if ((interface->desc.bNumEndpoints != 2) && (interface->desc.bNumEndpoints != 3)) { if ((interface->desc.bNumEndpoints < 1) || (interface->desc.bNumEndpoints > 3)) {
info("probe_scanner: Only two or three endpoints supported."); info("probe_scanner: Only 1, 2, or 3 endpoints supported.");
return -ENODEV; return -ENODEV;
} }
...@@ -944,6 +963,12 @@ probe_scanner(struct usb_interface *intf, ...@@ -944,6 +963,12 @@ probe_scanner(struct usb_interface *intf,
*/ */
switch(interface->desc.bNumEndpoints) { switch(interface->desc.bNumEndpoints) {
case 1:
if (!have_bulk_in) {
info("probe_scanner: One bulk-in endpoint required.");
return -EIO;
}
break;
case 2: case 2:
if (!have_bulk_in || !have_bulk_out) { if (!have_bulk_in || !have_bulk_out) {
info("probe_scanner: Two bulk endpoints required."); info("probe_scanner: Two bulk endpoints required.");
......
/* /*
* Driver for USB Scanners (linux-2.4.18) * Driver for USB Scanners (linux-2.5.52)
* *
* Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
* *
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
*/ */
// #define PV8630 // #define PV8630
#define DRIVER_VERSION "0.4.6" #define DRIVER_VERSION "0.4.9"
#define DRIVER_DESC "USB Scanner Driver" #define DRIVER_DESC "USB Scanner Driver"
#include <linux/usb.h> #include <linux/usb.h>
...@@ -70,19 +70,19 @@ MODULE_PARM_DESC(read_timeout, "User specified read timeout in seconds"); ...@@ -70,19 +70,19 @@ MODULE_PARM_DESC(read_timeout, "User specified read timeout in seconds");
// #define WR_DATA_DUMP /* DEBUG does not have to be defined. */ // #define WR_DATA_DUMP /* DEBUG does not have to be defined. */
static struct usb_device_id scanner_device_ids [] = { static struct usb_device_id scanner_device_ids [] = {
/* Acer */ /* Acer (now Benq) */
{ USB_DEVICE(0x04a5, 0x2060) }, /* Prisa Acerscan 620U & 640U (!)*/ { USB_DEVICE(0x04a5, 0x2060) }, /* 620U & 640U (!)*/
{ USB_DEVICE(0x04a5, 0x2040) }, /* Prisa AcerScan 620U (!) */ { USB_DEVICE(0x04a5, 0x2040) }, /* 620U (!) */
{ USB_DEVICE(0x04a5, 0x20c0) }, /* Prisa AcerScan 1240UT */ { USB_DEVICE(0x04a5, 0x20c0) }, /* 1240UT, 1240U */
{ USB_DEVICE(0x04a5, 0x2022) }, /* Vuego Scan Brisa 340U */ { USB_DEVICE(0x04a5, 0x2022) }, /* 340U */
{ USB_DEVICE(0x04a5, 0x1a20) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x1a20) }, /* Unknown - Oliver Schwartz */
{ USB_DEVICE(0x04a5, 0x1a2a) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x1a2a) }, /* Another 620U */
{ USB_DEVICE(0x04a5, 0x207e) }, /* Prisa 640BU */ { USB_DEVICE(0x04a5, 0x207e) }, /* 640BU */
{ USB_DEVICE(0x04a5, 0x20be) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x20be) }, /* Unknown - Oliver Schwartz */
{ USB_DEVICE(0x04a5, 0x20c0) }, /* Unknown - Oliver Schwartz */
{ USB_DEVICE(0x04a5, 0x20de) }, /* S2W 3300U */ { USB_DEVICE(0x04a5, 0x20de) }, /* S2W 3300U */
{ USB_DEVICE(0x04a5, 0x20b0) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x20b0) }, /* Benq 4300 */
{ USB_DEVICE(0x04a5, 0x20fe) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x20fe) }, /* Benq 5300 */
{ USB_DEVICE(0x04a5, 0x20fc) }, /* Benq 5000 */
/* Agfa */ /* Agfa */
{ USB_DEVICE(0x06bd, 0x0001) }, /* SnapScan 1212U */ { USB_DEVICE(0x06bd, 0x0001) }, /* SnapScan 1212U */
{ USB_DEVICE(0x06bd, 0x0002) }, /* SnapScan 1236U */ { USB_DEVICE(0x06bd, 0x0002) }, /* SnapScan 1236U */
...@@ -92,24 +92,37 @@ static struct usb_device_id scanner_device_ids [] = { ...@@ -92,24 +92,37 @@ static struct usb_device_id scanner_device_ids [] = {
{ USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */ { USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */
{ USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */ { USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */
{ USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */ { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */
{ USB_DEVICE(0x06bd, 0x2093) }, /* SnapScan e10*/
{ USB_DEVICE(0x06bd, 0x20ff) }, /* SnapScan e42*/
{ USB_DEVICE(0x06bd, 0x208f) }, /* SnapScan e50*/
{ USB_DEVICE(0x06bd, 0x20fd) }, /* SnapScan e52*/
/* Benq: see Acer */
/* Canon */ /* Canon */
{ USB_DEVICE(0x04a9, 0x2201) }, /* FB320U */
{ USB_DEVICE(0x04a9, 0x2205) }, /* FB1210U */
{ USB_DEVICE(0x04a9, 0x2202) }, /* CanoScan FB620U */ { USB_DEVICE(0x04a9, 0x2202) }, /* CanoScan FB620U */
{ USB_DEVICE(0x04a9, 0x2204) }, /* CanoScan FB630U/FB636U */ { USB_DEVICE(0x04a9, 0x2204) }, /* CanoScan FB630U/FB636U */
{ USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */ { USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */
{ USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */ { USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */
{ USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */ { USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */
{ USB_DEVICE(0x04a9, 0x220b) }, /* D646U */ { USB_DEVICE(0x04a9, 0x220b) }, /* D646U */
{ USB_DEVICE(0x04a9, 0x220d) }, /* CanoScan N670U/N676U/LIDE 20 */
{ USB_DEVICE(0x04a9, 0x220e) }, /* CanoScan N1240U/LIDE 30 */
{ USB_DEVICE(0x04a9, 0x3042) }, /* FS4000US */
/* Colorado -- See Primax/Colorado below */ /* Colorado -- See Primax/Colorado below */
/* Epson -- See Seiko/Epson below */ /* Epson -- See Seiko/Epson below */
/* Genius */ /* Genius */
{ USB_DEVICE(0x0458, 0x2001) }, /* ColorPage-Vivid Pro */ { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage-Vivid Pro */
{ USB_DEVICE(0x0458, 0x2007) }, /* ColorPage HR6 V2 */ { USB_DEVICE(0x0458, 0x2007) }, /* ColorPage HR6 V2 */
{ USB_DEVICE(0x0458, 0x2008) }, /* Unknown */ { USB_DEVICE(0x0458, 0x2008) }, /* ColorPage-HR6 V2 */
{ USB_DEVICE(0x0458, 0x2009) }, /* Unknown */ { USB_DEVICE(0x0458, 0x2009) }, /* ColorPage-HR6A */
{ USB_DEVICE(0x0458, 0x2013) }, /* Unknown */ { USB_DEVICE(0x0458, 0x2011) }, /* ColorPage-Vivid3x */
{ USB_DEVICE(0x0458, 0x2015) }, /* Unknown */ { USB_DEVICE(0x0458, 0x2013) }, /* ColorPage-HR7 */
{ USB_DEVICE(0x0458, 0x2016) }, /* Unknown */ { USB_DEVICE(0x0458, 0x2015) }, /* ColorPage-HR7LE */
{ USB_DEVICE(0x0458, 0x2016) }, /* ColorPage-HR6X */
/* Hewlett Packard */ /* Hewlett Packard */
{ USB_DEVICE(0x03f0, 0x0505) }, /* ScanJet 2100C */
{ USB_DEVICE(0x03f0, 0x0901) }, /* 2300C */
{ USB_DEVICE(0x03f0, 0x0205) }, /* 3300C */ { USB_DEVICE(0x03f0, 0x0205) }, /* 3300C */
{ USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */ { USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */
{ USB_DEVICE(0x03f0, 0x0101) }, /* 4100C */ { USB_DEVICE(0x03f0, 0x0101) }, /* 4100C */
...@@ -124,6 +137,8 @@ static struct usb_device_id scanner_device_ids [] = { ...@@ -124,6 +137,8 @@ static struct usb_device_id scanner_device_ids [] = {
{ USB_DEVICE(0x03f0, 0x605) }, /* 2200C */ { USB_DEVICE(0x03f0, 0x605) }, /* 2200C */
/* iVina */ /* iVina */
{ USB_DEVICE(0x0638, 0x0268) }, /* 1200U */ { USB_DEVICE(0x0638, 0x0268) }, /* 1200U */
/* Lexmark */
{ USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */
/* Lifetec */ /* Lifetec */
{ USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */ { USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */
/* Memorex */ /* Memorex */
...@@ -138,31 +153,44 @@ static struct usb_device_id scanner_device_ids [] = { ...@@ -138,31 +153,44 @@ static struct usb_device_id scanner_device_ids [] = {
// { USB_DEVICE(0x05da, 0x80ac) }, /* ScanMaker V6UL - SpicyU */ // { USB_DEVICE(0x05da, 0x80ac) }, /* ScanMaker V6UL - SpicyU */
/* Minolta */ /* Minolta */
// { USB_DEVICE(0x0638,0x026a) }, /* Minolta Dimage Scan Dual II */ // { USB_DEVICE(0x0638,0x026a) }, /* Minolta Dimage Scan Dual II */
// { USB_DEVICE(0x0686, 0x4004) }, /* Scan Elite II (need interrupt ep) */
{ USB_DEVICE(0x0686, 0x400d) }, /* Scan Dual III */
/* Mustek */ /* Mustek */
{ USB_DEVICE(0x055f, 0x0001) }, /* 1200 CU */ { USB_DEVICE(0x055f, 0x0001) }, /* ScanExpress 1200 CU */
{ USB_DEVICE(0x0400, 0x1000) }, /* BearPaw 1200 */ { USB_DEVICE(0x0400, 0x1000) }, /* BearPaw 1200 */
{ USB_DEVICE(0x055f, 0x0002) }, /* 600 CU */ { USB_DEVICE(0x055f, 0x0002) }, /* ScanExpress 600 CU */
{ USB_DEVICE(0x055f, 0x0873) }, /* 600 USB */ { USB_DEVICE(0x055f, 0x0873) }, /* ScanExpress 600 USB */
{ USB_DEVICE(0x055f, 0x0003) }, /* 1200 USB */ { USB_DEVICE(0x055f, 0x0003) }, /* ScanExpress 1200 USB */
{ USB_DEVICE(0x055f, 0x0006) }, /* 1200 UB */ { USB_DEVICE(0x055f, 0x0006) }, /* ScanExpress 1200 UB */
{ USB_DEVICE(0x055f, 0x0007) }, /* ScanExpress 1200 USB Plus */
{ USB_DEVICE(0x055f, 0x0210) }, /* ScanExpress A3 USB */
{ USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */ { USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */
{ USB_DEVICE(0x055f, 0x0008) }, /* 1200 CU Plus */ { USB_DEVICE(0x055f, 0x0008) }, /* ScanExpress 1200 CU Plus */
{ USB_DEVICE(0x0ff5, 0x0010) }, /* BearPaw 1200F */ { USB_DEVICE(0x055f, 0x0010) }, /* BearPaw 1200F */
{ USB_DEVICE(0x055f, 0x0218) }, /* BearPaw 2400 TA */ { USB_DEVICE(0x055f, 0x0218) }, /* BearPaw 2400 TA */
{ USB_DEVICE(0x05d8, 0x4002) }, /* 1200 CU and 1200 UB Plus */ { USB_DEVICE(0x05d8, 0x4002) }, /* BearPaw 1200 CU and ScanExpress 1200 UB Plus */
{ USB_DEVICE(0x055f, 0x0219) }, /* BearPaw 2400 TA Plus */
{ USB_DEVICE(0x055f, 0x021c) }, /* BearPaw 1200 CU Plus */
{ USB_DEVICE(0x055f, 0x021d) }, /* Bearpaw 2400 CU Plus */
{ USB_DEVICE(0x055f, 0x021e) }, /* BearPaw 1200 TA/CS */
{ USB_DEVICE(0x055f, 0x0400) }, /* BearPaw 2400 TA PRO */
{ USB_DEVICE(0x055f, 0x1000) }, /* BearPaw 4800 TA PRO */
/* Nikon */
{ USB_DEVICE(0x04b0, 0x4000) }, /* Coolscan LS 40 ED */
/* Plustek */ /* Plustek */
{ USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12 */ { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */
{ USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro UT24 */ { USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro U24 */
{ USB_DEVICE(0x07b3, 0x0010) }, /* OpticPro U12 */
{ USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */
{ USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */
{ USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */
{ USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */
{ USB_DEVICE(0x07b3, 0x0010) }, /* Unknown */
{ USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */
{ USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */
{ USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */
{ USB_DEVICE(0x07b3, 0x0015) }, /* Unknown */
{ USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */
{ USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */
{ USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U */
/* Primax/Colorado */ /* Primax/Colorado */
{ USB_DEVICE(0x0461, 0x0300) }, /* G2-300 #1 */ { USB_DEVICE(0x0461, 0x0300) }, /* G2-300 #1 */
{ USB_DEVICE(0x0461, 0x0380) }, /* G2-600 #1 */ { USB_DEVICE(0x0461, 0x0380) }, /* G2-600 #1 */
...@@ -180,24 +208,32 @@ static struct usb_device_id scanner_device_ids [] = { ...@@ -180,24 +208,32 @@ static struct usb_device_id scanner_device_ids [] = {
// { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */ // { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */
/* Seiko/Epson Corp. */ /* Seiko/Epson Corp. */
{ USB_DEVICE(0x04b8, 0x0101) }, /* Perfection 636U and 636Photo */ { USB_DEVICE(0x04b8, 0x0101) }, /* Perfection 636U and 636Photo */
{ USB_DEVICE(0x04b8, 0x0102) }, /* GT-2200 */
{ USB_DEVICE(0x04b8, 0x0103) }, /* Perfection 610 */ { USB_DEVICE(0x04b8, 0x0103) }, /* Perfection 610 */
{ USB_DEVICE(0x04b8, 0x0104) }, /* Perfection 1200U and 1200Photo*/ { USB_DEVICE(0x04b8, 0x0104) }, /* Perfection 1200U and 1200Photo*/
{ USB_DEVICE(0x04b8, 0x0105) }, /* StylusScan 2000 */
{ USB_DEVICE(0x04b8, 0x0106) }, /* Stylus Scan 2500 */ { USB_DEVICE(0x04b8, 0x0106) }, /* Stylus Scan 2500 */
{ USB_DEVICE(0x04b8, 0x0107) }, /* Expression 1600 */ { USB_DEVICE(0x04b8, 0x0107) }, /* Expression 1600 */
{ USB_DEVICE(0x04b8, 0x0109) }, /* Expression 1640XL */
{ USB_DEVICE(0x04b8, 0x010a) }, /* Perfection 1640SU and 1640SU Photo */ { USB_DEVICE(0x04b8, 0x010a) }, /* Perfection 1640SU and 1640SU Photo */
{ USB_DEVICE(0x04b8, 0x010b) }, /* Perfection 1240U */ { USB_DEVICE(0x04b8, 0x010b) }, /* Perfection 1240U */
{ USB_DEVICE(0x04b8, 0x010c) }, /* Perfection 640U */ { USB_DEVICE(0x04b8, 0x010c) }, /* Perfection 640U */
{ USB_DEVICE(0x04b8, 0x010e) }, /* Expression 1680 */ { USB_DEVICE(0x04b8, 0x010e) }, /* Expression 1680 */
{ USB_DEVICE(0x04a9, 0x2204) }, /* FB630U */ { USB_DEVICE(0x04b8, 0x010f) }, /* Perfection 1250U */
{ USB_DEVICE(0x04b8, 0x0110) }, /* Perfection 1650 */ { USB_DEVICE(0x04b8, 0x0110) }, /* Perfection 1650 */
{ USB_DEVICE(0x04b8, 0x0112) }, /* Perfection 2450 - GT-9700 for the Japanese mkt */ { USB_DEVICE(0x04b8, 0x0112) }, /* Perfection 2450 - GT-9700 for the Japanese mkt */
{ USB_DEVICE(0x04b8, 0x0114) }, /* Perfection 660 */ { USB_DEVICE(0x04b8, 0x0114) }, /* Perfection 660 */
{ USB_DEVICE(0x04b8, 0x011b) }, /* Perfection 2400 Photo */ { USB_DEVICE(0x04b8, 0x011b) }, /* Perfection 2400 Photo */
{ USB_DEVICE(0x04b8, 0x011c) }, /* Perfection 3200 */
{ USB_DEVICE(0x04b8, 0x011d) }, /* Perfection 1260 */
{ USB_DEVICE(0x04b8, 0x011e) }, /* Perfection 1660 Photo */ { USB_DEVICE(0x04b8, 0x011e) }, /* Perfection 1660 Photo */
{ USB_DEVICE(0x04b8, 0x0802) }, /* Stylus CX3200 */
/* Umax */ /* Umax */
{ USB_DEVICE(0x1606, 0x0010) }, /* Astra 1220U */ { USB_DEVICE(0x1606, 0x0010) }, /* Astra 1220U */
{ USB_DEVICE(0x1606, 0x0030) }, /* Astra 2000U */ { USB_DEVICE(0x1606, 0x0030) }, /* Astra 2000U */
{ USB_DEVICE(0x1606, 0x0060) }, /* Astra 3400U/3450U */
{ USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */ { USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */
{ USB_DEVICE(0x1606, 0x0160) }, /* Astra 5400U */
{ USB_DEVICE(0x1606, 0x0230) }, /* Astra 2200U */ { USB_DEVICE(0x1606, 0x0230) }, /* Astra 2200U */
/* Visioneer */ /* Visioneer */
{ USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */ { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */
......
...@@ -87,11 +87,11 @@ typedef struct { ...@@ -87,11 +87,11 @@ typedef struct {
} ibmcam_t; } ibmcam_t;
#define IBMCAM_T(uvd) ((ibmcam_t *)((uvd)->user_data)) #define IBMCAM_T(uvd) ((ibmcam_t *)((uvd)->user_data))
struct usbvideo *cams = NULL; static struct usbvideo *cams;
static int debug = 0; static int debug;
static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */ static int flags; /* = FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
static const int min_canvasWidth = 8; static const int min_canvasWidth = 8;
static const int min_canvasHeight = 4; static const int min_canvasHeight = 4;
......
...@@ -147,7 +147,7 @@ struct usb_stv { ...@@ -147,7 +147,7 @@ struct usb_stv {
}; };
unsigned char red[256] = { static unsigned char red[256] = {
0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42,
44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69,
...@@ -172,7 +172,7 @@ unsigned char red[256] = { ...@@ -172,7 +172,7 @@ unsigned char red[256] = {
220, 220, 221, 221 220, 220, 221, 221
}; };
unsigned char green[256] = { static unsigned char green[256] = {
0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47,
50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77,
...@@ -197,7 +197,7 @@ unsigned char green[256] = { ...@@ -197,7 +197,7 @@ unsigned char green[256] = {
245, 245, 246, 246 245, 245, 246, 246
}; };
unsigned char blue[256] = { static unsigned char blue[256] = {
0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51,
55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84,
......
...@@ -146,6 +146,7 @@ static const char udsl_driver_name[] = "Alcatel SpeedTouch USB"; ...@@ -146,6 +146,7 @@ static const char udsl_driver_name[] = "Alcatel SpeedTouch USB";
/* data thread */ /* data thread */
DECLARE_WAIT_QUEUE_HEAD (udsl_wqh); DECLARE_WAIT_QUEUE_HEAD (udsl_wqh);
static DECLARE_COMPLETION(thread_grave); static DECLARE_COMPLETION(thread_grave);
static DECLARE_MUTEX(udsl_usb_ioctl_lock);
static unsigned int datapid; static unsigned int datapid;
#ifdef DEBUG_PACKET #ifdef DEBUG_PACKET
...@@ -582,7 +583,6 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs) ...@@ -582,7 +583,6 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs)
struct udsl_usb_send_data_context *ctx = (struct udsl_usb_send_data_context *) urb->context; struct udsl_usb_send_data_context *ctx = (struct udsl_usb_send_data_context *) urb->context;
struct udsl_instance_data *instance = ctx->instance; struct udsl_instance_data *instance = ctx->instance;
int err; int err;
unsigned long flags;
PDEBUG ("udsl_usb_send_data_completion (vcc = %p, skb = %p, status %d)\n", ctx->vcc, PDEBUG ("udsl_usb_send_data_completion (vcc = %p, skb = %p, status %d)\n", ctx->vcc,
ctx->skb, urb->status); ctx->skb, urb->status);
...@@ -590,15 +590,15 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs) ...@@ -590,15 +590,15 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs)
ctx->vcc->pop (ctx->vcc, ctx->skb); ctx->vcc->pop (ctx->vcc, ctx->skb);
ctx->skb = NULL; ctx->skb = NULL;
spin_lock_irqsave (&instance->sndqlock, flags); spin_lock (&instance->sndqlock);
if (skb_queue_empty (&instance->sndqueue)) { if (skb_queue_empty (&instance->sndqueue)) {
spin_unlock_irqrestore (&instance->sndqlock, flags); spin_unlock (&instance->sndqlock);
return; return;
} }
/* submit next skb */ /* submit next skb */
ctx->skb = skb_dequeue (&(instance->sndqueue)); ctx->skb = skb_dequeue (&(instance->sndqueue));
ctx->vcc = ((struct udsl_cb *) (ctx->skb->cb))->vcc; ctx->vcc = ((struct udsl_cb *) (ctx->skb->cb))->vcc;
spin_unlock_irqrestore (&instance->sndqlock, flags); spin_unlock (&instance->sndqlock);
usb_fill_bulk_urb (urb, usb_fill_bulk_urb (urb,
instance->usb_dev, instance->usb_dev,
usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
...@@ -614,9 +614,7 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs) ...@@ -614,9 +614,7 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs)
int udsl_usb_cancelsends (struct udsl_instance_data *instance, struct atm_vcc *vcc) int udsl_usb_cancelsends (struct udsl_instance_data *instance, struct atm_vcc *vcc)
{ {
int i; int i;
unsigned long flags;
spin_lock_irqsave (&instance->sndqlock, flags);
for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) { for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) {
if (!instance->send_ctx[i].skb) if (!instance->send_ctx[i].skb)
continue; continue;
...@@ -628,7 +626,6 @@ int udsl_usb_cancelsends (struct udsl_instance_data *instance, struct atm_vcc *v ...@@ -628,7 +626,6 @@ int udsl_usb_cancelsends (struct udsl_instance_data *instance, struct atm_vcc *v
instance->send_ctx[i].skb = NULL; instance->send_ctx[i].skb = NULL;
} }
} }
spin_unlock_irqrestore (&instance->sndqlock, flags);
return 0; return 0;
} }
...@@ -702,7 +699,6 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs) ...@@ -702,7 +699,6 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
{ {
struct udsl_data_ctx *ctx; struct udsl_data_ctx *ctx;
struct udsl_instance_data *instance; struct udsl_instance_data *instance;
unsigned long flags;
if (!urb) if (!urb)
return; return;
...@@ -724,9 +720,9 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs) ...@@ -724,9 +720,9 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
skb_put (ctx->skb, urb->actual_length); skb_put (ctx->skb, urb->actual_length);
/* queue the skb for processing and wake the SAR */ /* queue the skb for processing and wake the SAR */
spin_lock_irqsave (&instance->recvqlock, flags); spin_lock (&instance->recvqlock);
skb_queue_tail (&instance->recvqueue, ctx->skb); skb_queue_tail (&instance->recvqueue, ctx->skb);
spin_unlock_irqrestore (&instance->recvqlock, flags); spin_unlock (&instance->recvqlock);
wake_up (&udsl_wqh); wake_up (&udsl_wqh);
/* get a new skb */ /* get a new skb */
ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE); ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE);
...@@ -737,9 +733,6 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs) ...@@ -737,9 +733,6 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
return; return;
} }
break; break;
case -EPIPE: /* stall or babble */
usb_clear_halt (urb->dev, usb_rcvbulkpipe (urb->dev, UDSL_ENDPOINT_DATA_IN));
break;
case -ENOENT: /* buffer was unlinked */ case -ENOENT: /* buffer was unlinked */
case -EILSEQ: /* unplug or timeout */ case -EILSEQ: /* unplug or timeout */
case -ETIMEDOUT: /* unplug or timeout */ case -ETIMEDOUT: /* unplug or timeout */
...@@ -895,7 +888,7 @@ static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void * ...@@ -895,7 +888,7 @@ static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *
{ {
struct usb_device *dev = interface_to_usbdev (intf); struct usb_device *dev = interface_to_usbdev (intf);
struct udsl_instance_data *instance; struct udsl_instance_data *instance;
int i; int i,retval;
for (i = 0; i < MAX_UDSL; i++) for (i = 0; i < MAX_UDSL; i++)
if (minor_data[i] && (minor_data[i]->usb_dev == dev)) if (minor_data[i] && (minor_data[i]->usb_dev == dev))
...@@ -906,17 +899,20 @@ static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void * ...@@ -906,17 +899,20 @@ static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *
instance = minor_data[i]; instance = minor_data[i];
down(&udsl_usb_ioctl_lock);
switch (code) { switch (code) {
case UDSL_IOCTL_START: case UDSL_IOCTL_START:
return udsl_usb_data_init (instance); retval = udsl_usb_data_init (instance);
break; break;
case UDSL_IOCTL_STOP: case UDSL_IOCTL_STOP:
return udsl_usb_data_exit (instance); retval = udsl_usb_data_exit (instance);
break; break;
default: default:
retval = -ENOTTY;
break; break;
} }
return -EINVAL; up(&udsl_usb_ioctl_lock);
return retval;
} }
static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id) static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
...@@ -998,11 +994,6 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -998,11 +994,6 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
PDEBUG ("disconnecting minor %d\n", i); PDEBUG ("disconnecting minor %d\n", i);
while (MOD_IN_USE > 1) {
current->state = TASK_INTERRUPTIBLE;
schedule_timeout (1);
}
kfree (instance); kfree (instance);
minor_data[i] = NULL; minor_data[i] = NULL;
......
...@@ -132,7 +132,7 @@ static void read_bulk_callback( struct urb *urb, struct pt_regs *regs ) ...@@ -132,7 +132,7 @@ static void read_bulk_callback( struct urb *urb, struct pt_regs *regs )
// Give this to the USB subsystem so it can tell us // Give this to the USB subsystem so it can tell us
// when more data arrives. // when more data arrives.
if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_KERNEL)) ) { if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_ATOMIC)) ) {
warn("%s failed submint rx_urb %d", __FUNCTION__, res); warn("%s failed submint rx_urb %d", __FUNCTION__, res);
} }
...@@ -302,7 +302,7 @@ static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net ) ...@@ -302,7 +302,7 @@ static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net )
ether_dev->tx_urb->transfer_buffer_length = count; ether_dev->tx_urb->transfer_buffer_length = count;
// Send the URB on its merry way. // Send the URB on its merry way.
if ((res = usb_submit_urb(ether_dev->tx_urb, GFP_KERNEL))) { if ((res = usb_submit_urb(ether_dev->tx_urb, GFP_ATOMIC))) {
// Hmm... It didn't go. Tell someone... // Hmm... It didn't go. Tell someone...
warn("failed tx_urb %d", res); warn("failed tx_urb %d", res);
// update some stats... // update some stats...
......
...@@ -827,7 +827,7 @@ static void keyspan_pda_shutdown (struct usb_serial *serial) ...@@ -827,7 +827,7 @@ static void keyspan_pda_shutdown (struct usb_serial *serial)
static struct usb_serial_device_type keyspan_pda_fake_device = { static struct usb_serial_device_type keyspan_pda_fake_device = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "Keyspan PDA - (prerenumeration)", .name = "Keyspan PDA - (prerenumeration)",
.short_name = "kyspn_pda_nofirm", .short_name = "keyspan_pda_pre",
.id_table = id_table_fake, .id_table = id_table_fake,
.num_interrupt_in = NUM_DONT_CARE, .num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE,
...@@ -841,7 +841,7 @@ static struct usb_serial_device_type keyspan_pda_fake_device = { ...@@ -841,7 +841,7 @@ static struct usb_serial_device_type keyspan_pda_fake_device = {
static struct usb_serial_device_type xircom_pgs_fake_device = { static struct usb_serial_device_type xircom_pgs_fake_device = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "Xircom / Entregra PGS - (prerenumeration)", .name = "Xircom / Entregra PGS - (prerenumeration)",
.short_name = "xircom_nofirm", .short_name = "xircom_no_firm",
.id_table = id_table_fake_xircom, .id_table = id_table_fake_xircom,
.num_interrupt_in = NUM_DONT_CARE, .num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE,
......
...@@ -396,22 +396,21 @@ extern int firmware_register(struct subsystem *); ...@@ -396,22 +396,21 @@ extern int firmware_register(struct subsystem *);
extern void firmware_unregister(struct subsystem *); extern void firmware_unregister(struct subsystem *);
/* debugging and troubleshooting/diagnostic helpers. */ /* debugging and troubleshooting/diagnostic helpers. */
#define dev_printk(sev, dev, format, arg...) \
printk(sev "%s %s: " format , (dev).driver->name , (dev).bus_id , ## arg)
#ifdef DEBUG #ifdef DEBUG
#define dev_dbg(dev, format, arg...) \ #define dev_dbg(dev, format, arg...) \
printk (KERN_DEBUG "%s %s: " format , \ dev_printk(KERN_DEBUG , (dev) , format , ## arg)
(dev).driver->name , (dev).bus_id , ## arg)
#else #else
#define dev_dbg(dev, format, arg...) do {} while (0) #define dev_dbg(dev, format, arg...) do {} while (0)
#endif #endif
#define dev_err(dev, format, arg...) \ #define dev_err(dev, format, arg...) \
printk (KERN_ERR "%s %s: " format , \ dev_printk(KERN_ERR , (dev) , format , ## arg)
(dev).driver->name , (dev).bus_id , ## arg)
#define dev_info(dev, format, arg...) \ #define dev_info(dev, format, arg...) \
printk (KERN_INFO "%s %s: " format , \ dev_printk(KERN_INFO , (dev) , format , ## arg)
(dev).driver->name , (dev).bus_id , ## arg)
#define dev_warn(dev, format, arg...) \ #define dev_warn(dev, format, arg...) \
printk (KERN_WARNING "%s %s: " format , \ dev_printk(KERN_WARNING , (dev) , format , ## arg)
(dev).driver->name , (dev).bus_id , ## arg)
#endif /* _DEVICE_H_ */ #endif /* _DEVICE_H_ */
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