diff options
| author | Paul Mackerras <paulus@samba.org> | 2002-12-24 08:21:27 +1100 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2002-12-24 08:21:27 +1100 |
| commit | 75528e466f18a2f2cd431f6c3fe27119317bb629 (patch) | |
| tree | c124ec63485ef54cf644ecb80461e4adb5173032 | |
| parent | aeb24f2986ff9471fd062e50815466b0c6415b52 (diff) | |
| parent | 5e163a89fedacf47100735e738c43687d3bf18a2 (diff) | |
Merge samba.org:/home/paulus/kernel/linux-2.5
into samba.org:/home/paulus/kernel/for-linus-ppc
| -rw-r--r-- | arch/alpha/vmlinux.lds.S | 6 | ||||
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 2 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.c | 12 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 57 | ||||
| -rw-r--r-- | drivers/usb/core/inode.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-mem.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-q.c | 245 | ||||
| -rw-r--r-- | drivers/usb/image/scanner.c | 33 | ||||
| -rw-r--r-- | drivers/usb/image/scanner.h | 96 | ||||
| -rw-r--r-- | drivers/usb/media/ibmcam.c | 6 | ||||
| -rw-r--r-- | drivers/usb/media/stv680.h | 6 | ||||
| -rw-r--r-- | drivers/usb/misc/speedtouch.c | 35 | ||||
| -rw-r--r-- | drivers/usb/net/cdc-ether.c | 4 | ||||
| -rw-r--r-- | drivers/usb/serial/keyspan_pda.c | 4 | ||||
| -rw-r--r-- | include/asm-generic/dma-mapping.h | 2 | ||||
| -rw-r--r-- | include/asm-generic/pci-dma-compat.h | 87 | ||||
| -rw-r--r-- | include/asm-i386/pci.h | 6 | ||||
| -rw-r--r-- | include/asm-i386/spinlock.h | 2 | ||||
| -rw-r--r-- | include/linux/device.h | 15 | ||||
| -rw-r--r-- | include/linux/pci.h | 86 |
20 files changed, 380 insertions, 328 deletions
diff --git a/arch/alpha/vmlinux.lds.S b/arch/alpha/vmlinux.lds.S index f6e1728c92ff..ac8106a4ea20 100644 --- a/arch/alpha/vmlinux.lds.S +++ b/arch/alpha/vmlinux.lds.S @@ -55,6 +55,12 @@ SECTIONS __setup_end = .; } + __param ALIGN(8): { + __start___param = .; + *(__param) + __stop___param = .; + } + .initcall.init ALIGN(8): { __initcall_start = .; *(.initcall1.init) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 86b6939681bd..9729e3618d42 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -278,7 +278,7 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) urb->actual_length = 0; urb->dev = acm->dev; - if (usb_submit_urb(urb, GFP_KERNEL)) + if (usb_submit_urb(urb, GFP_ATOMIC)) dbg("failed resubmitting read urb"); } diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 075c3c2a62e3..74a3993826fd 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1022,7 +1022,10 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) * they could clobber root hub response data. */ 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 */ @@ -1043,7 +1046,10 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) : 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) * FIXME use better explicit urb state */ if (urb->status != -EINPROGRESS) { - retval = -EINVAL; + retval = -EBUSY; goto done; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 22245f2d4832..3ccdaf5bdb65 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -279,12 +279,13 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_hub_status hubstatus; unsigned int pipe; int maxp, ret; + char *message; hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); if (!hub->descriptor) { - err("Unable to kmalloc %Zd bytes for hub descriptor", - sizeof(*hub->descriptor)); - return -1; + message = "can't kmalloc hub descriptor"; + ret = -ENOMEM; + goto fail; } /* Request the entire hub descriptor. @@ -294,13 +295,12 @@ static int usb_hub_configure(struct usb_hub *hub, ret = usb_get_hub_descriptor(dev, hub->descriptor, sizeof(*hub->descriptor)); if (ret < 0) { - err("Unable to get hub descriptor (err = %d)", ret); - kfree(hub->descriptor); - return -1; + message = "can't read hub descriptor"; + goto fail; } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) { - err("Hub is too big! %d children", hub->descriptor->bNbrPorts); - kfree(hub->descriptor); - return -1; + message = "hub has too many ports!"; + ret = -ENODEV; + goto fail; } dev->maxchild = hub->descriptor->bNbrPorts; @@ -396,9 +396,8 @@ static int usb_hub_configure(struct usb_hub *hub, ret = usb_get_hub_status(dev, &hubstatus); if (ret < 0) { - err("Unable to get hub status (err = %d)", ret); - kfree(hub->descriptor); - return -1; + message = "can't get hub status"; + goto fail; } le16_to_cpus(&hubstatus.wHubStatus); @@ -419,18 +418,17 @@ static int usb_hub_configure(struct usb_hub *hub, hub->urb = usb_alloc_urb(0, GFP_KERNEL); if (!hub->urb) { - err("couldn't allocate interrupt urb"); - kfree(hub->descriptor); - return -1; + message = "couldn't allocate interrupt urb"; + ret = -ENOMEM; + goto fail; } usb_fill_int_urb(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq, hub, endpoint->bInterval); ret = usb_submit_urb(hub->urb, GFP_KERNEL); if (ret) { - err("usb_submit_urb failed (%d)", ret); - kfree(hub->descriptor); - return -1; + message = "couldn't submit status urb"; + goto fail; } /* Wake up khubd */ @@ -439,6 +437,12 @@ static int usb_hub_configure(struct usb_hub *hub, usb_hub_power_on(hub); 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) @@ -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 */ if ((desc->desc.bInterfaceSubClass != 0) && (desc->desc.bInterfaceSubClass != 1)) { - err("invalid subclass (%d) for USB hub device #%d", - desc->desc.bInterfaceSubClass, dev->devnum); +descriptor_error: + dev_err (intf->dev, "bad descriptor, ignoring hub\n"); return -EIO; } /* Multiple endpoints? What kind of mutant ninja-hub is this? */ if (desc->desc.bNumEndpoints != 1) { - err("invalid bNumEndpoints (%d) for USB hub device #%d", - desc->desc.bNumEndpoints, dev->devnum); - return -EIO; + goto descriptor_error; } endpoint = &desc->endpoint[0].desc; /* Output endpoint? Curiousier and curiousier.. */ if (!(endpoint->bEndpointAddress & USB_DIR_IN)) { - err("Device #%d is hub class, but has output endpoint?", - dev->devnum); - return -EIO; + goto descriptor_error; } /* If it's not an interrupt endpoint, we'd better punt! */ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) { - err("Device #%d is hub class, but endpoint is not interrupt?", - dev->devnum); + goto descriptor_error; return -EIO; } @@ -554,8 +553,6 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) return 0; } - err("hub configuration failed for device at %s", dev->devpath); - hub_disconnect (intf); return -ENODEV; } diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index bceafa9b8966..2dfda57eaebf 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -494,7 +494,7 @@ static struct super_block *usb_get_sb(struct file_system_type *fs_type, { if (fs_type == &usbdevice_fs_type) 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); } diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 1ecaa0dda389..beded1eb2269 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -58,7 +58,7 @@ static void ehci_hcd_free (struct usb_hcd *hcd) /* 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); qtd->qtd_dma = dma; diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 1948de4eb2a9..699c191b70f5 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -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 */ -static void +static inline void qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) { qh->hw_current = 0; @@ -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 ( struct ehci_hcd *ehci, struct urb *urb, @@ -106,7 +108,15 @@ static inline void qtd_copy_status ( urb->actual_length += length - QTD_LENGTH (token); /* 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) { /* FIXME "must" disable babbling device's port too */ urb->status = -EOVERFLOW; @@ -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 @@ -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, * indicating how much "real" work we did. */ +#define HALT_BIT cpu_to_le32(QTD_STS_HALT) static unsigned qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) { - struct ehci_qtd *qtd, *last; - struct list_head *next, *qtd_list = &qh->qtd_list; - int unlink = 0, stopped = 0; + struct ehci_qtd *last = 0; + struct list_head *entry, *tmp; + int stopped = 0; unsigned count = 0; if (unlikely (list_empty (&qh->qtd_list))) return count; - /* scan QTDs till end of list, or we reach an active one */ - for (qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list), - last = 0, next = 0; - next != qtd_list; - last = qtd, qtd = list_entry (next, - struct ehci_qtd, qtd_list)) { - struct urb *urb = qtd->urb; + /* remove de-activated QTDs from front of queue. + * after faults (including short reads), cleanup this urb + * then let the queue advance. + * if queue is stopped, handles unlinks. + */ + list_for_each_safe (entry, tmp, &qh->qtd_list) { + struct ehci_qtd *qtd; + struct urb *urb; u32 token = 0; + qtd = list_entry (entry, struct ehci_qtd, qtd_list); + urb = qtd->urb; + /* clean up any state from previous QTD ...*/ if (last) { if (likely (last->urb != urb)) { @@ -244,74 +252,60 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) ehci_qtd_free (ehci, last); last = 0; } - next = qtd->qtd_list.next; - /* QTDs at tail may be active if QH+HC are running, - * or when unlinking some urbs queued to this QH - */ + /* hardware copies qtd out of qh overlay */ rmb (); token = le32_to_cpu (qtd->hw_token); stopped = stopped || (qh->qh_state == QH_STATE_IDLE) - || (__constant_cpu_to_le32 (QTD_STS_HALT) - & qh->hw_token) != 0 - || (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; - } + || (HALT_BIT & qh->hw_token) != 0 + || (ehci->hcd.state == USB_STATE_HALT); - /* unlink the rest? once we start unlinking, after - * a fault or explicit unlink, we unlink all later - * urbs. usb spec requires that for faults... - */ - if (unlink && urb->status == -EINPROGRESS) - urb->status = -ECONNRESET; + /* always clean up qtds the hc de-activated */ + if ((token & QTD_STS_ACTIVE) == 0) { - /* Else QH is active, so we must not modify QTDs - * that HC may be working on. No more qtds to check. - */ - } else if (unlikely ((token & QTD_STS_ACTIVE) != 0)) { - next = qtd_list; - qtd = 0; - continue; - } + /* magic dummy for short reads; won't advance */ + if (IS_SHORT_READ (token) + && !(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 { + /* 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. + */ + if ((token & QTD_STS_ACTIVE) + && urb->status == -EINPROGRESS) { + last = 0; + 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); qtd_copy_status (ehci, urb, qtd->length, token); 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); + last = qtd; } /* 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) ehci_qtd_free (ehci, last); } - /* reactivate queue after error and driver's cleanup */ - if (unlikely (stopped && !list_empty (&qh->qtd_list))) { - qh_update (ehci, qh, list_entry (qh->qtd_list.next, - struct ehci_qtd, qtd_list)); + /* update qh after fault cleanup */ + if (unlikely ((HALT_BIT & qh->hw_token) != 0)) { + qh_update (ehci, qh, + list_empty (&qh->qtd_list) + ? qh->dummy + : list_entry (qh->qtd_list.next, + struct ehci_qtd, qtd_list)); } return count; } +#undef HALT_BIT /*-------------------------------------------------------------------------*/ @@ -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. */ static struct ehci_qh * -ehci_qh_make ( +qh_make ( struct ehci_hcd *ehci, struct urb *urb, - struct list_head *qtd_list, int flags ) { struct ehci_qh *qh = ehci_qh_alloc (ehci, flags); @@ -649,27 +646,13 @@ done: /* NOTE: if (PIPE_INTERRUPT) { scheduler sets s-mask } */ + /* init as halted, toggle clear, advance to dummy */ qh->qh_state = QH_STATE_IDLE; qh->hw_info1 = cpu_to_le32 (info1); qh->hw_info2 = cpu_to_le32 (info2); - - /* initialize sw and hw queues with these qtds */ - if (!list_empty (qtd_list)) { - 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); + qh_update (ehci, qh, qh->dummy); + qh->hw_token = cpu_to_le32 (QTD_STS_HALT); + usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); return qh; } #undef hb_mult @@ -736,6 +719,11 @@ static struct ehci_qh *qh_append_tds ( struct ehci_qh *qh = 0; 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)) { struct ehci_qtd *qtd; @@ -766,8 +754,34 @@ static struct ehci_qh *qh_append_tds ( } } - /* append to tds already queued to this qh? */ - if (unlikely (!list_empty (&qh->qtd_list) && qtd)) { + /* FIXME: changing config or interface setting is not + * 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; dma_addr_t dma; u32 token; @@ -785,8 +799,10 @@ static struct ehci_qh *qh_append_tds ( dma = dummy->qtd_dma; *dummy = *qtd; dummy->qtd_dma = dma; + list_del (&qtd->qtd_list); list_add (&dummy->qtd_list, qtd_list); + __list_splice (qtd_list, qh->qtd_list.prev); ehci_qtd_init (qtd, qtd->qtd_dma); qtd->hw_alt_next = ehci->async->hw_alt_next; @@ -802,36 +818,9 @@ static struct ehci_qh *qh_append_tds ( wmb (); dummy->hw_token = token; - /* no URB queued */ - } 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); - } + urb->hcpriv = qh_get (qh); } - 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; } diff --git a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c index cda3492b1b31..27591a0898e0 100644 --- a/drivers/usb/image/scanner.c +++ b/drivers/usb/image/scanner.c @@ -1,7 +1,7 @@ /* -*- 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 * @@ -313,6 +313,19 @@ * - Changed maintainership from David E. Nelson to Brian * 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 * - Remove the 2/3 endpoint limitation * - Performance @@ -502,6 +515,12 @@ write_scanner(struct file * file, const char * buffer, 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; obuf = scn->obuf; @@ -896,15 +915,15 @@ probe_scanner(struct usb_interface *intf, 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 * setup the handler. FIXME: This is a future enhancement... */ dbg("probe_scanner: Number of Endpoints:%d", (int) interface->desc.bNumEndpoints); - if ((interface->desc.bNumEndpoints != 2) && (interface->desc.bNumEndpoints != 3)) { - info("probe_scanner: Only two or three endpoints supported."); + if ((interface->desc.bNumEndpoints < 1) || (interface->desc.bNumEndpoints > 3)) { + info("probe_scanner: Only 1, 2, or 3 endpoints supported."); return -ENODEV; } @@ -944,6 +963,12 @@ probe_scanner(struct usb_interface *intf, */ switch(interface->desc.bNumEndpoints) { + case 1: + if (!have_bulk_in) { + info("probe_scanner: One bulk-in endpoint required."); + return -EIO; + } + break; case 2: if (!have_bulk_in || !have_bulk_out) { info("probe_scanner: Two bulk endpoints required."); diff --git a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h index 08b64782604b..f95980c5e7aa 100644 --- a/drivers/usb/image/scanner.h +++ b/drivers/usb/image/scanner.h @@ -1,5 +1,5 @@ /* - * 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 * @@ -44,7 +44,7 @@ */ // #define PV8630 -#define DRIVER_VERSION "0.4.6" +#define DRIVER_VERSION "0.4.9" #define DRIVER_DESC "USB Scanner Driver" #include <linux/usb.h> @@ -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. */ static struct usb_device_id scanner_device_ids [] = { - /* Acer */ - { USB_DEVICE(0x04a5, 0x2060) }, /* Prisa Acerscan 620U & 640U (!)*/ - { USB_DEVICE(0x04a5, 0x2040) }, /* Prisa AcerScan 620U (!) */ - { USB_DEVICE(0x04a5, 0x20c0) }, /* Prisa AcerScan 1240UT */ - { USB_DEVICE(0x04a5, 0x2022) }, /* Vuego Scan Brisa 340U */ + /* Acer (now Benq) */ + { USB_DEVICE(0x04a5, 0x2060) }, /* 620U & 640U (!)*/ + { USB_DEVICE(0x04a5, 0x2040) }, /* 620U (!) */ + { USB_DEVICE(0x04a5, 0x20c0) }, /* 1240UT, 1240U */ + { USB_DEVICE(0x04a5, 0x2022) }, /* 340U */ { USB_DEVICE(0x04a5, 0x1a20) }, /* Unknown - Oliver Schwartz */ - { USB_DEVICE(0x04a5, 0x1a2a) }, /* Unknown - Oliver Schwartz */ - { USB_DEVICE(0x04a5, 0x207e) }, /* Prisa 640BU */ + { USB_DEVICE(0x04a5, 0x1a2a) }, /* Another 620U */ + { USB_DEVICE(0x04a5, 0x207e) }, /* 640BU */ { USB_DEVICE(0x04a5, 0x20be) }, /* Unknown - Oliver Schwartz */ - { USB_DEVICE(0x04a5, 0x20c0) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x20de) }, /* S2W 3300U */ - { USB_DEVICE(0x04a5, 0x20b0) }, /* Unknown - Oliver Schwartz */ - { USB_DEVICE(0x04a5, 0x20fe) }, /* Unknown - Oliver Schwartz */ + { USB_DEVICE(0x04a5, 0x20b0) }, /* Benq 4300 */ + { USB_DEVICE(0x04a5, 0x20fe) }, /* Benq 5300 */ + { USB_DEVICE(0x04a5, 0x20fc) }, /* Benq 5000 */ /* Agfa */ { USB_DEVICE(0x06bd, 0x0001) }, /* SnapScan 1212U */ { USB_DEVICE(0x06bd, 0x0002) }, /* SnapScan 1236U */ @@ -92,24 +92,37 @@ static struct usb_device_id scanner_device_ids [] = { { USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */ { USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */ { 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 */ + { USB_DEVICE(0x04a9, 0x2201) }, /* FB320U */ + { USB_DEVICE(0x04a9, 0x2205) }, /* FB1210U */ { USB_DEVICE(0x04a9, 0x2202) }, /* CanoScan FB620U */ { USB_DEVICE(0x04a9, 0x2204) }, /* CanoScan FB630U/FB636U */ { USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */ { USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */ { USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */ { 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 */ /* Epson -- See Seiko/Epson below */ /* Genius */ { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage-Vivid Pro */ { USB_DEVICE(0x0458, 0x2007) }, /* ColorPage HR6 V2 */ - { USB_DEVICE(0x0458, 0x2008) }, /* Unknown */ - { USB_DEVICE(0x0458, 0x2009) }, /* Unknown */ - { USB_DEVICE(0x0458, 0x2013) }, /* Unknown */ - { USB_DEVICE(0x0458, 0x2015) }, /* Unknown */ - { USB_DEVICE(0x0458, 0x2016) }, /* Unknown */ + { USB_DEVICE(0x0458, 0x2008) }, /* ColorPage-HR6 V2 */ + { USB_DEVICE(0x0458, 0x2009) }, /* ColorPage-HR6A */ + { USB_DEVICE(0x0458, 0x2011) }, /* ColorPage-Vivid3x */ + { USB_DEVICE(0x0458, 0x2013) }, /* ColorPage-HR7 */ + { USB_DEVICE(0x0458, 0x2015) }, /* ColorPage-HR7LE */ + { USB_DEVICE(0x0458, 0x2016) }, /* ColorPage-HR6X */ /* Hewlett Packard */ + { USB_DEVICE(0x03f0, 0x0505) }, /* ScanJet 2100C */ + { USB_DEVICE(0x03f0, 0x0901) }, /* 2300C */ { USB_DEVICE(0x03f0, 0x0205) }, /* 3300C */ { USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */ { USB_DEVICE(0x03f0, 0x0101) }, /* 4100C */ @@ -124,6 +137,8 @@ static struct usb_device_id scanner_device_ids [] = { { USB_DEVICE(0x03f0, 0x605) }, /* 2200C */ /* iVina */ { USB_DEVICE(0x0638, 0x0268) }, /* 1200U */ + /* Lexmark */ + { USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */ /* Lifetec */ { USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */ /* Memorex */ @@ -138,31 +153,44 @@ static struct usb_device_id scanner_device_ids [] = { // { USB_DEVICE(0x05da, 0x80ac) }, /* ScanMaker V6UL - SpicyU */ /* Minolta */ // { 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 */ - { USB_DEVICE(0x055f, 0x0001) }, /* 1200 CU */ + { USB_DEVICE(0x055f, 0x0001) }, /* ScanExpress 1200 CU */ { USB_DEVICE(0x0400, 0x1000) }, /* BearPaw 1200 */ - { USB_DEVICE(0x055f, 0x0002) }, /* 600 CU */ - { USB_DEVICE(0x055f, 0x0873) }, /* 600 USB */ - { USB_DEVICE(0x055f, 0x0003) }, /* 1200 USB */ - { USB_DEVICE(0x055f, 0x0006) }, /* 1200 UB */ + { USB_DEVICE(0x055f, 0x0002) }, /* ScanExpress 600 CU */ + { USB_DEVICE(0x055f, 0x0873) }, /* ScanExpress 600 USB */ + { USB_DEVICE(0x055f, 0x0003) }, /* ScanExpress 1200 USB */ + { 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(0x055f, 0x0008) }, /* 1200 CU Plus */ - { USB_DEVICE(0x0ff5, 0x0010) }, /* BearPaw 1200F */ + { USB_DEVICE(0x055f, 0x0008) }, /* ScanExpress 1200 CU Plus */ + { USB_DEVICE(0x055f, 0x0010) }, /* BearPaw 1200F */ { 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 */ - { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12 */ - { USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro UT24 */ + { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/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, 0x0007) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */ - { USB_DEVICE(0x07b3, 0x0010) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */ - { USB_DEVICE(0x07b3, 0x0015) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U */ /* Primax/Colorado */ { USB_DEVICE(0x0461, 0x0300) }, /* G2-300 #1 */ { USB_DEVICE(0x0461, 0x0380) }, /* G2-600 #1 */ @@ -180,24 +208,32 @@ static struct usb_device_id scanner_device_ids [] = { // { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */ /* Seiko/Epson Corp. */ { USB_DEVICE(0x04b8, 0x0101) }, /* Perfection 636U and 636Photo */ + { USB_DEVICE(0x04b8, 0x0102) }, /* GT-2200 */ { USB_DEVICE(0x04b8, 0x0103) }, /* Perfection 610 */ { USB_DEVICE(0x04b8, 0x0104) }, /* Perfection 1200U and 1200Photo*/ + { USB_DEVICE(0x04b8, 0x0105) }, /* StylusScan 2000 */ { USB_DEVICE(0x04b8, 0x0106) }, /* Stylus Scan 2500 */ { USB_DEVICE(0x04b8, 0x0107) }, /* Expression 1600 */ + { USB_DEVICE(0x04b8, 0x0109) }, /* Expression 1640XL */ { USB_DEVICE(0x04b8, 0x010a) }, /* Perfection 1640SU and 1640SU Photo */ { USB_DEVICE(0x04b8, 0x010b) }, /* Perfection 1240U */ { USB_DEVICE(0x04b8, 0x010c) }, /* Perfection 640U */ { 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, 0x0112) }, /* Perfection 2450 - GT-9700 for the Japanese mkt */ { USB_DEVICE(0x04b8, 0x0114) }, /* Perfection 660 */ { 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, 0x0802) }, /* Stylus CX3200 */ /* Umax */ { USB_DEVICE(0x1606, 0x0010) }, /* Astra 1220U */ { USB_DEVICE(0x1606, 0x0030) }, /* Astra 2000U */ + { USB_DEVICE(0x1606, 0x0060) }, /* Astra 3400U/3450U */ { USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */ + { USB_DEVICE(0x1606, 0x0160) }, /* Astra 5400U */ { USB_DEVICE(0x1606, 0x0230) }, /* Astra 2200U */ /* Visioneer */ { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */ diff --git a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c index 7a53772811c2..5400823e6b86 100644 --- a/drivers/usb/media/ibmcam.c +++ b/drivers/usb/media/ibmcam.c @@ -87,11 +87,11 @@ typedef struct { } ibmcam_t; #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_canvasHeight = 4; diff --git a/drivers/usb/media/stv680.h b/drivers/usb/media/stv680.h index 7d8bcbfdbf5d..a1de6a4ecf73 100644 --- a/drivers/usb/media/stv680.h +++ b/drivers/usb/media/stv680.h @@ -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, 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, @@ -172,7 +172,7 @@ unsigned char red[256] = { 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, 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, @@ -197,7 +197,7 @@ unsigned char green[256] = { 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, 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, diff --git a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c index 9f71e2e7c7f0..53d09d199270 100644 --- a/drivers/usb/misc/speedtouch.c +++ b/drivers/usb/misc/speedtouch.c @@ -146,6 +146,7 @@ static const char udsl_driver_name[] = "Alcatel SpeedTouch USB"; /* data thread */ DECLARE_WAIT_QUEUE_HEAD (udsl_wqh); static DECLARE_COMPLETION(thread_grave); +static DECLARE_MUTEX(udsl_usb_ioctl_lock); static unsigned int datapid; #ifdef DEBUG_PACKET @@ -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_instance_data *instance = ctx->instance; int err; - unsigned long flags; PDEBUG ("udsl_usb_send_data_completion (vcc = %p, skb = %p, status %d)\n", ctx->vcc, ctx->skb, urb->status); @@ -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->skb = NULL; - spin_lock_irqsave (&instance->sndqlock, flags); + spin_lock (&instance->sndqlock); if (skb_queue_empty (&instance->sndqueue)) { - spin_unlock_irqrestore (&instance->sndqlock, flags); + spin_unlock (&instance->sndqlock); return; } /* submit next skb */ ctx->skb = skb_dequeue (&(instance->sndqueue)); ctx->vcc = ((struct udsl_cb *) (ctx->skb->cb))->vcc; - spin_unlock_irqrestore (&instance->sndqlock, flags); + spin_unlock (&instance->sndqlock); usb_fill_bulk_urb (urb, instance->usb_dev, 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) int udsl_usb_cancelsends (struct udsl_instance_data *instance, struct atm_vcc *vcc) { int i; - unsigned long flags; - spin_lock_irqsave (&instance->sndqlock, flags); for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) { if (!instance->send_ctx[i].skb) continue; @@ -628,7 +626,6 @@ int udsl_usb_cancelsends (struct udsl_instance_data *instance, struct atm_vcc *v instance->send_ctx[i].skb = NULL; } } - spin_unlock_irqrestore (&instance->sndqlock, flags); return 0; } @@ -702,7 +699,6 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs) { struct udsl_data_ctx *ctx; struct udsl_instance_data *instance; - unsigned long flags; if (!urb) return; @@ -724,9 +720,9 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs) skb_put (ctx->skb, urb->actual_length); /* 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); - spin_unlock_irqrestore (&instance->recvqlock, flags); + spin_unlock (&instance->recvqlock); wake_up (&udsl_wqh); /* get a new skb */ 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) return; } 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 -EILSEQ: /* 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 * { struct usb_device *dev = interface_to_usbdev (intf); struct udsl_instance_data *instance; - int i; + int i,retval; for (i = 0; i < MAX_UDSL; i++) 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 * instance = minor_data[i]; + down(&udsl_usb_ioctl_lock); switch (code) { case UDSL_IOCTL_START: - return udsl_usb_data_init (instance); + retval = udsl_usb_data_init (instance); break; case UDSL_IOCTL_STOP: - return udsl_usb_data_exit (instance); + retval = udsl_usb_data_exit (instance); break; default: + retval = -ENOTTY; 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) @@ -998,11 +994,6 @@ static void udsl_usb_disconnect (struct usb_interface *intf) PDEBUG ("disconnecting minor %d\n", i); - while (MOD_IN_USE > 1) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout (1); - } - kfree (instance); minor_data[i] = NULL; diff --git a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c index 5c8c1998eee9..46271a3c1e64 100644 --- a/drivers/usb/net/cdc-ether.c +++ b/drivers/usb/net/cdc-ether.c @@ -132,7 +132,7 @@ goon: // Give this to the USB subsystem so it can tell us // 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); } @@ -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; // 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... warn("failed tx_urb %d", res); // update some stats... diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 70ca7d7b6659..02bbb9cb5174 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -827,7 +827,7 @@ static void keyspan_pda_shutdown (struct usb_serial *serial) static struct usb_serial_device_type keyspan_pda_fake_device = { .owner = THIS_MODULE, .name = "Keyspan PDA - (prerenumeration)", - .short_name = "kyspn_pda_nofirm", + .short_name = "keyspan_pda_pre", .id_table = id_table_fake, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, @@ -841,7 +841,7 @@ static struct usb_serial_device_type keyspan_pda_fake_device = { static struct usb_serial_device_type xircom_pgs_fake_device = { .owner = THIS_MODULE, .name = "Xircom / Entregra PGS - (prerenumeration)", - .short_name = "xircom_nofirm", + .short_name = "xircom_no_firm", .id_table = id_table_fake_xircom, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h index f1aa41ee93d9..ac107ddd3e30 100644 --- a/include/asm-generic/dma-mapping.h +++ b/include/asm-generic/dma-mapping.h @@ -10,6 +10,8 @@ /* we implement the API below in terms of the existing PCI one, * so include it */ #include <linux/pci.h> +/* need struct page definitions */ +#include <linux/mm.h> static inline int dma_supported(struct device *dev, u64 mask) diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h new file mode 100644 index 000000000000..b871ec69a79a --- /dev/null +++ b/include/asm-generic/pci-dma-compat.h @@ -0,0 +1,87 @@ +/* include this file if the platform implements the dma_ DMA Mapping API + * and wants to provide the pci_ DMA Mapping API in terms of it */ + +#ifndef _ASM_GENERIC_PCI_DMA_COMPAT_H +#define _ASM_GENERIC_PCI_DMA_COMPAT_H + +#include <linux/dma-mapping.h> + +/* note pci_set_dma_mask isn't here, since it's a public function + * exported from drivers/pci, use dma_supported instead */ + +static inline int +pci_dma_supported(struct pci_dev *hwdev, u64 mask) +{ + return dma_supported(&hwdev->dev, mask); +} + +static inline void * +pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t *dma_handle) +{ + return dma_alloc_coherent(&hwdev->dev, size, dma_handle); +} + +static inline void +pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + dma_free_coherent(&hwdev->dev, size, vaddr, dma_handle); +} + +static inline dma_addr_t +pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) +{ + return dma_map_single(&hwdev->dev, ptr, size, (enum dma_data_direction)direction); +} + +static inline void +pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, + size_t size, int direction) +{ + dma_unmap_single(&hwdev->dev, dma_addr, size, (enum dma_data_direction)direction); +} + +static inline dma_addr_t +pci_map_page(struct pci_dev *hwdev, struct page *page, + unsigned long offset, size_t size, int direction) +{ + return dma_map_page(&hwdev->dev, page, offset, size, (enum dma_data_direction)direction); +} + +static inline void +pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address, + size_t size, int direction) +{ + dma_unmap_page(&hwdev->dev, dma_address, size, (enum dma_data_direction)direction); +} + +static inline int +pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction) +{ + return dma_map_sg(&hwdev->dev, sg, nents, (enum dma_data_direction)direction); +} + +static inline void +pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction) +{ + dma_unmap_sg(&hwdev->dev, sg, nents, (enum dma_data_direction)direction); +} + +static inline void +pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, + size_t size, int direction) +{ + dma_sync_single(&hwdev->dev, dma_handle, size, (enum dma_data_direction)direction); +} + +static inline void +pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nelems, int direction) +{ + dma_sync_sg(&hwdev->dev, sg, nelems, (enum dma_data_direction)direction); +} + +#endif diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h index 48a0dc93ffdc..d41feaba85ef 100644 --- a/include/asm-i386/pci.h +++ b/include/asm-i386/pci.h @@ -6,9 +6,6 @@ #ifdef __KERNEL__ #include <linux/mm.h> /* for struct page */ -/* we support the new DMA API, but still provide the old one */ -#define PCI_NEW_DMA_COMPAT_API 1 - /* Can be used to override the logic in pci_scan_bus for skipping already-configured bus numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the loader */ @@ -105,4 +102,7 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, #endif /* __KERNEL__ */ +/* implement the pci_ DMA API in terms of the generic device dma_ one */ +#include <asm-generic/pci-dma-compat.h> + #endif /* __i386_PCI_H */ diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index d26bf652d894..ae3615feecdb 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -48,8 +48,8 @@ typedef struct { "js 2f\n" \ LOCK_SECTION_START("") \ "2:\t" \ - "cmpb $0,%0\n\t" \ "rep;nop\n\t" \ + "cmpb $0,%0\n\t" \ "jle 2b\n\t" \ "jmp 1b\n" \ LOCK_SECTION_END diff --git a/include/linux/device.h b/include/linux/device.h index 48612267bd65..a2d6e8171f9b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -396,22 +396,21 @@ extern int firmware_register(struct subsystem *); extern void firmware_unregister(struct subsystem *); /* 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 #define dev_dbg(dev, format, arg...) \ - printk (KERN_DEBUG "%s %s: " format , \ - (dev).driver->name , (dev).bus_id , ## arg) + dev_printk(KERN_DEBUG , (dev) , format , ## arg) #else #define dev_dbg(dev, format, arg...) do {} while (0) #endif #define dev_err(dev, format, arg...) \ - printk (KERN_ERR "%s %s: " format , \ - (dev).driver->name , (dev).bus_id , ## arg) + dev_printk(KERN_ERR , (dev) , format , ## arg) #define dev_info(dev, format, arg...) \ - printk (KERN_INFO "%s %s: " format , \ - (dev).driver->name , (dev).bus_id , ## arg) + dev_printk(KERN_INFO , (dev) , format , ## arg) #define dev_warn(dev, format, arg...) \ - printk (KERN_WARNING "%s %s: " format , \ - (dev).driver->name , (dev).bus_id , ## arg) + dev_printk(KERN_WARNING , (dev) , format , ## arg) #endif /* _DEVICE_H_ */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 3fa241545729..9d4e269ac1db 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -834,92 +834,6 @@ extern int pci_pci_problems; #define PCIPCI_VIAETBF 8 #define PCIPCI_VSFX 16 -#include <linux/dma-mapping.h> - -/* If you define PCI_NEW_DMA_COMPAT_API it means you support the new DMA API - * and you want the pci_ DMA API to be implemented using it. - */ -#if defined(PCI_NEW_DMA_COMPAT_API) && defined(CONFIG_PCI) - -/* note pci_set_dma_mask isn't here, since it's a public function - * exported from drivers/pci, use dma_supported instead */ - -static inline int -pci_dma_supported(struct pci_dev *hwdev, u64 mask) -{ - return dma_supported(&hwdev->dev, mask); -} - -static inline void * -pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) -{ - return dma_alloc_coherent(&hwdev->dev, size, dma_handle); -} - -static inline void -pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - dma_free_coherent(&hwdev->dev, size, vaddr, dma_handle); -} - -static inline dma_addr_t -pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) -{ - return dma_map_single(&hwdev->dev, ptr, size, (enum dma_data_direction)direction); -} - -static inline void -pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, - size_t size, int direction) -{ - dma_unmap_single(&hwdev->dev, dma_addr, size, (enum dma_data_direction)direction); -} - -static inline dma_addr_t -pci_map_page(struct pci_dev *hwdev, struct page *page, - unsigned long offset, size_t size, int direction) -{ - return dma_map_page(&hwdev->dev, page, offset, size, (enum dma_data_direction)direction); -} - -static inline void -pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address, - size_t size, int direction) -{ - dma_unmap_page(&hwdev->dev, dma_address, size, (enum dma_data_direction)direction); -} - -static inline int -pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, int direction) -{ - return dma_map_sg(&hwdev->dev, sg, nents, (enum dma_data_direction)direction); -} - -static inline void -pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, int direction) -{ - dma_unmap_sg(&hwdev->dev, sg, nents, (enum dma_data_direction)direction); -} - -static inline void -pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, - size_t size, int direction) -{ - dma_sync_single(&hwdev->dev, dma_handle, size, (enum dma_data_direction)direction); -} - -static inline void -pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nelems, int direction) -{ - dma_sync_sg(&hwdev->dev, sg, nelems, (enum dma_data_direction)direction); -} - -#endif #endif /* __KERNEL__ */ #endif /* LINUX_PCI_H */ |
