summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2002-12-24 08:21:27 +1100
committerPaul Mackerras <paulus@samba.org>2002-12-24 08:21:27 +1100
commit75528e466f18a2f2cd431f6c3fe27119317bb629 (patch)
treec124ec63485ef54cf644ecb80461e4adb5173032
parentaeb24f2986ff9471fd062e50815466b0c6415b52 (diff)
parent5e163a89fedacf47100735e738c43687d3bf18a2 (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.S6
-rw-r--r--drivers/usb/class/cdc-acm.c2
-rw-r--r--drivers/usb/core/hcd.c12
-rw-r--r--drivers/usb/core/hub.c57
-rw-r--r--drivers/usb/core/inode.c2
-rw-r--r--drivers/usb/host/ehci-mem.c2
-rw-r--r--drivers/usb/host/ehci-q.c245
-rw-r--r--drivers/usb/image/scanner.c33
-rw-r--r--drivers/usb/image/scanner.h96
-rw-r--r--drivers/usb/media/ibmcam.c6
-rw-r--r--drivers/usb/media/stv680.h6
-rw-r--r--drivers/usb/misc/speedtouch.c35
-rw-r--r--drivers/usb/net/cdc-ether.c4
-rw-r--r--drivers/usb/serial/keyspan_pda.c4
-rw-r--r--include/asm-generic/dma-mapping.h2
-rw-r--r--include/asm-generic/pci-dma-compat.h87
-rw-r--r--include/asm-i386/pci.h6
-rw-r--r--include/asm-i386/spinlock.h2
-rw-r--r--include/linux/device.h15
-rw-r--r--include/linux/pci.h86
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 */