Commit e0a22486 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/linus-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 42197830 f5683a63
...@@ -189,10 +189,10 @@ trace ...@@ -189,10 +189,10 @@ trace
The fbufs, mbufs and trace parameters are global and apply to all connected The fbufs, mbufs and trace parameters are global and apply to all connected
cameras. Each camera has its own set of buffers. cameras. Each camera has its own set of buffers.
size, fps, palette only specify defaults when you open() the device; this is size and fps only specify defaults when you open() the device; this is to
to accommodate some tools that don't set the size or colour palette. You can accommodate some tools that don't set the size. You can change these
change these settings after open() with the Video4Linux ioctl() calls. The settings after open() with the Video4Linux ioctl() calls. The default of
default of defaults is QCIF size at 10 fps, BGR order. defaults is QCIF size at 10 fps, BGR order.
The compression parameter is semiglobal; it sets the initial compression The compression parameter is semiglobal; it sets the initial compression
preference for all camera's, but this parameter can be set per camera with preference for all camera's, but this parameter can be set per camera with
......
...@@ -34,6 +34,26 @@ CONFIG_USB_BLUETOOTH_TTY ...@@ -34,6 +34,26 @@ CONFIG_USB_BLUETOOTH_TTY
The module will be called bluetty.o. If you want to compile it as The module will be called bluetty.o. If you want to compile it as
a module, say M here and read <file:Documentation/modules.txt>. a module, say M here and read <file:Documentation/modules.txt>.
CONFIG_USB_MIDI
Say Y here if you want to connect a USB MIDI device to your
computer's USB port. This driver is for devices that comply with
'Universal Serial Bus Device Class Definition for MIDI Device'.
The following devices are known to work:
* Steinberg USB2MIDI
* Roland MPU64
* Roland PC-300
* Roland SC8850
* Roland UM-1
* Roland UM-2
* Roland UA-100
* Yamaha MU1000
This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called usb-midi.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
CONFIG_USB_PRINTER CONFIG_USB_PRINTER
Say Y here if you want to connect a USB printer to your computer's Say Y here if you want to connect a USB printer to your computer's
USB port. USB port.
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
#define DRIVER_DESC "USB Printer Device Class driver" #define DRIVER_DESC "USB Printer Device Class driver"
#define USBLP_BUF_SIZE 8192 #define USBLP_BUF_SIZE 8192
#define DEVICE_ID_SIZE 1024 #define USBLP_DEVICE_ID_SIZE 1024
/* ioctls: */ /* ioctls: */
#define LPGETSTATUS 0x060b /* same as in drivers/char/lp.c */ #define LPGETSTATUS 0x060b /* same as in drivers/char/lp.c */
...@@ -722,7 +722,8 @@ static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t ...@@ -722,7 +722,8 @@ static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t
usblp->minor, usblp->readurb->status); usblp->minor, usblp->readurb->status);
usblp->readurb->dev = usblp->dev; usblp->readurb->dev = usblp->dev;
usblp->readcount = 0; usblp->readcount = 0;
usb_submit_urb(usblp->readurb, GFP_KERNEL); if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
dbg("error submitting urb");
count = -EIO; count = -EIO;
goto done; goto done;
} }
...@@ -839,7 +840,7 @@ static void *usblp_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -839,7 +840,7 @@ static void *usblp_probe(struct usb_device *dev, unsigned int ifnum,
/* Malloc device ID string buffer to the largest expected length, /* Malloc device ID string buffer to the largest expected length,
* since we can re-query it on an ioctl and a dynamic string * since we can re-query it on an ioctl and a dynamic string
* could change in length. */ * could change in length. */
if (!(usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))) { if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) {
err("out of memory for device_id_string"); err("out of memory for device_id_string");
goto abort_minor; goto abort_minor;
} }
...@@ -1045,7 +1046,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp) ...@@ -1045,7 +1046,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
{ {
int err, length; int err, length;
err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1); err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
if (err < 0) { if (err < 0) {
dbg("usblp%d: error = %d reading IEEE-1284 Device ID string", dbg("usblp%d: error = %d reading IEEE-1284 Device ID string",
usblp->minor, err); usblp->minor, err);
...@@ -1059,8 +1060,8 @@ static int usblp_cache_device_id_string(struct usblp *usblp) ...@@ -1059,8 +1060,8 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1];
if (length < 2) if (length < 2)
length = 2; length = 2;
else if (length >= DEVICE_ID_SIZE) else if (length >= USBLP_DEVICE_ID_SIZE)
length = DEVICE_ID_SIZE - 1; length = USBLP_DEVICE_ID_SIZE - 1;
usblp->device_id_string[length] = '\0'; usblp->device_id_string[length] = '\0';
dbg("usblp%d Device ID string [len=%d]=\"%s\"", dbg("usblp%d Device ID string [len=%d]=\"%s\"",
......
...@@ -574,8 +574,10 @@ static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff ...@@ -574,8 +574,10 @@ static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff
bus = list_entry(buslist, struct usb_bus, bus_list); bus = list_entry(buslist, struct usb_bus, bus_list);
/* recurse through all children of the root hub */ /* recurse through all children of the root hub */
ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0); ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
if (ret < 0) if (ret < 0) {
up(&usb_bus_list_lock);
return ret; return ret;
}
total_written += ret; total_written += ret;
} }
up (&usb_bus_list_lock); up (&usb_bus_list_lock);
......
...@@ -215,8 +215,7 @@ extern __inline__ void async_removepending(struct async *as) ...@@ -215,8 +215,7 @@ extern __inline__ void async_removepending(struct async *as)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ps->lock, flags); spin_lock_irqsave(&ps->lock, flags);
list_del(&as->asynclist); list_del_init(&as->asynclist);
INIT_LIST_HEAD(&as->asynclist);
spin_unlock_irqrestore(&ps->lock, flags); spin_unlock_irqrestore(&ps->lock, flags);
} }
...@@ -228,8 +227,7 @@ extern __inline__ struct async *async_getcompleted(struct dev_state *ps) ...@@ -228,8 +227,7 @@ extern __inline__ struct async *async_getcompleted(struct dev_state *ps)
spin_lock_irqsave(&ps->lock, flags); spin_lock_irqsave(&ps->lock, flags);
if (!list_empty(&ps->async_completed)) { if (!list_empty(&ps->async_completed)) {
as = list_entry(ps->async_completed.next, struct async, asynclist); as = list_entry(ps->async_completed.next, struct async, asynclist);
list_del(&as->asynclist); list_del_init(&as->asynclist);
INIT_LIST_HEAD(&as->asynclist);
} }
spin_unlock_irqrestore(&ps->lock, flags); spin_unlock_irqrestore(&ps->lock, flags);
return as; return as;
...@@ -247,8 +245,7 @@ extern __inline__ struct async *async_getpending(struct dev_state *ps, void *use ...@@ -247,8 +245,7 @@ extern __inline__ struct async *async_getpending(struct dev_state *ps, void *use
p = p->next; p = p->next;
if (as->userurb != userurb) if (as->userurb != userurb)
continue; continue;
list_del(&as->asynclist); list_del_init(&as->asynclist);
INIT_LIST_HEAD(&as->asynclist);
spin_unlock_irqrestore(&ps->lock, flags); spin_unlock_irqrestore(&ps->lock, flags);
return as; return as;
} }
...@@ -263,8 +260,7 @@ static void async_completed(struct urb *urb) ...@@ -263,8 +260,7 @@ static void async_completed(struct urb *urb)
struct siginfo sinfo; struct siginfo sinfo;
spin_lock(&ps->lock); spin_lock(&ps->lock);
list_del(&as->asynclist); list_move_tail(&as->asynclist, &ps->async_completed);
list_add_tail(&as->asynclist, &ps->async_completed);
spin_unlock(&ps->lock); spin_unlock(&ps->lock);
wake_up(&ps->wait); wake_up(&ps->wait);
if (as->signr) { if (as->signr) {
...@@ -284,8 +280,7 @@ static void destroy_all_async(struct dev_state *ps) ...@@ -284,8 +280,7 @@ static void destroy_all_async(struct dev_state *ps)
spin_lock_irqsave(&ps->lock, flags); spin_lock_irqsave(&ps->lock, flags);
while (!list_empty(&ps->async_pending)) { while (!list_empty(&ps->async_pending)) {
as = list_entry(ps->async_pending.next, struct async, asynclist); as = list_entry(ps->async_pending.next, struct async, asynclist);
list_del(&as->asynclist); list_del_init(&as->asynclist);
INIT_LIST_HEAD(&as->asynclist);
spin_unlock_irqrestore(&ps->lock, flags); spin_unlock_irqrestore(&ps->lock, flags);
/* usb_unlink_urb calls the completion handler with status == -ENOENT */ /* usb_unlink_urb calls the completion handler with status == -ENOENT */
usb_unlink_urb(as->urb); usb_unlink_urb(as->urb);
...@@ -528,8 +523,8 @@ static int usbdev_release(struct inode *inode, struct file *file) ...@@ -528,8 +523,8 @@ static int usbdev_release(struct inode *inode, struct file *file)
unsigned int i; unsigned int i;
lock_kernel(); lock_kernel();
list_del(&ps->list); list_del_init(&ps->list);
INIT_LIST_HEAD(&ps->list);
if (ps->dev) { if (ps->dev) {
for (i = 0; ps->ifclaimed && i < 8*sizeof(ps->ifclaimed); i++) for (i = 0; ps->ifclaimed && i < 8*sizeof(ps->ifclaimed); i++)
if (test_bit(i, &ps->ifclaimed)) if (test_bit(i, &ps->ifclaimed))
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/io.h>
#include <asm/irq.h>
#ifdef CONFIG_USB_DEBUG #ifdef CONFIG_USB_DEBUG
#define DEBUG #define DEBUG
......
...@@ -220,14 +220,12 @@ static int hci_unlink_urb (struct urb * urb) ...@@ -220,14 +220,12 @@ static int hci_unlink_urb (struct urb * urb)
/* URB active? */ /* URB active? */
if (urb->transfer_flags & (USB_ASYNC_UNLINK | USB_TIMEOUT_KILLED)) { if (urb->transfer_flags & (USB_ASYNC_UNLINK | USB_TIMEOUT_KILLED)) {
/* asynchron with callback */ /* asynchronous with callback */
/* relink the urb to the del list */
list_del (&urb->urb_list); /* relink the urb to the del list */ list_move (&urb->urb_list, &hci->del_list);
list_add (&urb->urb_list, &hci->del_list);
spin_unlock_irqrestore (&usb_urb_lock, flags); spin_unlock_irqrestore (&usb_urb_lock, flags);
} else { } else {
/* synchron without callback */ /* synchronous without callback */
add_wait_queue (&hci->waitq, &wait); add_wait_queue (&hci->waitq, &wait);
...@@ -235,8 +233,8 @@ static int hci_unlink_urb (struct urb * urb) ...@@ -235,8 +233,8 @@ static int hci_unlink_urb (struct urb * urb)
comp = urb->complete; comp = urb->complete;
urb->complete = NULL; urb->complete = NULL;
list_del (&urb->urb_list); /* relink the urb to the del list */ /* relink the urb to the del list */
list_add (&urb->urb_list, &hci->del_list); list_move(&urb->urb_list, &hci->del_list);
spin_unlock_irqrestore (&usb_urb_lock, flags); spin_unlock_irqrestore (&usb_urb_lock, flags);
...@@ -560,10 +558,9 @@ static struct urb *qu_next_urb (hci_t * hci, struct urb * urb, int resub_ok) ...@@ -560,10 +558,9 @@ static struct urb *qu_next_urb (hci_t * hci, struct urb * urb, int resub_ok)
epd_t *ed = &hci_dev->ed[qu_pipeindex (urb->pipe)]; epd_t *ed = &hci_dev->ed[qu_pipeindex (urb->pipe)];
DBGFUNC ("enter qu_next_urb\n"); DBGFUNC ("enter qu_next_urb\n");
list_del (&urb->urb_list); list_del_init(&urb->urb_list);
INIT_LIST_HEAD (&urb->urb_list);
if (ed->pipe_head == urb) {
if (ed->pipe_head == urb) {
#ifdef HC_URB_TIMEOUT #ifdef HC_URB_TIMEOUT
if (urb->timeout) if (urb->timeout)
del_timer (&ed->timeout); del_timer (&ed->timeout);
...@@ -574,8 +571,7 @@ static struct urb *qu_next_urb (hci_t * hci, struct urb * urb, int resub_ok) ...@@ -574,8 +571,7 @@ static struct urb *qu_next_urb (hci_t * hci, struct urb * urb, int resub_ok)
if (!list_empty (&ed->urb_queue)) { if (!list_empty (&ed->urb_queue)) {
urb = list_entry (ed->urb_queue.next, struct urb, urb_list); urb = list_entry (ed->urb_queue.next, struct urb, urb_list);
list_del (&urb->urb_list); list_del_init (&urb->urb_list);
INIT_LIST_HEAD (&urb->urb_list);
ed->pipe_head = urb; ed->pipe_head = urb;
qu_queue_active_urb (hci, urb, ed); qu_queue_active_urb (hci, urb, ed);
} else { } else {
...@@ -756,8 +752,7 @@ static int sh_schedule_trans (hci_t * hci, int isSOF) ...@@ -756,8 +752,7 @@ static int sh_schedule_trans (hci_t * hci, int isSOF)
* only when the new SOF happens */ * only when the new SOF happens */
lh = hci->bulk_list.next; lh = hci->bulk_list.next;
list_del (&hci->bulk_list); list_move (&hci->bulk_list, lh);
list_add (&hci->bulk_list, lh);
} }
return 0; return 0;
} }
......
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
* - lots more testing!! * - lots more testing!!
*/ */
#define DRIVER_VERSION "2002-Jun-01" #define DRIVER_VERSION "2002-Jun-10"
#define DRIVER_AUTHOR "Roman Weissgaerber <weissg@vienna.at>, David Brownell" #define DRIVER_AUTHOR "Roman Weissgaerber <weissg@vienna.at>, David Brownell"
#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
...@@ -307,7 +307,6 @@ ohci_free_config (struct usb_hcd *hcd, struct usb_device *udev) ...@@ -307,7 +307,6 @@ ohci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
spin_lock_irqsave (&ohci->lock, flags); spin_lock_irqsave (&ohci->lock, flags);
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
struct ed *ed = dev->ep [i]; struct ed *ed = dev->ep [i];
struct td *tdTailP;
if (!ed) if (!ed)
continue; continue;
...@@ -319,10 +318,7 @@ ohci_free_config (struct usb_hcd *hcd, struct usb_device *udev) ...@@ -319,10 +318,7 @@ ohci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
case ED_NEW: case ED_NEW:
break; break;
case ED_UNLINK: case ED_UNLINK:
tdTailP = dma_to_td (ohci, td_free (ohci, ed->dummy);
le32_to_cpup (&ed->hwTailP) & 0xfffffff0);
td_free (ohci, tdTailP); /* free dummy td */
hash_free_ed (ohci, ed);
break; break;
case ED_OPER: case ED_OPER:
......
...@@ -440,14 +440,16 @@ static struct ed *ep_add_ed ( ...@@ -440,14 +440,16 @@ static struct ed *ep_add_ed (
spin_unlock_irqrestore (&ohci->lock, flags); spin_unlock_irqrestore (&ohci->lock, flags);
return NULL; return NULL;
} }
ed->dummy = td;
ed->hwTailP = cpu_to_le32 (td->td_dma); ed->hwTailP = cpu_to_le32 (td->td_dma);
ed->hwHeadP = ed->hwTailP; ed->hwHeadP = ed->hwTailP; /* ED_C, ED_H zeroed */
ed->state = ED_UNLINK; ed->state = ED_UNLINK;
ed->type = usb_pipetype (pipe); ed->type = usb_pipetype (pipe);
} }
// FIXME: don't do this if it's linked to the HC, // FIXME: don't do this if it's linked to the HC, or without knowing it's
// we might clobber data toggle or other state ... // safe to clobber state/mode info tied to (previous) config/altsetting.
// (but dev0/ep0, used by set_address, must get clobbered)
ed->hwINFO = cpu_to_le32 (usb_pipedevice (pipe) ed->hwINFO = cpu_to_le32 (usb_pipedevice (pipe)
| usb_pipeendpoint (pipe) << 7 | usb_pipeendpoint (pipe) << 7
...@@ -523,27 +525,31 @@ td_fill (struct ohci_hcd *ohci, unsigned int info, ...@@ -523,27 +525,31 @@ td_fill (struct ohci_hcd *ohci, unsigned int info,
dma_addr_t data, int len, dma_addr_t data, int len,
struct urb *urb, int index) struct urb *urb, int index)
{ {
volatile struct td *td, *td_pt; struct td *td, *td_pt;
urb_priv_t *urb_priv = urb->hcpriv; urb_priv_t *urb_priv = urb->hcpriv;
int is_iso = info & TD_ISO;
if (index >= urb_priv->length) { if (index >= urb_priv->length) {
err ("internal OHCI error: TD index > length"); err ("internal OHCI error: TD index > length");
return; return;
} }
#if 0 /* aim for only one interrupt per urb. mostly applies to control
/* no interrupt needed except for URB's last TD */ * and iso; other urbs rarely need more than one TD per urb.
*
* NOTE: could delay interrupts even for the last TD, and get fewer
* interrupts ... increasing per-urb latency by sharing interrupts.
*/
if (index != (urb_priv->length - 1)) if (index != (urb_priv->length - 1))
info |= TD_DI; info |= is_iso ? TD_DI_SET (7) : TD_DI_SET (1);
#endif
/* use this td as the next dummy */ /* use this td as the next dummy */
td_pt = urb_priv->td [index]; td_pt = urb_priv->td [index];
td_pt->hwNextTD = 0; td_pt->hwNextTD = 0;
/* fill the old dummy TD */ /* fill the old dummy TD */
td = urb_priv->td [index] = dma_to_td (ohci, td = urb_priv->td [index] = urb_priv->ed->dummy;
le32_to_cpup (&urb_priv->ed->hwTailP)); urb_priv->ed->dummy = td_pt;
td->ed = urb_priv->ed; td->ed = urb_priv->ed;
td->next_dl_td = NULL; td->next_dl_td = NULL;
...@@ -554,7 +560,7 @@ td_fill (struct ohci_hcd *ohci, unsigned int info, ...@@ -554,7 +560,7 @@ td_fill (struct ohci_hcd *ohci, unsigned int info,
data = 0; data = 0;
td->hwINFO = cpu_to_le32 (info); td->hwINFO = cpu_to_le32 (info);
if ((td->ed->type) == PIPE_ISOCHRONOUS) { if (is_iso) {
td->hwCBP = cpu_to_le32 (data & 0xFFFFF000); td->hwCBP = cpu_to_le32 (data & 0xFFFFF000);
td->ed->intriso.last_iso = info & 0xffff; td->ed->intriso.last_iso = info & 0xffff;
} else { } else {
...@@ -901,6 +907,7 @@ static void finish_unlinks (struct ohci_hcd *ohci, u16 tick) ...@@ -901,6 +907,7 @@ static void finish_unlinks (struct ohci_hcd *ohci, u16 tick)
* [a2] some (earlier) URBs still linked, re-enable * [a2] some (earlier) URBs still linked, re-enable
* (b) finishing ED unlink * (b) finishing ED unlink
* [b1] no URBs queued, ED is truly idle now * [b1] no URBs queued, ED is truly idle now
* ... we could set state ED_NEW and free dummy
* [b2] URBs now queued, link ED back into schedule * [b2] URBs now queued, link ED back into schedule
* right now we only have (a) * right now we only have (a)
*/ */
...@@ -910,9 +917,6 @@ static void finish_unlinks (struct ohci_hcd *ohci, u16 tick) ...@@ -910,9 +917,6 @@ static void finish_unlinks (struct ohci_hcd *ohci, u16 tick)
if (tdHeadP == tdTailP) { if (tdHeadP == tdTailP) {
if (ed->state == ED_OPER) if (ed->state == ED_OPER)
start_ed_unlink (ohci, ed); start_ed_unlink (ohci, ed);
td_free (ohci, tdTailP);
ed->hwINFO = ED_SKIP;
ed->state = ED_NEW;
} else } else
ed->hwINFO &= ~ED_SKIP; ed->hwINFO &= ~ED_SKIP;
......
...@@ -29,6 +29,7 @@ struct ed { ...@@ -29,6 +29,7 @@ struct ed {
/* rest are purely for the driver's use */ /* rest are purely for the driver's use */
dma_addr_t dma; /* addr of ED */ dma_addr_t dma; /* addr of ED */
struct ed *ed_prev; /* for non-interrupt EDs */ struct ed *ed_prev; /* for non-interrupt EDs */
struct td *dummy;
u8 type; /* PIPE_{BULK,...} */ u8 type; /* PIPE_{BULK,...} */
u8 interval; /* interrupt, isochronous */ u8 interval; /* interrupt, isochronous */
...@@ -63,24 +64,33 @@ struct ed { ...@@ -63,24 +64,33 @@ struct ed {
struct td { struct td {
/* first fields are hardware-specified, le32 */ /* first fields are hardware-specified, le32 */
__u32 hwINFO; /* transfer info bitmask */ __u32 hwINFO; /* transfer info bitmask */
/* hwINFO bits for both general and iso tds: */
#define TD_CC 0xf0000000 /* condition code */ #define TD_CC 0xf0000000 /* condition code */
#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) #define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
//#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) //#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
#define TD_DI 0x00E00000 /* frames before interrupt */
#define TD_DI_SET(X) (((X) & 0x07)<< 21)
/* these two bits are available for definition/use by HCDs in both
* general and iso tds ... others are available for only one type
*/
//#define TD____ 0x00020000
#define TD_ISO 0x00010000 /* copy of ED_ISO */
/* hwINFO bits for general tds: */
#define TD_EC 0x0C000000 /* error count */ #define TD_EC 0x0C000000 /* error count */
#define TD_T 0x03000000 /* data toggle state */ #define TD_T 0x03000000 /* data toggle state */
#define TD_T_DATA0 0x02000000 /* DATA0 */ #define TD_T_DATA0 0x02000000 /* DATA0 */
#define TD_T_DATA1 0x03000000 /* DATA1 */ #define TD_T_DATA1 0x03000000 /* DATA1 */
#define TD_T_TOGGLE 0x00000000 /* uses ED_C */ #define TD_T_TOGGLE 0x00000000 /* uses ED_C */
#define TD_DI 0x00E00000 /* frames before interrupt */
//#define TD_DI_SET(X) (((X) & 0x07)<< 21)
#define TD_DP 0x00180000 /* direction/pid */ #define TD_DP 0x00180000 /* direction/pid */
#define TD_DP_SETUP 0x00000000 /* SETUP pid */ #define TD_DP_SETUP 0x00000000 /* SETUP pid */
#define TD_DP_IN 0x00100000 /* IN pid */ #define TD_DP_IN 0x00100000 /* IN pid */
#define TD_DP_OUT 0x00080000 /* OUT pid */ #define TD_DP_OUT 0x00080000 /* OUT pid */
/* 0x00180000 rsvd */ /* 0x00180000 rsvd */
#define TD_R 0x00040000 /* round: short packets OK? */ #define TD_R 0x00040000 /* round: short packets OK? */
/* bits 0x1ffff are defined by HCD */
#define TD_ISO 0x00010000 /* copy of ED_ISO */ /* (no hwINFO #defines yet for iso tds) */
__u32 hwCBP; /* Current Buffer Pointer (or 0) */ __u32 hwCBP; /* Current Buffer Pointer (or 0) */
__u32 hwNextTD; /* Next TD Pointer */ __u32 hwNextTD; /* Next TD Pointer */
......
...@@ -1773,10 +1773,8 @@ static void stall_callback(unsigned long ptr) ...@@ -1773,10 +1773,8 @@ static void stall_callback(unsigned long ptr)
uhci_fsbr_timeout(uhci, u); uhci_fsbr_timeout(uhci, u);
/* Check if the URB timed out */ /* Check if the URB timed out */
if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout)) { if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout))
list_del(&up->urb_list); list_move_tail(&up->urb_list, &list);
list_add_tail(&up->urb_list, &list);
}
spin_unlock(&u->lock); spin_unlock(&u->lock);
} }
......
...@@ -2008,10 +2008,8 @@ static void rh_int_timer_do(unsigned long ptr) ...@@ -2008,10 +2008,8 @@ static void rh_int_timer_do(unsigned long ptr)
uhci_fsbr_timeout(uhci, u); uhci_fsbr_timeout(uhci, u);
/* Check if the URB timed out */ /* Check if the URB timed out */
if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout)) { if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout))
list_del(&u->urb_list); list_move_tail(&u->urb_list, &list);
list_add_tail(&u->urb_list, &list);
}
spin_unlock(&u->lock); spin_unlock(&u->lock);
} }
......
...@@ -273,8 +273,6 @@ static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback) ...@@ -273,8 +273,6 @@ static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback)
usb_urb_callback usb_callback; usb_urb_callback usb_callback;
int res; int res;
hpusbscsi->use_count++;
/* we don't answer for anything but our single device on any faked host controller */ /* we don't answer for anything but our single device on any faked host controller */
if ( srb->device->lun || srb->device->id || srb->device->channel ) { if ( srb->device->lun || srb->device->id || srb->device->channel ) {
if (callback) { if (callback) {
...@@ -341,7 +339,6 @@ static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback) ...@@ -341,7 +339,6 @@ static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback)
} }
out: out:
hpusbscsi->use_count--;
return 0; return 0;
} }
......
...@@ -20,25 +20,25 @@ struct hpusbscsi ...@@ -20,25 +20,25 @@ struct hpusbscsi
int ep_in; int ep_in;
int ep_int; int ep_int;
int interrupt_interval; int interrupt_interval;
int number;
int fragment;
struct Scsi_Host *host; struct Scsi_Host *host;
Scsi_Host_Template ctempl;
int number;
scsi_callback scallback; scsi_callback scallback;
Scsi_Cmnd *srb; Scsi_Cmnd *srb;
u8 sense_command[SENSE_COMMAND_SIZE];
int use_count;
wait_queue_head_t pending; wait_queue_head_t pending;
wait_queue_head_t deathrow; wait_queue_head_t deathrow;
struct urb *dataurb; struct urb *dataurb;
struct urb *controlurb; struct urb *controlurb;
int fragment;
int state; int state;
int current_data_pipe; int current_data_pipe;
Scsi_Host_Template ctempl;
u8 sense_command[SENSE_COMMAND_SIZE];
u8 scsi_state_byte; u8 scsi_state_byte;
}; };
......
...@@ -80,8 +80,7 @@ static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_ ...@@ -80,8 +80,7 @@ static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_
goto err; goto err;
} }
tmp = src->next; tmp = src->next;
list_del (tmp); list_move_tail (tmp, dst);
list_add_tail (tmp, dst);
err: spin_unlock_irqrestore (&s->lock, flags); err: spin_unlock_irqrestore (&s->lock, flags);
return ret; return ret;
...@@ -609,6 +608,7 @@ static int dabusb_open (struct inode *inode, struct file *file) ...@@ -609,6 +608,7 @@ static int dabusb_open (struct inode *inode, struct file *file)
down (&s->mutex); down (&s->mutex);
} }
if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
up(&s->mutex);
err("set_interface failed"); err("set_interface failed");
return -EINVAL; return -EINVAL;
} }
......
This diff is collapsed.
#ifndef PWC_IOCTL_H #ifndef PWC_IOCTL_H
#define PWC_IOCTL_H #define PWC_IOCTL_H
/* (C) 2001 Nemosoft Unv. webcam@smcc.demon.nl /* (C) 2001-2002 Nemosoft Unv. webcam@smcc.demon.nl
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/* /* This is pwc-ioctl.h belonging to PWC 8.7 */
/*
Changes Changes
2001/08/03 Alvarado Added ioctl constants to access methods for 2001/08/03 Alvarado Added ioctl constants to access methods for
changing white balance and red/blue gains changing white balance and red/blue gains
...@@ -52,6 +54,14 @@ ...@@ -52,6 +54,14 @@
#define PWC_FPS_SNAPSHOT 0x00400000 #define PWC_FPS_SNAPSHOT 0x00400000
struct pwc_probe
{
char name[32];
int type;
};
/* pwc_whitebalance.mode values */ /* pwc_whitebalance.mode values */
#define PWC_WB_INDOOR 0 #define PWC_WB_INDOOR 0
#define PWC_WB_OUTDOOR 1 #define PWC_WB_OUTDOOR 1
...@@ -63,9 +73,9 @@ ...@@ -63,9 +73,9 @@
Set mode to one of the PWC_WB_* values above. Set mode to one of the PWC_WB_* values above.
*red and *blue are the respective gains of these colour components inside *red and *blue are the respective gains of these colour components inside
the camera; range 0..65535 the camera; range 0..65535
When mode == PWC_WB_MANUAL, manual_red and manual_blue are set or read; When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
otherwise undefined. otherwise undefined.
read_red and read_blue are read-only. 'read_red' and 'read_blue' are read-only.
*/ */
struct pwc_whitebalance struct pwc_whitebalance
...@@ -75,6 +85,17 @@ struct pwc_whitebalance ...@@ -75,6 +85,17 @@ struct pwc_whitebalance
int read_red, read_blue; /* R/O */ int read_red, read_blue; /* R/O */
}; };
/*
'control_speed' and 'control_delay' are used in automatic whitebalance mode,
and tell the camera how fast it should react to changes in lighting, and
with how much delay. Valid values are 0..65535.
*/
struct pwc_wb_speed
{
int control_speed;
int control_delay;
};
/* Used with VIDIOCPWC[SG]LED */ /* Used with VIDIOCPWC[SG]LED */
struct pwc_leds struct pwc_leds
...@@ -104,6 +125,19 @@ struct pwc_leds ...@@ -104,6 +125,19 @@ struct pwc_leds
/* Get preferred compression quality */ /* Get preferred compression quality */
#define VIDIOCPWCGCQUAL _IOR('v', 195, int) #define VIDIOCPWCGCQUAL _IOR('v', 195, int)
/* This is a probe function; since so many devices are supported, it
becomes difficult to include all the names in programs that want to
check for the enhanced Philips stuff. So in stead, try this PROBE;
it returns a structure with the original name, and the corresponding
Philips type.
To use, fill the structure with zeroes, call PROBE and if that succeeds,
compare the name with that returned from VIDIOCGCAP; they should be the
same. If so, you can be assured it is a Philips (OEM) cam and the type
is valid.
*/
#define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe)
/* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */ /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */
#define VIDIOCPWCSAGC _IOW('v', 200, int) #define VIDIOCPWCSAGC _IOW('v', 200, int)
/* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */ /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */
...@@ -115,9 +149,28 @@ struct pwc_leds ...@@ -115,9 +149,28 @@ struct pwc_leds
#define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance) #define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance)
#define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance) #define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance)
/* Turn LED on/off ; int range 0..65535 */ /* Auto WB speed */
#define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed)
#define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed)
/* LEDs on/off/blink; int range 0..65535 */
#define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds) #define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds)
/* Get state of LED; int range 0..65535 */
#define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds) #define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds)
/* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */
#define VIDIOCPWCSCONTOUR _IOW('v', 206, int)
#define VIDIOCPWCGCONTOUR _IOR('v', 206, int)
/* Backlight compensation; 0 = off, otherwise on */
#define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int)
#define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int)
/* Flickerless mode; = 0 off, otherwise on */
#define VIDIOCPWCSFLICKER _IOW('v', 208, int)
#define VIDIOCPWCGFLICKER _IOR('v', 208, int)
/* Dynamic noise reduction; 0 off, 3 = high noise reduction */
#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int)
#define VIDIOCPWCGDYNNOISE _IOR('v', 209, int)
#endif #endif
/* (C) 1999-2001 Nemosoft Unv. (webcam@smcc.demon.nl) /* (C) 1999-2002 Nemosoft Unv. (webcam@smcc.demon.nl)
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -60,8 +60,8 @@ ...@@ -60,8 +60,8 @@
/* Version block */ /* Version block */
#define PWC_MAJOR 8 #define PWC_MAJOR 8
#define PWC_MINOR 5 #define PWC_MINOR 7
#define PWC_VERSION "8.5" #define PWC_VERSION "8.7"
#define PWC_NAME "pwc" #define PWC_NAME "pwc"
/* Turn certain features on/off */ /* Turn certain features on/off */
...@@ -247,6 +247,7 @@ extern int pwc_get_saturation(struct pwc_device *pdev); ...@@ -247,6 +247,7 @@ extern int pwc_get_saturation(struct pwc_device *pdev);
extern int pwc_set_saturation(struct pwc_device *pdev, int value); extern int pwc_set_saturation(struct pwc_device *pdev, int value);
extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value); extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value);
extern int pwc_get_cmos_sensor(struct pwc_device *pdev);
/* Power down or up the camera; not supported by all models */ /* Power down or up the camera; not supported by all models */
extern int pwc_camera_power(struct pwc_device *pdev, int power); extern int pwc_camera_power(struct pwc_device *pdev, int power);
......
...@@ -1330,7 +1330,13 @@ static int se401_init(struct usb_se401 *se401) ...@@ -1330,7 +1330,13 @@ static int se401_init(struct usb_se401 *se401)
se401->sizes=cp[4]+cp[5]*256; se401->sizes=cp[4]+cp[5]*256;
se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
if (!se401->width)
return 1;
se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
if (!se401->height) {
kfree(se401->width);
return 1;
}
for (i=0; i<se401->sizes; i++) { for (i=0; i<se401->sizes; i++) {
se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256; se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256; se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
......
...@@ -426,6 +426,7 @@ static void CDC_SetEthernetPacketFilter (ether_dev_t *ether_dev) ...@@ -426,6 +426,7 @@ static void CDC_SetEthernetPacketFilter (ether_dev_t *ether_dev)
} }
#endif #endif
static void CDCEther_set_multicast( struct net_device *net ) static void CDCEther_set_multicast( struct net_device *net )
{ {
ether_dev_t *ether_dev = net->priv; ether_dev_t *ether_dev = net->priv;
......
...@@ -401,8 +401,7 @@ static void ipaq_write_gather(struct usb_serial_port *port) ...@@ -401,8 +401,7 @@ static void ipaq_write_gather(struct usb_serial_port *port)
pkt->written += count; pkt->written += count;
priv->queue_len -= count; priv->queue_len -= count;
if (pkt->written == pkt->len) { if (pkt->written == pkt->len) {
list_del(&pkt->list); list_move(&pkt->list, &priv->freelist);
list_add(&pkt->list, &priv->freelist);
priv->free_len += PACKET_SIZE; priv->free_len += PACKET_SIZE;
} }
if (room == 0) { if (room == 0) {
......
...@@ -194,20 +194,24 @@ static void keyspan_pda_wakeup_write( struct usb_serial_port *port ) ...@@ -194,20 +194,24 @@ static void keyspan_pda_wakeup_write( struct usb_serial_port *port )
static void keyspan_pda_request_unthrottle( struct usb_serial *serial ) static void keyspan_pda_request_unthrottle( struct usb_serial *serial )
{ {
int result;
dbg(" request_unthrottle"); dbg(" request_unthrottle");
/* ask the device to tell us when the tx buffer becomes /* ask the device to tell us when the tx buffer becomes
sufficiently empty */ sufficiently empty */
usb_control_msg(serial->dev, result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0), usb_sndctrlpipe(serial->dev, 0),
7, /* request_unthrottle */ 7, /* request_unthrottle */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE USB_TYPE_VENDOR | USB_RECIP_INTERFACE
| USB_DIR_OUT, | USB_DIR_OUT,
16, /* value: threshold */ 16, /* value: threshold */
0, /* index */ 0, /* index */
NULL, NULL,
0, 0,
2*HZ); 2*HZ);
if (result < 0)
dbg("%s - error %d from usb_control_msg",
__FUNCTION__, result);
} }
...@@ -334,14 +338,19 @@ static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state ...@@ -334,14 +338,19 @@ static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state
{ {
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
int value; int value;
int result;
if (break_state == -1) if (break_state == -1)
value = 1; /* start break */ value = 1; /* start break */
else else
value = 0; /* clear break */ value = 0; /* clear break */
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
4, /* set break */ 4, /* set break */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
value, 0, NULL, 0, 2*HZ); value, 0, NULL, 0, 2*HZ);
if (result < 0)
dbg("%s - error %d from usb_control_msg",
__FUNCTION__, result);
/* there is something funky about this.. the TCSBRK that 'cu' performs /* there is something funky about this.. the TCSBRK that 'cu' performs
ought to translate into a break_ctl(-1),break_ctl(0) pair HZ/4 ought to translate into a break_ctl(-1),break_ctl(0) pair HZ/4
seconds apart, but it feels like the break sent isn't as long as it seconds apart, but it feels like the break sent isn't as long as it
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment