Commit 7f6cf788 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 c0630ba1 7730f361
...@@ -2746,6 +2746,14 @@ E: wsalamon@tislabs.com ...@@ -2746,6 +2746,14 @@ E: wsalamon@tislabs.com
E: wsalamon@nai.com E: wsalamon@nai.com
D: portions of the Linux Security Module (LSM) framework and security modules D: portions of the Linux Security Module (LSM) framework and security modules
N: Duncan Sands
E: duncan.sands@wanadoo.fr
W: http://topo.math.u-psud.fr/~sands
D: Alcatel SpeedTouch USB driver
S: 69 rue Dunois
S: 75013 Paris
S: France
N: Robert Sanders N: Robert Sanders
E: gt8134b@prism.gatech.edu E: gt8134b@prism.gatech.edu
D: Dosemu D: Dosemu
......
...@@ -215,6 +215,14 @@ M: Juergen Fischer <fischer@norbit.de> ...@@ -215,6 +215,14 @@ M: Juergen Fischer <fischer@norbit.de>
L: linux-scsi@vger.kernel.org L: linux-scsi@vger.kernel.org
S: Maintained S: Maintained
ALCATEL SPEEDTOUCH USB DRIVER
P: Duncan Sands
M: duncan.sands@wanadoo.fr
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
W: http://www.linux-usb.org/SpeedTouch/
S: Maintained
ALPHA PORT ALPHA PORT
P: Richard Henderson P: Richard Henderson
M: rth@twiddle.net M: rth@twiddle.net
......
obj-$(CONFIG_USB_CATC) += crc32.o obj-$(CONFIG_USB_CATC) += crc32.o
obj-$(CONFIG_USB_SPEEDTOUCH) += crc32.o
obj-$(CONFIG_USB_USBNET) += crc32.o
...@@ -606,6 +606,7 @@ static int acm_probe (struct usb_interface *intf, ...@@ -606,6 +606,7 @@ static int acm_probe (struct usb_interface *intf,
if (!acm->ctrlurb) { if (!acm->ctrlurb) {
err("out of memory"); err("out of memory");
kfree(acm); kfree(acm);
kfree(buf);
return -ENOMEM; return -ENOMEM;
} }
acm->readurb = usb_alloc_urb(0, GFP_KERNEL); acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
...@@ -613,6 +614,7 @@ static int acm_probe (struct usb_interface *intf, ...@@ -613,6 +614,7 @@ static int acm_probe (struct usb_interface *intf,
err("out of memory"); err("out of memory");
usb_free_urb(acm->ctrlurb); usb_free_urb(acm->ctrlurb);
kfree(acm); kfree(acm);
kfree(buf);
return -ENOMEM; return -ENOMEM;
} }
acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
...@@ -621,6 +623,7 @@ static int acm_probe (struct usb_interface *intf, ...@@ -621,6 +623,7 @@ static int acm_probe (struct usb_interface *intf,
usb_free_urb(acm->readurb); usb_free_urb(acm->readurb);
usb_free_urb(acm->ctrlurb); usb_free_urb(acm->ctrlurb);
kfree(acm); kfree(acm);
kfree(buf);
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -219,16 +219,25 @@ static void sg_complete (struct urb *urb, struct pt_regs *regs) ...@@ -219,16 +219,25 @@ static void sg_complete (struct urb *urb, struct pt_regs *regs)
spin_lock_irqsave (&io->lock, flags); spin_lock_irqsave (&io->lock, flags);
/* In 2.5 we require hcds' endpoint queues not to progress after fault /* In 2.5 we require hcds' endpoint queues not to progress after fault
* reports, until the competion callback (this!) returns. That lets * reports, until the completion callback (this!) returns. That lets
* device driver code (like this routine) unlink queued urbs first, * device driver code (like this routine) unlink queued urbs first,
* if it needs to, since the HC won't work on them at all. So it's * if it needs to, since the HC won't work on them at all. So it's
* not possible for page N+1 to overwrite page N, and so on. * not possible for page N+1 to overwrite page N, and so on.
*
* That's only for "hard" faults; "soft" faults (unlinks) sometimes
* complete before the HCD can get requests away from hardware,
* though never during cleanup after a hard fault.
*/ */
if (io->status && urb->actual_length) { if (io->status
err ("driver for bus %s dev %s ep %d-%s corrupted data!", && (io->status != -ECONNRESET
io->dev->bus->bus_name, io->dev->devpath, || urb->status != -ECONNRESET)
&& urb->actual_length) {
dev_err (io->dev->bus->controller,
"dev %s ep%d%s scatterlist error %d/%d\n",
io->dev->devpath,
usb_pipeendpoint (urb->pipe), usb_pipeendpoint (urb->pipe),
usb_pipein (urb->pipe) ? "in" : "out"); usb_pipein (urb->pipe) ? "in" : "out",
urb->status, io->status);
// BUG (); // BUG ();
} }
......
...@@ -195,7 +195,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags) ...@@ -195,7 +195,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
if (!urb || urb->hcpriv || !urb->complete) if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL; return -EINVAL;
if (!(dev = urb->dev) || !dev->bus || dev->devnum <= 0) if (!(dev = urb->dev) || !dev->present || !dev->bus || dev->devnum <= 0)
return -ENODEV; return -ENODEV;
if (!(op = dev->bus->op) || !op->submit_urb) if (!(op = dev->bus->op) || !op->submit_urb)
return -ENODEV; return -ENODEV;
...@@ -376,7 +376,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags) ...@@ -376,7 +376,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
*/ */
int usb_unlink_urb(struct urb *urb) int usb_unlink_urb(struct urb *urb)
{ {
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op) if (urb && urb->dev && urb->dev->present && urb->dev->bus && urb->dev->bus->op)
return urb->dev->bus->op->unlink_urb(urb); return urb->dev->bus->op->unlink_urb(urb);
else else
return -ENODEV; return -ENODEV;
......
...@@ -679,6 +679,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus) ...@@ -679,6 +679,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus)
memset(dev, 0, sizeof(*dev)); memset(dev, 0, sizeof(*dev));
device_initialize(&dev->dev); device_initialize(&dev->dev);
dev->present = 1;
usb_bus_get(bus); usb_bus_get(bus);
...@@ -854,6 +855,10 @@ void usb_disconnect(struct usb_device **pdev) ...@@ -854,6 +855,10 @@ void usb_disconnect(struct usb_device **pdev)
} }
device_unregister(&dev->dev); device_unregister(&dev->dev);
/* mark the device as not present so any further urb submissions for
* this device will fail. */
dev->present = 0;
/* Decrement the reference count, it'll auto free everything when */ /* Decrement the reference count, it'll auto free everything when */
/* it hits 0 which could very well be now */ /* it hits 0 which could very well be now */
usb_put_dev(dev); usb_put_dev(dev);
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/version.h> #include <linux/version.h>
...@@ -306,6 +306,19 @@ static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) ...@@ -306,6 +306,19 @@ static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap)
return 0; return 0;
} }
static int
ehci_reboot (struct notifier_block *self, unsigned long code, void *null)
{
struct ehci_hcd *ehci;
ehci = container_of (self, struct ehci_hcd, reboot_notifier);
/* make BIOS/etc use companion controller during reboot */
writel (0, &ehci->regs->configured_flag);
return 0;
}
/* called by khubd or root hub init threads */ /* called by khubd or root hub init threads */
static int ehci_start (struct usb_hcd *hcd) static int ehci_start (struct usb_hcd *hcd)
...@@ -464,6 +477,9 @@ static int ehci_start (struct usb_hcd *hcd) ...@@ -464,6 +477,9 @@ static int ehci_start (struct usb_hcd *hcd)
* are explicitly handed to companion controller(s), so no TT is * are explicitly handed to companion controller(s), so no TT is
* involved with the root hub. * involved with the root hub.
*/ */
ehci->reboot_notifier.notifier_call = ehci_reboot;
register_reboot_notifier (&ehci->reboot_notifier);
ehci->hcd.state = USB_STATE_READY; ehci->hcd.state = USB_STATE_READY;
writel (FLAG_CF, &ehci->regs->configured_flag); writel (FLAG_CF, &ehci->regs->configured_flag);
readl (&ehci->regs->command); /* unblock posted write */ readl (&ehci->regs->command); /* unblock posted write */
...@@ -520,6 +536,7 @@ static void ehci_stop (struct usb_hcd *hcd) ...@@ -520,6 +536,7 @@ static void ehci_stop (struct usb_hcd *hcd)
/* let companion controllers work when we aren't */ /* let companion controllers work when we aren't */
writel (0, &ehci->regs->configured_flag); writel (0, &ehci->regs->configured_flag);
unregister_reboot_notifier (&ehci->reboot_notifier);
remove_debug_files (ehci); remove_debug_files (ehci);
......
...@@ -81,8 +81,10 @@ struct ehci_hcd { /* one per controller */ ...@@ -81,8 +81,10 @@ struct ehci_hcd { /* one per controller */
struct pci_pool *sitd_pool; /* sitd per split iso urb */ struct pci_pool *sitd_pool; /* sitd per split iso urb */
struct timer_list watchdog; struct timer_list watchdog;
struct notifier_block reboot_notifier;
unsigned stamp; unsigned stamp;
/* irq statistics */
#ifdef EHCI_STATS #ifdef EHCI_STATS
struct ehci_stats stats; struct ehci_stats stats;
# define COUNT(x) do { (x)++; } while (0) # define COUNT(x) do { (x)++; } while (0)
......
...@@ -163,11 +163,10 @@ config USB_POWERMATE ...@@ -163,11 +163,10 @@ config USB_POWERMATE
tristate "Griffin PowerMate and Contour Jog support" tristate "Griffin PowerMate and Contour Jog support"
depends on USB && INPUT depends on USB && INPUT
---help--- ---help---
Say Y here if you want to use Griffin PowerMate or Contour Jog devices. Say Y here if you want to use Griffin PowerMate or Contour Jog devices.
These are stainless steel dials which can measure clockwise and These are aluminum dials which can measure clockwise and anticlockwise
anticlockwise rotation. The dial also acts as a pushbutton. The base rotation. The dial also acts as a pushbutton. The base contains an LED
contains an LED which can be instructed to pulse or to switch to a which can be instructed to pulse or to switch to a particular intensity.
particular intensity.
You can download userspace tools from http://sowerbutts.com/powermate/ You can download userspace tools from http://sowerbutts.com/powermate/
......
...@@ -355,7 +355,7 @@ static struct usb_device_id usb_kbd_id_table [] = { ...@@ -355,7 +355,7 @@ static struct usb_device_id usb_kbd_id_table [] = {
MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
static struct usb_driver usb_kbd_driver = { static struct usb_driver usb_kbd_driver = {
.name = "keyboard", .name = "usbkbd",
.probe = usb_kbd_probe, .probe = usb_kbd_probe,
.disconnect = usb_kbd_disconnect, .disconnect = usb_kbd_disconnect,
.id_table = usb_kbd_id_table, .id_table = usb_kbd_id_table,
......
...@@ -238,7 +238,7 @@ static struct usb_device_id usb_mouse_id_table [] = { ...@@ -238,7 +238,7 @@ static struct usb_device_id usb_mouse_id_table [] = {
MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
static struct usb_driver usb_mouse_driver = { static struct usb_driver usb_mouse_driver = {
.name = "usb_mouse", .name = "usbmouse",
.probe = usb_mouse_probe, .probe = usb_mouse_probe,
.disconnect = usb_mouse_disconnect, .disconnect = usb_mouse_disconnect,
.id_table = usb_mouse_id_table, .id_table = usb_mouse_id_table,
......
/* /*
* OmniVision OV511 Camera-to-USB Bridge Driver * OmniVision OV511 Camera-to-USB Bridge Driver
* *
* Copyright (c) 1999-2002 Mark W. McClelland * Copyright (c) 1999-2003 Mark W. McClelland
* Original decompression code Copyright 1998-2000 OmniVision Technologies * Original decompression code Copyright 1998-2000 OmniVision Technologies
* Many improvements by Bret Wallach <bwallac1@san.rr.com> * Many improvements by Bret Wallach <bwallac1@san.rr.com>
* Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000) * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
/* /*
* Version Information * Version Information
*/ */
#define DRIVER_VERSION "v1.63 for Linux 2.5" #define DRIVER_VERSION "v1.64 for Linux 2.5"
#define EMAIL "mark@alpha.dyndns.org" #define EMAIL "mark@alpha.dyndns.org"
#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach \ #define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach \
& Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \ & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
...@@ -137,7 +137,7 @@ MODULE_PARM_DESC(snapshot, "Enable snapshot mode"); ...@@ -137,7 +137,7 @@ MODULE_PARM_DESC(snapshot, "Enable snapshot mode");
MODULE_PARM(cams, "i"); MODULE_PARM(cams, "i");
MODULE_PARM_DESC(cams, "Number of simultaneous cameras"); MODULE_PARM_DESC(cams, "Number of simultaneous cameras");
MODULE_PARM(compress, "i"); MODULE_PARM(compress, "i");
MODULE_PARM_DESC(compress, "Turn on compression (not reliable yet)"); MODULE_PARM_DESC(compress, "Turn on compression");
MODULE_PARM(testpat, "i"); MODULE_PARM(testpat, "i");
MODULE_PARM_DESC(testpat, MODULE_PARM_DESC(testpat,
"Replace image with vertical bar testpattern (only partially working)"); "Replace image with vertical bar testpattern (only partially working)");
...@@ -1349,6 +1349,13 @@ ov51x_restart(struct usb_ov511 *ov) ...@@ -1349,6 +1349,13 @@ ov51x_restart(struct usb_ov511 *ov)
return 0; return 0;
} }
/* Sleeps until no frames are active. Returns !0 if got signal */
static int
ov51x_wait_frames_inactive(struct usb_ov511 *ov)
{
return wait_event_interruptible(ov->wq, ov->curframe < 0);
}
/* Resets the hardware snapshot button */ /* Resets the hardware snapshot button */
static void static void
ov51x_clear_snapshot(struct usb_ov511 *ov) ov51x_clear_snapshot(struct usb_ov511 *ov)
...@@ -2121,7 +2128,7 @@ sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val) ...@@ -2121,7 +2128,7 @@ sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val)
return 0; return 0;
} }
#endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */ #endif /* CONFIG_VIDEO_PROC_FS */
/* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */ /* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */
static void static void
...@@ -2486,8 +2493,6 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height, ...@@ -2486,8 +2493,6 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height,
/******** Clock programming ********/ /******** Clock programming ********/
// FIXME: Test this with OV6630
/* The OV6620 needs special handling. This prevents the /* The OV6620 needs special handling. This prevents the
* severe banding that normally occurs */ * severe banding that normally occurs */
if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630)
...@@ -2995,6 +3000,7 @@ ov51x_set_default_params(struct usb_ov511 *ov) ...@@ -2995,6 +3000,7 @@ ov51x_set_default_params(struct usb_ov511 *ov)
ov->frame[i].format = force_palette; ov->frame[i].format = force_palette;
else else
ov->frame[i].format = VIDEO_PALETTE_YUV420; ov->frame[i].format = VIDEO_PALETTE_YUV420;
ov->frame[i].depth = get_depth(ov->frame[i].format); ov->frame[i].depth = get_depth(ov->frame[i].format);
} }
...@@ -3577,12 +3583,8 @@ ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n) ...@@ -3577,12 +3583,8 @@ ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
if (frame->scanstate == STATE_LINES) { if (frame->scanstate == STATE_LINES) {
int nextf; int nextf;
frame->grabstate = FRAME_DONE; // FIXME: Is this right? frame->grabstate = FRAME_DONE;
wake_up_interruptible(&frame->wq);
if (waitqueue_active(&frame->wq)) {
frame->grabstate = FRAME_DONE;
wake_up_interruptible(&frame->wq);
}
/* If next frame is ready or grabbing, /* If next frame is ready or grabbing,
* point to it */ * point to it */
...@@ -3747,12 +3749,8 @@ ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n) ...@@ -3747,12 +3749,8 @@ ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
if (frame->scanstate == STATE_LINES) { if (frame->scanstate == STATE_LINES) {
int nextf; int nextf;
frame->grabstate = FRAME_DONE; // FIXME: Is this right? frame->grabstate = FRAME_DONE;
wake_up_interruptible(&frame->wq);
if (waitqueue_active(&frame->wq)) {
frame->grabstate = FRAME_DONE;
wake_up_interruptible(&frame->wq);
}
/* If next frame is ready or grabbing, /* If next frame is ready or grabbing,
* point to it */ * point to it */
...@@ -4228,7 +4226,7 @@ ov51x_alloc(struct usb_ov511 *ov) ...@@ -4228,7 +4226,7 @@ ov51x_alloc(struct usb_ov511 *ov)
} }
static void static void
ov51x_dealloc(struct usb_ov511 *ov, int now) ov51x_dealloc(struct usb_ov511 *ov)
{ {
PDEBUG(4, "entered"); PDEBUG(4, "entered");
down(&ov->buf_lock); down(&ov->buf_lock);
...@@ -4258,10 +4256,6 @@ ov51x_v4l1_open(struct inode *inode, struct file *file) ...@@ -4258,10 +4256,6 @@ ov51x_v4l1_open(struct inode *inode, struct file *file)
if (ov->user) if (ov->user)
goto out; goto out;
err = ov51x_alloc(ov);
if (err < 0)
goto out;
ov->sub_flag = 0; ov->sub_flag = 0;
/* In case app doesn't set them... */ /* In case app doesn't set them... */
...@@ -4283,9 +4277,13 @@ ov51x_v4l1_open(struct inode *inode, struct file *file) ...@@ -4283,9 +4277,13 @@ ov51x_v4l1_open(struct inode *inode, struct file *file)
goto out; goto out;
} }
err = ov51x_alloc(ov);
if (err < 0)
goto out;
err = ov51x_init_isoc(ov); err = ov51x_init_isoc(ov);
if (err) { if (err) {
ov51x_dealloc(ov, 0); ov51x_dealloc(ov);
goto out; goto out;
} }
...@@ -4319,7 +4317,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) ...@@ -4319,7 +4317,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file)
ov51x_led_control(ov, 0); ov51x_led_control(ov, 0);
if (ov->dev) if (ov->dev)
ov51x_dealloc(ov, 0); ov51x_dealloc(ov);
up(&ov->lock); up(&ov->lock);
...@@ -4331,7 +4329,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) ...@@ -4331,7 +4329,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file)
ov->cbuf = NULL; ov->cbuf = NULL;
up(&ov->cbuf_lock); up(&ov->cbuf_lock);
ov51x_dealloc(ov, 1); ov51x_dealloc(ov);
kfree(ov); kfree(ov);
ov = NULL; ov = NULL;
} }
...@@ -4449,7 +4447,7 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, ...@@ -4449,7 +4447,7 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
case VIDIOCSPICT: case VIDIOCSPICT:
{ {
struct video_picture *p = arg; struct video_picture *p = arg;
int i; int i, rc;
PDEBUG(4, "VIDIOCSPICT"); PDEBUG(4, "VIDIOCSPICT");
...@@ -4469,10 +4467,9 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, ...@@ -4469,10 +4467,9 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
if (p->palette != ov->frame[0].format) { if (p->palette != ov->frame[0].format) {
PDEBUG(4, "Detected format change"); PDEBUG(4, "Detected format change");
/* If we're collecting previous frame wait rc = ov51x_wait_frames_inactive(ov);
before changing modes */ if (rc)
interruptible_sleep_on(&ov->wq); return rc;
if (signal_pending(current)) return -EINTR;
mode_init_regs(ov, ov->frame[0].width, mode_init_regs(ov, ov->frame[0].width,
ov->frame[0].height, p->palette, ov->sub_flag); ov->frame[0].height, p->palette, ov->sub_flag);
...@@ -4530,7 +4527,7 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, ...@@ -4530,7 +4527,7 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
case VIDIOCSWIN: case VIDIOCSWIN:
{ {
struct video_window *vw = arg; struct video_window *vw = arg;
int i, result; int i, rc;
PDEBUG(4, "VIDIOCSWIN: %dx%d", vw->width, vw->height); PDEBUG(4, "VIDIOCSWIN: %dx%d", vw->width, vw->height);
...@@ -4545,15 +4542,14 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, ...@@ -4545,15 +4542,14 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
return -EINVAL; return -EINVAL;
#endif #endif
/* If we're collecting previous frame wait rc = ov51x_wait_frames_inactive(ov);
before changing modes */ if (rc)
interruptible_sleep_on(&ov->wq); return rc;
if (signal_pending(current)) return -EINTR;
result = mode_init_regs(ov, vw->width, vw->height, rc = mode_init_regs(ov, vw->width, vw->height,
ov->frame[0].format, ov->sub_flag); ov->frame[0].format, ov->sub_flag);
if (result < 0) if (rc < 0)
return result; return rc;
for (i = 0; i < OV511_NUMFRAMES; i++) { for (i = 0; i < OV511_NUMFRAMES; i++) {
ov->frame[i].width = vw->width; ov->frame[i].width = vw->width;
...@@ -4600,7 +4596,7 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, ...@@ -4600,7 +4596,7 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
case VIDIOCMCAPTURE: case VIDIOCMCAPTURE:
{ {
struct video_mmap *vm = arg; struct video_mmap *vm = arg;
int ret, depth; int rc, depth;
unsigned int f = vm->frame; unsigned int f = vm->frame;
PDEBUG(4, "VIDIOCMCAPTURE: frame: %d, %dx%d, %s", f, vm->width, PDEBUG(4, "VIDIOCMCAPTURE: frame: %d, %dx%d, %s", f, vm->width,
...@@ -4642,14 +4638,14 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, ...@@ -4642,14 +4638,14 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
(ov->frame[f].depth != depth)) { (ov->frame[f].depth != depth)) {
PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters"); PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters");
/* If we're collecting previous frame wait rc = ov51x_wait_frames_inactive(ov);
before changing modes */ if (rc)
interruptible_sleep_on(&ov->wq); return rc;
if (signal_pending(current)) return -EINTR;
ret = mode_init_regs(ov, vm->width, vm->height, rc = mode_init_regs(ov, vm->width, vm->height,
vm->format, ov->sub_flag); vm->format, ov->sub_flag);
#if 0 #if 0
if (ret < 0) { if (rc < 0) {
PDEBUG(1, "Got error while initializing regs "); PDEBUG(1, "Got error while initializing regs ");
return ret; return ret;
} }
...@@ -4702,18 +4698,15 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, ...@@ -4702,18 +4698,15 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
return rc; return rc;
if (frame->grabstate == FRAME_ERROR) { if (frame->grabstate == FRAME_ERROR) {
int ret; if ((rc = ov51x_new_frame(ov, fnum)) < 0)
return rc;
if ((ret = ov51x_new_frame(ov, fnum)) < 0)
return ret;
goto redo; goto redo;
} }
/* Fall through */ /* Fall through */
case FRAME_DONE: case FRAME_DONE:
if (ov->snap_enabled && !frame->snapshot) { if (ov->snap_enabled && !frame->snapshot) {
int ret; if ((rc = ov51x_new_frame(ov, fnum)) < 0)
if ((ret = ov51x_new_frame(ov, fnum)) < 0) return rc;
return ret;
goto redo; goto redo;
} }
...@@ -6089,7 +6082,6 @@ ov518_configure(struct usb_ov511 *ov) ...@@ -6089,7 +6082,6 @@ ov518_configure(struct usb_ov511 *ov)
return -EBUSY; return -EBUSY;
} }
/**************************************************************************** /****************************************************************************
* *
* USB routines * USB routines
...@@ -6097,11 +6089,10 @@ ov518_configure(struct usb_ov511 *ov) ...@@ -6097,11 +6089,10 @@ ov518_configure(struct usb_ov511 *ov)
***************************************************************************/ ***************************************************************************/
static int static int
ov51x_probe(struct usb_interface *intf, ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
const struct usb_device_id *id)
{ {
struct usb_device *dev = interface_to_usbdev(intf); struct usb_device *dev = interface_to_usbdev(intf);
struct usb_interface_descriptor *interface; struct usb_interface_descriptor *idesc;
struct usb_ov511 *ov; struct usb_ov511 *ov;
int i; int i;
int registered = 0; int registered = 0;
...@@ -6112,12 +6103,11 @@ ov51x_probe(struct usb_interface *intf, ...@@ -6112,12 +6103,11 @@ ov51x_probe(struct usb_interface *intf,
if (dev->descriptor.bNumConfigurations != 1) if (dev->descriptor.bNumConfigurations != 1)
return -ENODEV; return -ENODEV;
interface = &intf->altsetting[0].desc; idesc = &intf->altsetting[0].desc;
/* Checking vendor/product should be enough, but what the hell */ if (idesc->bInterfaceClass != 0xFF)
if (interface->bInterfaceClass != 0xFF)
return -ENODEV; return -ENODEV;
if (interface->bInterfaceSubClass != 0x00) if (idesc->bInterfaceSubClass != 0x00)
return -ENODEV; return -ENODEV;
if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) { if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) {
...@@ -6128,7 +6118,7 @@ ov51x_probe(struct usb_interface *intf, ...@@ -6128,7 +6118,7 @@ ov51x_probe(struct usb_interface *intf,
memset(ov, 0, sizeof(*ov)); memset(ov, 0, sizeof(*ov));
ov->dev = dev; ov->dev = dev;
ov->iface = interface->bInterfaceNumber; ov->iface = idesc->bInterfaceNumber;
ov->led_policy = led; ov->led_policy = led;
ov->compress = compress; ov->compress = compress;
ov->lightfreq = lightfreq; ov->lightfreq = lightfreq;
...@@ -6272,7 +6262,7 @@ ov51x_probe(struct usb_interface *intf, ...@@ -6272,7 +6262,7 @@ ov51x_probe(struct usb_interface *intf,
error_out: error_out:
err("Camera initialization failed"); err("Camera initialization failed");
return -ENOMEM; return -EIO;
} }
static void static void
...@@ -6284,6 +6274,7 @@ ov51x_disconnect(struct usb_interface *intf) ...@@ -6284,6 +6274,7 @@ ov51x_disconnect(struct usb_interface *intf)
PDEBUG(3, ""); PDEBUG(3, "");
usb_set_intfdata (intf, NULL); usb_set_intfdata (intf, NULL);
if (!ov) if (!ov)
return; return;
...@@ -6298,10 +6289,9 @@ ov51x_disconnect(struct usb_interface *intf) ...@@ -6298,10 +6289,9 @@ ov51x_disconnect(struct usb_interface *intf)
/* This will cause the process to request another frame */ /* This will cause the process to request another frame */
for (n = 0; n < OV511_NUMFRAMES; n++) for (n = 0; n < OV511_NUMFRAMES; n++)
if (waitqueue_active(&ov->frame[n].wq)) wake_up_interruptible(&ov->frame[n].wq);
wake_up_interruptible(&ov->frame[n].wq);
if (waitqueue_active(&ov->wq)) wake_up_interruptible(&ov->wq);
wake_up_interruptible(&ov->wq);
ov->streaming = 0; ov->streaming = 0;
ov51x_unlink_isoc(ov); ov51x_unlink_isoc(ov);
...@@ -6317,7 +6307,7 @@ ov51x_disconnect(struct usb_interface *intf) ...@@ -6317,7 +6307,7 @@ ov51x_disconnect(struct usb_interface *intf)
ov->cbuf = NULL; ov->cbuf = NULL;
up(&ov->cbuf_lock); up(&ov->cbuf_lock);
ov51x_dealloc(ov, 1); ov51x_dealloc(ov);
kfree(ov); kfree(ov);
ov = NULL; ov = NULL;
} }
...@@ -6333,7 +6323,6 @@ static struct usb_driver ov511_driver = { ...@@ -6333,7 +6323,6 @@ static struct usb_driver ov511_driver = {
.disconnect = ov51x_disconnect .disconnect = ov51x_disconnect
}; };
/**************************************************************************** /****************************************************************************
* *
* Module routines * Module routines
......
...@@ -96,6 +96,15 @@ config USB_LCD ...@@ -96,6 +96,15 @@ config USB_LCD
config USB_SPEEDTOUCH config USB_SPEEDTOUCH
tristate "Alcatel Speedtouch ADSL USB Modem" tristate "Alcatel Speedtouch ADSL USB Modem"
depends on USB && ATM depends on USB && ATM
help
Say Y here if you have an Alcatel SpeedTouch USB or SpeedTouch 330
modem. In order to use your modem you will need to install some user
space tools, see <http://www.linux-usb.org/SpeedTouch/> for details.
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 speedtch. If you want to compile it as
a module, say M here and read <file:Documentation/modules.txt>.
config USB_TEST config USB_TEST
tristate "USB testing driver (DEVELOPMENT)" tristate "USB testing driver (DEVELOPMENT)"
......
This diff is collapsed.
...@@ -58,7 +58,6 @@ struct atmsar_vcc_data { ...@@ -58,7 +58,6 @@ struct atmsar_vcc_data {
int type; int type;
/* connection specific non-atmsar data */ /* connection specific non-atmsar data */
struct sk_buff *(*alloc_tx) (struct atm_vcc * vcc, unsigned int size);
struct atm_vcc *vcc; struct atm_vcc *vcc;
struct k_atm_aal_stats *stats; struct k_atm_aal_stats *stats;
unsigned short mtu; /* max is actually 65k for AAL5... */ unsigned short mtu; /* max is actually 65k for AAL5... */
...@@ -81,15 +80,8 @@ extern struct atmsar_vcc_data *atmsar_open (struct atmsar_vcc_data **list, struc ...@@ -81,15 +80,8 @@ extern struct atmsar_vcc_data *atmsar_open (struct atmsar_vcc_data **list, struc
unchar gfc, uint flags); unchar gfc, uint flags);
extern void atmsar_close (struct atmsar_vcc_data **list, struct atmsar_vcc_data *vcc); extern void atmsar_close (struct atmsar_vcc_data **list, struct atmsar_vcc_data *vcc);
extern struct sk_buff *atmsar_encode_rawcell (struct atmsar_vcc_data *ctx, struct sk_buff *skb);
extern struct sk_buff *atmsar_encode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb);
struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_buff *skb, struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_buff *skb,
struct atmsar_vcc_data **ctx); struct atmsar_vcc_data **ctx);
struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb); struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb);
struct sk_buff *atmsar_alloc_tx (struct atmsar_vcc_data *vcc, unsigned int size);
unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target, unsigned int pdu_length);
#endif /* _ATMSAR_H_ */ #endif /* _ATMSAR_H_ */
This diff is collapsed.
...@@ -130,6 +130,7 @@ static struct usb_device_id usb_klsi_table[] = { ...@@ -130,6 +130,7 @@ static struct usb_device_id usb_klsi_table[] = {
{ USB_DEVICE(0x03e8, 0x0008) }, /* AOX Endpoints USB Ethernet */ { USB_DEVICE(0x03e8, 0x0008) }, /* AOX Endpoints USB Ethernet */
{ USB_DEVICE(0x04bb, 0x0901) }, /* I-O DATA USB-ET/T */ { USB_DEVICE(0x04bb, 0x0901) }, /* I-O DATA USB-ET/T */
{ USB_DEVICE(0x0506, 0x03e8) }, /* 3Com 3C19250 */ { USB_DEVICE(0x0506, 0x03e8) }, /* 3Com 3C19250 */
{ USB_DEVICE(0x0506, 0x11f8) }, /* 3Com 3C460 */
{ USB_DEVICE(0x0557, 0x2002) }, /* ATEN USB Ethernet */ { USB_DEVICE(0x0557, 0x2002) }, /* ATEN USB Ethernet */
{ USB_DEVICE(0x0557, 0x4000) }, /* D-Link DSB-650C */ { USB_DEVICE(0x0557, 0x4000) }, /* D-Link DSB-650C */
{ USB_DEVICE(0x0565, 0x0002) }, /* Peracom Enet */ { USB_DEVICE(0x0565, 0x0002) }, /* Peracom Enet */
...@@ -712,7 +713,7 @@ static void kaweth_usb_transmit_complete(struct urb *urb, struct pt_regs *regs) ...@@ -712,7 +713,7 @@ static void kaweth_usb_transmit_complete(struct urb *urb, struct pt_regs *regs)
static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
{ {
struct kaweth_device *kaweth = net->priv; struct kaweth_device *kaweth = net->priv;
char *private_header; u16 *private_header;
int res; int res;
...@@ -744,7 +745,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) ...@@ -744,7 +745,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
} }
private_header = __skb_push(skb, 2); private_header = __skb_push(skb, 2);
*private_header = cpu_to_le16(skb->len); *private_header = cpu_to_le16(skb->len-2);
kaweth->tx_skb = skb; kaweth->tx_skb = skb;
usb_fill_bulk_urb(kaweth->tx_urb, usb_fill_bulk_urb(kaweth->tx_urb,
......
...@@ -133,6 +133,7 @@ struct usb_eth_dev { ...@@ -133,6 +133,7 @@ struct usb_eth_dev {
#define VENDOR_LANEED 0x056e #define VENDOR_LANEED 0x056e
#define VENDOR_LINKSYS 0x066b #define VENDOR_LINKSYS 0x066b
#define VENDOR_MELCO 0x0411 #define VENDOR_MELCO 0x0411
#define VENDOR_MOBILITY 0x1342
#define VENDOR_NETGEAR 0x0846 #define VENDOR_NETGEAR 0x0846
#define VENDOR_SMARTBRIDGES 0x08d1 #define VENDOR_SMARTBRIDGES 0x08d1
#define VENDOR_SMC 0x0707 #define VENDOR_SMC 0x0707
...@@ -167,7 +168,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c, ...@@ -167,7 +168,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet", PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
VENDOR_ADMTEK, 0x8511, VENDOR_ADMTEK, 0x8511,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
...@@ -215,6 +216,8 @@ PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1, ...@@ -215,6 +216,8 @@ PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002, PEGASUS_DEV( "GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002,
DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA ) DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
PEGASUS_DEV( "EasiDock Ethernet", VENDOR_MOBILITY, 0x0304,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000, PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c, PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
......
...@@ -297,10 +297,14 @@ config USB_SERIAL_KEYSPAN_USA19W ...@@ -297,10 +297,14 @@ config USB_SERIAL_KEYSPAN_USA19W
config USB_SERIAL_KEYSPAN_USA19QW config USB_SERIAL_KEYSPAN_USA19QW
bool "USB Keyspan USA-19QW Firmware" bool "USB Keyspan USA-19QW Firmware"
depends on USB_SERIAL_KEYSPAN depends on USB_SERIAL_KEYSPAN
help
Say Y here to include firmware for the USA-19QW converter.
config USB_SERIAL_KEYSPAN_USA19QI config USB_SERIAL_KEYSPAN_USA19QI
bool "USB Keyspan USA-19QI Firmware" bool "USB Keyspan USA-19QI Firmware"
depends on USB_SERIAL_KEYSPAN depends on USB_SERIAL_KEYSPAN
help
Say Y here to include firmware for the USA-19QI converter.
config USB_SERIAL_KEYSPAN_USA49W config USB_SERIAL_KEYSPAN_USA49W
bool "USB Keyspan USA-49W Firmware" bool "USB Keyspan USA-49W Firmware"
......
...@@ -141,7 +141,6 @@ static int __init usb_console_setup(struct console *co, char *options) ...@@ -141,7 +141,6 @@ static int __init usb_console_setup(struct console *co, char *options)
} }
port = &serial->port[0]; port = &serial->port[0];
down (&port->sem);
port->tty = NULL; port->tty = NULL;
info->port = port; info->port = port;
...@@ -158,8 +157,6 @@ static int __init usb_console_setup(struct console *co, char *options) ...@@ -158,8 +157,6 @@ static int __init usb_console_setup(struct console *co, char *options)
port->open_count = 0; port->open_count = 0;
} }
up (&port->sem);
if (retval) { if (retval) {
err ("could not open USB console port"); err ("could not open USB console port");
return retval; return retval;
...@@ -208,8 +205,6 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun ...@@ -208,8 +205,6 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
if (count == 0) if (count == 0)
return; return;
down (&port->sem);
dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
if (!port->open_count) { if (!port->open_count) {
...@@ -224,7 +219,6 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun ...@@ -224,7 +219,6 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
retval = usb_serial_generic_write(port, 0, buf, count); retval = usb_serial_generic_write(port, 0, buf, count);
exit: exit:
up (&port->sem);
dbg("%s - return value (if we had one): %d", __FUNCTION__, retval); dbg("%s - return value (if we had one): %d", __FUNCTION__, retval);
} }
......
...@@ -391,7 +391,11 @@ static LIST_HEAD(usb_serial_driver_list); ...@@ -391,7 +391,11 @@ static LIST_HEAD(usb_serial_driver_list);
struct usb_serial *usb_serial_get_by_minor (unsigned int minor) struct usb_serial *usb_serial_get_by_minor (unsigned int minor)
{ {
return serial_table[minor]; struct usb_serial *serial = serial_table[minor];
if (serial)
kobject_get (&serial->kobj);
return serial;
} }
static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_ports, unsigned int *minor) static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_ports, unsigned int *minor)
...@@ -468,7 +472,6 @@ static int serial_open (struct tty_struct *tty, struct file * filp) ...@@ -468,7 +472,6 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
port = &serial->port[portNumber]; port = &serial->port[portNumber];
tty->driver_data = port; tty->driver_data = port;
down (&port->sem);
port->tty = tty; port->tty = tty;
/* lock this module before we call it, /* lock this module before we call it,
...@@ -492,8 +495,6 @@ static int serial_open (struct tty_struct *tty, struct file * filp) ...@@ -492,8 +495,6 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
} }
} }
bailout: bailout:
up (&port->sem);
return retval; return retval;
} }
...@@ -516,6 +517,7 @@ static void __serial_close(struct usb_serial_port *port, struct file *filp) ...@@ -516,6 +517,7 @@ static void __serial_close(struct usb_serial_port *port, struct file *filp)
} }
module_put(port->serial->type->owner); module_put(port->serial->type->owner);
kobject_put(&port->serial->kobj);
} }
static void serial_close(struct tty_struct *tty, struct file * filp) static void serial_close(struct tty_struct *tty, struct file * filp)
...@@ -526,16 +528,12 @@ static void serial_close(struct tty_struct *tty, struct file * filp) ...@@ -526,16 +528,12 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
if (!serial) if (!serial)
return; return;
down (&port->sem);
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
/* if disconnect beat us to the punch here, there's nothing to do */ /* if disconnect beat us to the punch here, there's nothing to do */
if (tty->driver_data) { if (tty->driver_data) {
__serial_close(port, filp); __serial_close(port, filp);
} }
up (&port->sem);
} }
static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
...@@ -547,8 +545,6 @@ static int serial_write (struct tty_struct * tty, int from_user, const unsigned ...@@ -547,8 +545,6 @@ static int serial_write (struct tty_struct * tty, int from_user, const unsigned
if (!serial) if (!serial)
return -ENODEV; return -ENODEV;
down (&port->sem);
dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
if (!port->open_count) { if (!port->open_count) {
...@@ -563,7 +559,6 @@ static int serial_write (struct tty_struct * tty, int from_user, const unsigned ...@@ -563,7 +559,6 @@ static int serial_write (struct tty_struct * tty, int from_user, const unsigned
retval = usb_serial_generic_write(port, from_user, buf, count); retval = usb_serial_generic_write(port, from_user, buf, count);
exit: exit:
up (&port->sem);
return retval; return retval;
} }
...@@ -576,8 +571,6 @@ static int serial_write_room (struct tty_struct *tty) ...@@ -576,8 +571,6 @@ static int serial_write_room (struct tty_struct *tty)
if (!serial) if (!serial)
return -ENODEV; return -ENODEV;
down (&port->sem);
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
if (!port->open_count) { if (!port->open_count) {
...@@ -592,7 +585,6 @@ static int serial_write_room (struct tty_struct *tty) ...@@ -592,7 +585,6 @@ static int serial_write_room (struct tty_struct *tty)
retval = usb_serial_generic_write_room(port); retval = usb_serial_generic_write_room(port);
exit: exit:
up (&port->sem);
return retval; return retval;
} }
...@@ -605,8 +597,6 @@ static int serial_chars_in_buffer (struct tty_struct *tty) ...@@ -605,8 +597,6 @@ static int serial_chars_in_buffer (struct tty_struct *tty)
if (!serial) if (!serial)
return -ENODEV; return -ENODEV;
down (&port->sem);
dbg("%s = port %d", __FUNCTION__, port->number); dbg("%s = port %d", __FUNCTION__, port->number);
if (!port->open_count) { if (!port->open_count) {
...@@ -621,7 +611,6 @@ static int serial_chars_in_buffer (struct tty_struct *tty) ...@@ -621,7 +611,6 @@ static int serial_chars_in_buffer (struct tty_struct *tty)
retval = usb_serial_generic_chars_in_buffer(port); retval = usb_serial_generic_chars_in_buffer(port);
exit: exit:
up (&port->sem);
return retval; return retval;
} }
...@@ -633,8 +622,6 @@ static void serial_throttle (struct tty_struct * tty) ...@@ -633,8 +622,6 @@ static void serial_throttle (struct tty_struct * tty)
if (!serial) if (!serial)
return; return;
down (&port->sem);
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
if (!port->open_count) { if (!port->open_count) {
...@@ -647,7 +634,6 @@ static void serial_throttle (struct tty_struct * tty) ...@@ -647,7 +634,6 @@ static void serial_throttle (struct tty_struct * tty)
serial->type->throttle(port); serial->type->throttle(port);
exit: exit:
up (&port->sem);
} }
static void serial_unthrottle (struct tty_struct * tty) static void serial_unthrottle (struct tty_struct * tty)
...@@ -658,8 +644,6 @@ static void serial_unthrottle (struct tty_struct * tty) ...@@ -658,8 +644,6 @@ static void serial_unthrottle (struct tty_struct * tty)
if (!serial) if (!serial)
return; return;
down (&port->sem);
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
if (!port->open_count) { if (!port->open_count) {
...@@ -672,7 +656,6 @@ static void serial_unthrottle (struct tty_struct * tty) ...@@ -672,7 +656,6 @@ static void serial_unthrottle (struct tty_struct * tty)
serial->type->unthrottle(port); serial->type->unthrottle(port);
exit: exit:
up (&port->sem);
} }
static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
...@@ -684,8 +667,6 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in ...@@ -684,8 +667,6 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in
if (!serial) if (!serial)
return -ENODEV; return -ENODEV;
down (&port->sem);
dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
if (!port->open_count) { if (!port->open_count) {
...@@ -700,7 +681,6 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in ...@@ -700,7 +681,6 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in
retval = -ENOIOCTLCMD; retval = -ENOIOCTLCMD;
exit: exit:
up (&port->sem);
return retval; return retval;
} }
...@@ -712,8 +692,6 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old) ...@@ -712,8 +692,6 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
if (!serial) if (!serial)
return; return;
down (&port->sem);
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
if (!port->open_count) { if (!port->open_count) {
...@@ -726,7 +704,6 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old) ...@@ -726,7 +704,6 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
serial->type->set_termios(port, old); serial->type->set_termios(port, old);
exit: exit:
up (&port->sem);
} }
static void serial_break (struct tty_struct *tty, int break_state) static void serial_break (struct tty_struct *tty, int break_state)
...@@ -737,8 +714,6 @@ static void serial_break (struct tty_struct *tty, int break_state) ...@@ -737,8 +714,6 @@ static void serial_break (struct tty_struct *tty, int break_state)
if (!serial) if (!serial)
return; return;
down (&port->sem);
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
if (!port->open_count) { if (!port->open_count) {
...@@ -751,7 +726,6 @@ static void serial_break (struct tty_struct *tty, int break_state) ...@@ -751,7 +726,6 @@ static void serial_break (struct tty_struct *tty, int break_state)
serial->type->break_ctl(port, break_state); serial->type->break_ctl(port, break_state);
exit: exit:
up (&port->sem);
} }
static void serial_shutdown (struct usb_serial *serial) static void serial_shutdown (struct usb_serial *serial)
...@@ -797,6 +771,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int ...@@ -797,6 +771,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
begin += length; begin += length;
length = 0; length = 0;
} }
kobject_put(&serial->kobj);
} }
*eof = 1; *eof = 1;
done: done:
...@@ -833,6 +808,75 @@ void usb_serial_port_softint(void *private) ...@@ -833,6 +808,75 @@ void usb_serial_port_softint(void *private)
wake_up_interruptible(&tty->write_wait); wake_up_interruptible(&tty->write_wait);
} }
static void destroy_serial (struct kobject *kobj)
{
struct usb_serial *serial;
struct usb_serial_port *port;
int i;
dbg ("%s", __FUNCTION__);
serial = to_usb_serial(kobj);
/* fail all future close/read/write/ioctl/etc calls */
for (i = 0; i < serial->num_ports; ++i) {
port = &serial->port[i];
if (port->tty != NULL) {
port->tty->driver_data = NULL;
while (port->open_count > 0) {
__serial_close(port, NULL);
}
}
}
serial_shutdown (serial);
for (i = 0; i < serial->num_ports; ++i)
device_unregister(&serial->port[i].dev);
for (i = 0; i < serial->num_ports; ++i)
serial->port[i].open_count = 0;
for (i = 0; i < serial->num_bulk_in; ++i) {
port = &serial->port[i];
if (port->read_urb) {
usb_unlink_urb (port->read_urb);
usb_free_urb (port->read_urb);
}
if (port->bulk_in_buffer)
kfree (port->bulk_in_buffer);
}
for (i = 0; i < serial->num_bulk_out; ++i) {
port = &serial->port[i];
if (port->write_urb) {
usb_unlink_urb (port->write_urb);
usb_free_urb (port->write_urb);
}
if (port->bulk_out_buffer)
kfree (port->bulk_out_buffer);
}
for (i = 0; i < serial->num_interrupt_in; ++i) {
port = &serial->port[i];
if (port->interrupt_in_urb) {
usb_unlink_urb (port->interrupt_in_urb);
usb_free_urb (port->interrupt_in_urb);
}
if (port->interrupt_in_buffer)
kfree (port->interrupt_in_buffer);
}
/* return the minor range that this device had */
return_serial (serial);
usb_put_dev(serial->dev);
/* free up any memory that we allocated */
kfree (serial);
}
static struct kobj_type usb_serial_kobj_type = {
.release = destroy_serial,
};
static struct usb_serial * create_serial (struct usb_device *dev, static struct usb_serial * create_serial (struct usb_device *dev,
struct usb_interface *interface, struct usb_interface *interface,
struct usb_serial_device_type *type) struct usb_serial_device_type *type)
...@@ -845,12 +889,16 @@ static struct usb_serial * create_serial (struct usb_device *dev, ...@@ -845,12 +889,16 @@ static struct usb_serial * create_serial (struct usb_device *dev,
return NULL; return NULL;
} }
memset (serial, 0, sizeof(*serial)); memset (serial, 0, sizeof(*serial));
serial->dev = dev; serial->dev = usb_get_dev(dev);
serial->type = type; serial->type = type;
serial->interface = interface; serial->interface = interface;
serial->vendor = dev->descriptor.idVendor; serial->vendor = dev->descriptor.idVendor;
serial->product = dev->descriptor.idProduct; serial->product = dev->descriptor.idProduct;
/* initialize the kobject portion of the usb_device */
kobject_init(&serial->kobj);
serial->kobj.ktype = &usb_serial_kobj_type;
return serial; return serial;
} }
...@@ -1113,7 +1161,6 @@ int usb_serial_probe(struct usb_interface *interface, ...@@ -1113,7 +1161,6 @@ int usb_serial_probe(struct usb_interface *interface,
port->serial = serial; port->serial = serial;
port->magic = USB_SERIAL_PORT_MAGIC; port->magic = USB_SERIAL_PORT_MAGIC;
INIT_WORK(&port->work, usb_serial_port_softint, port); INIT_WORK(&port->work, usb_serial_port_softint, port);
init_MUTEX (&port->sem);
} }
/* if this device type has an attach function, call it */ /* if this device type has an attach function, call it */
...@@ -1189,67 +1236,14 @@ void usb_serial_disconnect(struct usb_interface *interface) ...@@ -1189,67 +1236,14 @@ void usb_serial_disconnect(struct usb_interface *interface)
{ {
struct usb_serial *serial = usb_get_intfdata (interface); struct usb_serial *serial = usb_get_intfdata (interface);
struct device *dev = &interface->dev; struct device *dev = &interface->dev;
struct usb_serial_port *port;
int i;
dbg ("%s", __FUNCTION__); dbg ("%s", __FUNCTION__);
usb_set_intfdata (interface, NULL); usb_set_intfdata (interface, NULL);
if (serial) { if (serial) {
/* fail all future close/read/write/ioctl/etc calls */ /* let the last holder of this object
for (i = 0; i < serial->num_ports; ++i) { * cause it to be cleaned up */
port = &serial->port[i]; kobject_put (&serial->kobj);
down (&port->sem);
if (port->tty != NULL) {
port->tty->driver_data = NULL;
while (port->open_count > 0) {
__serial_close(port, NULL);
}
}
up (&port->sem);
}
serial->dev = NULL;
serial_shutdown (serial);
for (i = 0; i < serial->num_ports; ++i)
device_unregister(&serial->port[i].dev);
for (i = 0; i < serial->num_ports; ++i)
serial->port[i].open_count = 0;
for (i = 0; i < serial->num_bulk_in; ++i) {
port = &serial->port[i];
if (port->read_urb) {
usb_unlink_urb (port->read_urb);
usb_free_urb (port->read_urb);
}
if (port->bulk_in_buffer)
kfree (port->bulk_in_buffer);
}
for (i = 0; i < serial->num_bulk_out; ++i) {
port = &serial->port[i];
if (port->write_urb) {
usb_unlink_urb (port->write_urb);
usb_free_urb (port->write_urb);
}
if (port->bulk_out_buffer)
kfree (port->bulk_out_buffer);
}
for (i = 0; i < serial->num_interrupt_in; ++i) {
port = &serial->port[i];
if (port->interrupt_in_urb) {
usb_unlink_urb (port->interrupt_in_urb);
usb_free_urb (port->interrupt_in_urb);
}
if (port->interrupt_in_buffer)
kfree (port->interrupt_in_buffer);
}
/* return the minor range that this device had */
return_serial (serial);
/* free up any memory that we allocated */
kfree (serial);
} }
dev_info(dev, "device disconnected\n"); dev_info(dev, "device disconnected\n");
} }
......
...@@ -89,7 +89,6 @@ ...@@ -89,7 +89,6 @@
* @write_wait: a wait_queue_head_t used by the port. * @write_wait: a wait_queue_head_t used by the port.
* @work: work queue entry for the line discipline waking up. * @work: work queue entry for the line discipline waking up.
* @open_count: number of times this port has been opened. * @open_count: number of times this port has been opened.
* @sem: struct semaphore used to lock this structure.
* *
* This structure is used by the usb-serial core and drivers for the specific * This structure is used by the usb-serial core and drivers for the specific
* ports of a device. * ports of a device.
...@@ -116,7 +115,6 @@ struct usb_serial_port { ...@@ -116,7 +115,6 @@ struct usb_serial_port {
wait_queue_head_t write_wait; wait_queue_head_t write_wait;
struct work_struct work; struct work_struct work;
int open_count; int open_count;
struct semaphore sem;
struct device dev; struct device dev;
}; };
#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev) #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
...@@ -164,8 +162,10 @@ struct usb_serial { ...@@ -164,8 +162,10 @@ struct usb_serial {
__u16 vendor; __u16 vendor;
__u16 product; __u16 product;
struct usb_serial_port port[MAX_NUM_PORTS]; struct usb_serial_port port[MAX_NUM_PORTS];
struct kobject kobj;
void * private; void * private;
}; };
#define to_usb_serial(d) container_of(d, struct usb_serial, kobj)
#define NUM_DONT_CARE (-1) #define NUM_DONT_CARE (-1)
......
...@@ -314,7 +314,7 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe, ...@@ -314,7 +314,7 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe,
return USB_STOR_XFER_ERROR; return USB_STOR_XFER_ERROR;
/* the transfer was cancelled, presumably by an abort */ /* the transfer was cancelled, presumably by an abort */
case -ENODEV: case -ECONNRESET:
US_DEBUGP("-- transfer cancelled\n"); US_DEBUGP("-- transfer cancelled\n");
return USB_STOR_XFER_ERROR; return USB_STOR_XFER_ERROR;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/device.h> /* for struct device */ #include <linux/device.h> /* for struct device */
#include <linux/fs.h> /* for struct file_operations */ #include <linux/fs.h> /* for struct file_operations */
#include <linux/completion.h> /* for struct completion */ #include <linux/completion.h> /* for struct completion */
#include <linux/sched.h> /* for current && schedule_timeout */
static __inline__ void wait_ms(unsigned int ms) static __inline__ void wait_ms(unsigned int ms)
...@@ -239,6 +240,7 @@ struct usb_device { ...@@ -239,6 +240,7 @@ struct usb_device {
int have_langid; /* whether string_langid is valid yet */ int have_langid; /* whether string_langid is valid yet */
int string_langid; /* language ID for strings */ int string_langid; /* language ID for strings */
int present; /* if device is present or not */
void *hcpriv; /* Host Controller private data */ void *hcpriv; /* Host Controller private data */
......
...@@ -25,7 +25,7 @@ obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ ...@@ -25,7 +25,7 @@ obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/
obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
include $(TOPDIR)/drivers/net/Makefile.lib include $(TOPDIR)/drivers/net/Makefile.lib
include $(TOPDIR)/drivers/usb/class/Makefile.lib include $(TOPDIR)/drivers/usb/Makefile.lib
include $(TOPDIR)/fs/Makefile.lib include $(TOPDIR)/fs/Makefile.lib
include $(TOPDIR)/net/bluetooth/bnep/Makefile.lib include $(TOPDIR)/net/bluetooth/bnep/Makefile.lib
......
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