Commit bb0851ff authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (25 commits)
  USB: s3c2410 gadget: ensure vbus pin in input mode during read
  USB: s3c2410 gadget: allow sharing of vbus irq
  USB: s3c2410 gadget: Header move fixups
  USB: usb-storage: unusual_devs entry for JetFlash TS1GJF2A
  USB: fix up EHCI startup synchronization
  USB: make the microtek driver and HAL cooperate
  USB: uevent environment key fix
  USB: keep track of whether interface sysfs files exist
  USB: sierra: new product id
  USB HCD: avoid duplicate local_irq_disable()
  USB: mailing lists have changed
  USB: remove USB HUB entry from MAINTAINERS
  USB: fix directory references in usb/README
  USB: add support for an older firmware revision for the Nikon D200
  USB: FIx locks and urb->status in adutux (updated)
  USB: power-management documenation update
  USB: Fix signr comment in usbdevice_fs.h
  usbserial: fix inconsistent lock state
  USB: fix usbled disconnect read race #2
  USB: free memory when writing fails in usb/serial/mos7840.c
  ...
parents 34f2c1c3 5f629ad7
...@@ -278,6 +278,14 @@ optional. The methods' jobs are quite simple: ...@@ -278,6 +278,14 @@ optional. The methods' jobs are quite simple:
(although the interfaces will be in the same altsettings as (although the interfaces will be in the same altsettings as
before the suspend). before the suspend).
If the device is disconnected or powered down while it is suspended,
the disconnect method will be called instead of the resume or
reset_resume method. This is also quite likely to happen when
waking up from hibernation, as many systems do not maintain suspend
current to the USB host controllers during hibernation. (It's
possible to work around the hibernation-forces-disconnect problem by
using the USB Persist facility.)
The reset_resume method is used by the USB Persist facility (see The reset_resume method is used by the USB Persist facility (see
Documentation/usb/persist.txt) and it can also be used under certain Documentation/usb/persist.txt) and it can also be used under certain
circumstances when CONFIG_USB_PERSIST is not enabled. Currently, if a circumstances when CONFIG_USB_PERSIST is not enabled. Currently, if a
......
...@@ -323,8 +323,7 @@ S: Maintained ...@@ -323,8 +323,7 @@ S: Maintained
ALCATEL SPEEDTOUCH USB DRIVER ALCATEL SPEEDTOUCH USB DRIVER
P: Duncan Sands P: Duncan Sands
M: duncan.sands@free.fr M: duncan.sands@free.fr
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
W: http://www.linux-usb.org/SpeedTouch/ W: http://www.linux-usb.org/SpeedTouch/
S: Maintained S: Maintained
...@@ -1043,7 +1042,7 @@ S: Maintained ...@@ -1043,7 +1042,7 @@ S: Maintained
CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER
P: Lennert Buytenhek P: Lennert Buytenhek
M: kernel@wantstofly.org M: kernel@wantstofly.org
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
S: Maintained S: Maintained
CIRRUS LOGIC CS4280/CS461x SOUNDDRIVER CIRRUS LOGIC CS4280/CS461x SOUNDDRIVER
...@@ -1552,7 +1551,7 @@ S: Maintained ...@@ -1552,7 +1551,7 @@ S: Maintained
FREESCALE HIGHSPEED USB DEVICE DRIVER FREESCALE HIGHSPEED USB DEVICE DRIVER
P: Li Yang P: Li Yang
M: leoli@freescale.com M: leoli@freescale.com
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linuxppc-dev@ozlabs.org L: linuxppc-dev@ozlabs.org
S: Maintained S: Maintained
...@@ -3810,22 +3809,20 @@ S: Maintained ...@@ -3810,22 +3809,20 @@ S: Maintained
USB ACM DRIVER USB ACM DRIVER
P: Oliver Neukum P: Oliver Neukum
M: oliver@neukum.name M: oliver@neukum.name
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
USB BLOCK DRIVER (UB ub) USB BLOCK DRIVER (UB ub)
P: Pete Zaitcev P: Pete Zaitcev
M: zaitcev@redhat.com M: zaitcev@redhat.com
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
S: Supported S: Supported
USB CDC ETHERNET DRIVER USB CDC ETHERNET DRIVER
P: Greg Kroah-Hartman P: Greg Kroah-Hartman
M: greg@kroah.com M: greg@kroah.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
W: http://www.kroah.com/linux-usb/ W: http://www.kroah.com/linux-usb/
...@@ -3839,13 +3836,13 @@ S: Maintained ...@@ -3839,13 +3836,13 @@ S: Maintained
USB EHCI DRIVER USB EHCI DRIVER
P: David Brownell P: David Brownell
M: dbrownell@users.sourceforge.net M: dbrownell@users.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
S: Odd Fixes S: Odd Fixes
USB ET61X[12]51 DRIVER USB ET61X[12]51 DRIVER
P: Luca Risolia P: Luca Risolia
M: luca.risolia@studio.unibo.it M: luca.risolia@studio.unibo.it
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: video4linux-list@redhat.com L: video4linux-list@redhat.com
W: http://www.linux-projects.org W: http://www.linux-projects.org
S: Maintained S: Maintained
...@@ -3853,41 +3850,33 @@ S: Maintained ...@@ -3853,41 +3850,33 @@ S: Maintained
USB GADGET/PERIPHERAL SUBSYSTEM USB GADGET/PERIPHERAL SUBSYSTEM
P: David Brownell P: David Brownell
M: dbrownell@users.sourceforge.net M: dbrownell@users.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
W: http://www.linux-usb.org/gadget W: http://www.linux-usb.org/gadget
S: Maintained S: Maintained
USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...) USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
P: Jiri Kosina P: Jiri Kosina
M: jkosina@suse.cz M: jkosina@suse.cz
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/jikos/hid.git T: git kernel.org:/pub/scm/linux/kernel/git/jikos/hid.git
S: Maintained S: Maintained
USB HUB DRIVER
P: Johannes Erdfelt
M: johannes@erdfelt.com
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB ISP116X DRIVER USB ISP116X DRIVER
P: Olav Kongas P: Olav Kongas
M: ok@artecdesign.ee M: ok@artecdesign.ee
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
S: Maintained S: Maintained
USB KAWASAKI LSI DRIVER USB KAWASAKI LSI DRIVER
P: Oliver Neukum P: Oliver Neukum
M: oliver@neukum.name M: oliver@neukum.name
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
USB MASS STORAGE DRIVER USB MASS STORAGE DRIVER
P: Matthew Dharm P: Matthew Dharm
M: mdharm-usb@one-eyed-alien.net M: mdharm-usb@one-eyed-alien.net
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: usb-storage@lists.one-eyed-alien.net L: usb-storage@lists.one-eyed-alien.net
S: Maintained S: Maintained
W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ W: http://www.one-eyed-alien.net/~mdharm/linux-usb/
...@@ -3895,28 +3884,26 @@ W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ ...@@ -3895,28 +3884,26 @@ W: http://www.one-eyed-alien.net/~mdharm/linux-usb/
USB OHCI DRIVER USB OHCI DRIVER
P: David Brownell P: David Brownell
M: dbrownell@users.sourceforge.net M: dbrownell@users.sourceforge.net
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Odd Fixes S: Odd Fixes
USB OPTION-CARD DRIVER USB OPTION-CARD DRIVER
P: Matthias Urlichs P: Matthias Urlichs
M: smurf@smurf.noris.de M: smurf@smurf.noris.de
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
S: Maintained S: Maintained
USB OV511 DRIVER USB OV511 DRIVER
P: Mark McClelland P: Mark McClelland
M: mmcclell@bigfoot.com M: mmcclell@bigfoot.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
W: http://alpha.dyndns.org/ov511/ W: http://alpha.dyndns.org/ov511/
S: Maintained S: Maintained
USB PEGASUS DRIVER USB PEGASUS DRIVER
P: Petko Manolov P: Petko Manolov
M: petkan@users.sourceforge.net M: petkan@users.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
W: http://pegasus2.sourceforge.net/ W: http://pegasus2.sourceforge.net/
S: Maintained S: Maintained
...@@ -3924,14 +3911,13 @@ S: Maintained ...@@ -3924,14 +3911,13 @@ S: Maintained
USB PRINTER DRIVER (usblp) USB PRINTER DRIVER (usblp)
P: Pete Zaitcev P: Pete Zaitcev
M: zaitcev@redhat.com M: zaitcev@redhat.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Supported S: Supported
USB RTL8150 DRIVER USB RTL8150 DRIVER
P: Petko Manolov P: Petko Manolov
M: petkan@users.sourceforge.net M: petkan@users.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
W: http://pegasus2.sourceforge.net/ W: http://pegasus2.sourceforge.net/
S: Maintained S: Maintained
...@@ -3939,8 +3925,7 @@ S: Maintained ...@@ -3939,8 +3925,7 @@ S: Maintained
USB SE401 DRIVER USB SE401 DRIVER
P: Jeroen Vreeken P: Jeroen Vreeken
M: pe1rxq@amsat.org M: pe1rxq@amsat.org
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
W: http://www.chello.nl/~j.vreeken/se401/ W: http://www.chello.nl/~j.vreeken/se401/
S: Maintained S: Maintained
...@@ -3954,72 +3939,59 @@ USB SERIAL DIGI ACCELEPORT DRIVER ...@@ -3954,72 +3939,59 @@ USB SERIAL DIGI ACCELEPORT DRIVER
P: Peter Berger and Al Borchers P: Peter Berger and Al Borchers
M: pberger@brimson.com M: pberger@brimson.com
M: alborchers@steinerpoint.com M: alborchers@steinerpoint.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
USB SERIAL DRIVER USB SERIAL DRIVER
P: Greg Kroah-Hartman P: Greg Kroah-Hartman
M: gregkh@suse.de M: gregkh@suse.de
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Supported S: Supported
USB SERIAL BELKIN F5U103 DRIVER USB SERIAL BELKIN F5U103 DRIVER
P: William Greathouse P: William Greathouse
M: wgreathouse@smva.com M: wgreathouse@smva.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
USB SERIAL CYPRESS M8 DRIVER USB SERIAL CYPRESS M8 DRIVER
P: Lonnie Mendez P: Lonnie Mendez
M: dignome@gmail.com M: dignome@gmail.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
W: http://geocities.com/i0xox0i W: http://geocities.com/i0xox0i
W: http://firstlight.net/cvs W: http://firstlight.net/cvs
USB SERIAL CYBERJACK PINPAD/E-COM DRIVER
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB AUERSWALD DRIVER USB AUERSWALD DRIVER
P: Wolfgang Muees P: Wolfgang Muees
M: wolfgang@iksw-muees.de M: wolfgang@iksw-muees.de
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
P: Gary Brubaker P: Gary Brubaker
M: xavyer@ix.netcom.com M: xavyer@ix.netcom.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
USB SERIAL KEYSPAN DRIVER USB SERIAL KEYSPAN DRIVER
P: Greg Kroah-Hartman P: Greg Kroah-Hartman
M: greg@kroah.com M: greg@kroah.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
W: http://www.kroah.com/linux/ W: http://www.kroah.com/linux/
S: Maintained S: Maintained
USB SERIAL WHITEHEAT DRIVER USB SERIAL WHITEHEAT DRIVER
P: Support Department P: Support Department
M: support@connecttech.com M: support@connecttech.com
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
W: http://www.connecttech.com W: http://www.connecttech.com
S: Supported S: Supported
USB SN9C1xx DRIVER USB SN9C1xx DRIVER
P: Luca Risolia P: Luca Risolia
M: luca.risolia@studio.unibo.it M: luca.risolia@studio.unibo.it
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: video4linux-list@redhat.com L: video4linux-list@redhat.com
W: http://www.linux-projects.org W: http://www.linux-projects.org
S: Maintained S: Maintained
...@@ -4027,8 +3999,7 @@ S: Maintained ...@@ -4027,8 +3999,7 @@ S: Maintained
USB SUBSYSTEM USB SUBSYSTEM
P: Greg Kroah-Hartman P: Greg Kroah-Hartman
M: gregkh@suse.de M: gregkh@suse.de
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
W: http://www.linux-usb.org W: http://www.linux-usb.org
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Supported S: Supported
...@@ -4036,8 +4007,7 @@ S: Supported ...@@ -4036,8 +4007,7 @@ S: Supported
USB UHCI DRIVER USB UHCI DRIVER
P: Alan Stern P: Alan Stern
M: stern@rowland.harvard.edu M: stern@rowland.harvard.edu
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
USB "USBNET" DRIVER FRAMEWORK USB "USBNET" DRIVER FRAMEWORK
...@@ -4050,7 +4020,7 @@ S: Maintained ...@@ -4050,7 +4020,7 @@ S: Maintained
USB W996[87]CF DRIVER USB W996[87]CF DRIVER
P: Luca Risolia P: Luca Risolia
M: luca.risolia@studio.unibo.it M: luca.risolia@studio.unibo.it
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: video4linux-list@redhat.com L: video4linux-list@redhat.com
W: http://www.linux-projects.org W: http://www.linux-projects.org
S: Maintained S: Maintained
...@@ -4058,7 +4028,7 @@ S: Maintained ...@@ -4058,7 +4028,7 @@ S: Maintained
USB ZC0301 DRIVER USB ZC0301 DRIVER
P: Luca Risolia P: Luca Risolia
M: luca.risolia@studio.unibo.it M: luca.risolia@studio.unibo.it
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: video4linux-list@redhat.com L: video4linux-list@redhat.com
W: http://www.linux-projects.org W: http://www.linux-projects.org
S: Maintained S: Maintained
...@@ -4066,15 +4036,14 @@ S: Maintained ...@@ -4066,15 +4036,14 @@ S: Maintained
USB ZD1201 DRIVER USB ZD1201 DRIVER
P: Jeroen Vreeken P: Jeroen Vreeken
M: pe1rxq@amsat.org M: pe1rxq@amsat.org
L: linux-usb-users@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
W: http://linux-lc100020.sourceforge.net W: http://linux-lc100020.sourceforge.net
S: Maintained S: Maintained
USB ZR364XX DRIVER USB ZR364XX DRIVER
P: Antoine Jacquet P: Antoine Jacquet
M: royale@zerezo.com M: royale@zerezo.com
L: linux-usb-devel@lists.sourceforge.net L: linux-usb@vger.kernel.org
L: video4linux-list@redhat.com L: video4linux-list@redhat.com
W: http://royale.zerezo.com/zr364xx/ W: http://royale.zerezo.com/zr364xx/
S: Maintained S: Maintained
......
...@@ -39,12 +39,12 @@ first subdirectory in the list below that it fits into. ...@@ -39,12 +39,12 @@ first subdirectory in the list below that it fits into.
image/ - This is for still image drivers, like scanners or image/ - This is for still image drivers, like scanners or
digital cameras. digital cameras.
input/ - This is for any driver that uses the input subsystem, ../input/ - This is for any driver that uses the input subsystem,
like keyboard, mice, touchscreens, tablets, etc. like keyboard, mice, touchscreens, tablets, etc.
media/ - This is for multimedia drivers, like video cameras, ../media/ - This is for multimedia drivers, like video cameras,
radios, and any other drivers that talk to the v4l radios, and any other drivers that talk to the v4l
subsystem. subsystem.
net/ - This is for network drivers. ../net/ - This is for network drivers.
serial/ - This is for USB to serial drivers. serial/ - This is for USB to serial drivers.
storage/ - This is for USB mass-storage drivers. storage/ - This is for USB mass-storage drivers.
class/ - This is for all USB device drivers that do not fit class/ - This is for all USB device drivers that do not fit
......
...@@ -585,9 +585,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -585,9 +585,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
{ {
struct usb_device *usb_dev; struct usb_device *usb_dev;
if (!dev)
return -ENODEV;
/* driver is often null here; dev_dbg() would oops */ /* driver is often null here; dev_dbg() would oops */
pr_debug ("usb %s: uevent\n", dev->bus_id); pr_debug ("usb %s: uevent\n", dev->bus_id);
...@@ -631,14 +628,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -631,14 +628,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
usb_dev->descriptor.bDeviceProtocol)) usb_dev->descriptor.bDeviceProtocol))
return -ENOMEM; return -ENOMEM;
if (add_uevent_var(env, "BUSNUM=%03d",
usb_dev->bus->busnum))
return -ENOMEM;
if (add_uevent_var(env, "DEVNUM=%03d",
usb_dev->devnum))
return -ENOMEM;
return 0; return 0;
} }
......
...@@ -1311,8 +1311,8 @@ void usb_hcd_flush_endpoint(struct usb_device *udev, ...@@ -1311,8 +1311,8 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
hcd = bus_to_hcd(udev->bus); hcd = bus_to_hcd(udev->bus);
/* No more submits can occur */ /* No more submits can occur */
rescan:
spin_lock_irq(&hcd_urb_list_lock); spin_lock_irq(&hcd_urb_list_lock);
rescan:
list_for_each_entry (urb, &ep->urb_list, urb_list) { list_for_each_entry (urb, &ep->urb_list, urb_list) {
int is_in; int is_in;
...@@ -1345,6 +1345,7 @@ void usb_hcd_flush_endpoint(struct usb_device *udev, ...@@ -1345,6 +1345,7 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
usb_put_urb (urb); usb_put_urb (urb);
/* list contents may have changed */ /* list contents may have changed */
spin_lock(&hcd_urb_list_lock);
goto rescan; goto rescan;
} }
spin_unlock_irq(&hcd_urb_list_lock); spin_unlock_irq(&hcd_urb_list_lock);
......
...@@ -335,7 +335,7 @@ static void kick_khubd(struct usb_hub *hub) ...@@ -335,7 +335,7 @@ static void kick_khubd(struct usb_hub *hub)
to_usb_interface(hub->intfdev)->pm_usage_cnt = 1; to_usb_interface(hub->intfdev)->pm_usage_cnt = 1;
spin_lock_irqsave(&hub_event_lock, flags); spin_lock_irqsave(&hub_event_lock, flags);
if (!hub->disconnected & list_empty(&hub->event_list)) { if (!hub->disconnected && list_empty(&hub->event_list)) {
list_add_tail(&hub->event_list, &hub_event_list); list_add_tail(&hub->event_list, &hub_event_list);
wake_up(&khubd_wait); wake_up(&khubd_wait);
} }
......
...@@ -1172,7 +1172,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) ...@@ -1172,7 +1172,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
struct usb_host_interface *alt; struct usb_host_interface *alt;
int ret; int ret;
int manual = 0; int manual = 0;
int changed;
if (dev->state == USB_STATE_SUSPENDED) if (dev->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH; return -EHOSTUNREACH;
...@@ -1212,8 +1211,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) ...@@ -1212,8 +1211,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
*/ */
/* prevent submissions using previous endpoint settings */ /* prevent submissions using previous endpoint settings */
changed = (iface->cur_altsetting != alt); if (iface->cur_altsetting != alt && device_is_registered(&iface->dev))
if (changed && device_is_registered(&iface->dev))
usb_remove_sysfs_intf_files(iface); usb_remove_sysfs_intf_files(iface);
usb_disable_interface(dev, iface); usb_disable_interface(dev, iface);
...@@ -1250,7 +1248,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) ...@@ -1250,7 +1248,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
* (Likewise, EP0 never "halts" on well designed devices.) * (Likewise, EP0 never "halts" on well designed devices.)
*/ */
usb_enable_interface(dev, iface); usb_enable_interface(dev, iface);
if (changed && device_is_registered(&iface->dev)) if (device_is_registered(&iface->dev))
usb_create_sysfs_intf_files(iface); usb_create_sysfs_intf_files(iface);
return 0; return 0;
...@@ -1348,34 +1346,10 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -1348,34 +1346,10 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
struct usb_interface *intf; struct usb_interface *intf;
struct usb_host_interface *alt; struct usb_host_interface *alt;
if (!dev)
return -ENODEV;
/* driver is often null here; dev_dbg() would oops */
pr_debug ("usb %s: uevent\n", dev->bus_id);
intf = to_usb_interface(dev); intf = to_usb_interface(dev);
usb_dev = interface_to_usbdev(intf); usb_dev = interface_to_usbdev(intf);
alt = intf->cur_altsetting; alt = intf->cur_altsetting;
#ifdef CONFIG_USB_DEVICEFS
if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
usb_dev->bus->busnum, usb_dev->devnum))
return -ENOMEM;
#endif
if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
le16_to_cpu(usb_dev->descriptor.idVendor),
le16_to_cpu(usb_dev->descriptor.idProduct),
le16_to_cpu(usb_dev->descriptor.bcdDevice)))
return -ENOMEM;
if (add_uevent_var(env, "TYPE=%d/%d/%d",
usb_dev->descriptor.bDeviceClass,
usb_dev->descriptor.bDeviceSubClass,
usb_dev->descriptor.bDeviceProtocol))
return -ENOMEM;
if (add_uevent_var(env, "INTERFACE=%d/%d/%d", if (add_uevent_var(env, "INTERFACE=%d/%d/%d",
alt->desc.bInterfaceClass, alt->desc.bInterfaceClass,
alt->desc.bInterfaceSubClass, alt->desc.bInterfaceSubClass,
...@@ -1641,12 +1615,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration) ...@@ -1641,12 +1615,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
intf->dev.bus_id, ret); intf->dev.bus_id, ret);
continue; continue;
} }
/* The driver's probe method can call usb_set_interface(),
* which would mean the interface's sysfs files are already
* created. Just in case, we'll remove them first.
*/
usb_remove_sysfs_intf_files(intf);
usb_create_sysfs_intf_files(intf); usb_create_sysfs_intf_files(intf);
} }
......
...@@ -735,6 +735,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf) ...@@ -735,6 +735,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
struct usb_host_interface *alt = intf->cur_altsetting; struct usb_host_interface *alt = intf->cur_altsetting;
int retval; int retval;
if (intf->sysfs_files_created)
return 0;
retval = sysfs_create_group(&dev->kobj, &intf_attr_grp); retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
if (retval) if (retval)
return retval; return retval;
...@@ -746,6 +748,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf) ...@@ -746,6 +748,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
if (intf->intf_assoc) if (intf->intf_assoc)
retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp); retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp);
usb_create_intf_ep_files(intf, udev); usb_create_intf_ep_files(intf, udev);
intf->sysfs_files_created = 1;
return 0; return 0;
} }
...@@ -753,8 +756,11 @@ void usb_remove_sysfs_intf_files(struct usb_interface *intf) ...@@ -753,8 +756,11 @@ void usb_remove_sysfs_intf_files(struct usb_interface *intf)
{ {
struct device *dev = &intf->dev; struct device *dev = &intf->dev;
if (!intf->sysfs_files_created)
return;
usb_remove_intf_ep_files(intf); usb_remove_intf_ep_files(intf);
device_remove_file(dev, &dev_attr_interface); device_remove_file(dev, &dev_attr_interface);
sysfs_remove_group(&dev->kobj, &intf_attr_grp); sysfs_remove_group(&dev->kobj, &intf_attr_grp);
sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp); sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp);
intf->sysfs_files_created = 0;
} }
...@@ -192,9 +192,34 @@ static void usb_release_dev(struct device *dev) ...@@ -192,9 +192,34 @@ static void usb_release_dev(struct device *dev)
kfree(udev); kfree(udev);
} }
#ifdef CONFIG_HOTPLUG
static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct usb_device *usb_dev;
usb_dev = to_usb_device(dev);
if (add_uevent_var(env, "BUSNUM=%03d", usb_dev->bus->busnum))
return -ENOMEM;
if (add_uevent_var(env, "DEVNUM=%03d", usb_dev->devnum))
return -ENOMEM;
return 0;
}
#else
static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
return -ENODEV;
}
#endif /* CONFIG_HOTPLUG */
struct device_type usb_device_type = { struct device_type usb_device_type = {
.name = "usb_device", .name = "usb_device",
.release = usb_release_dev, .release = usb_release_dev,
.uevent = usb_dev_uevent,
}; };
#ifdef CONFIG_PM #ifdef CONFIG_PM
......
...@@ -1241,14 +1241,14 @@ static void pullup_enable(struct omap_udc *udc) ...@@ -1241,14 +1241,14 @@ static void pullup_enable(struct omap_udc *udc)
udc->gadget.dev.parent->power.power_state = PMSG_ON; udc->gadget.dev.parent->power.power_state = PMSG_ON;
udc->gadget.dev.power.power_state = PMSG_ON; udc->gadget.dev.power.power_state = PMSG_ON;
UDC_SYSCON1_REG |= UDC_PULLUP_EN; UDC_SYSCON1_REG |= UDC_PULLUP_EN;
if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx()) if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx())
OTG_CTRL_REG |= OTG_BSESSVLD; OTG_CTRL_REG |= OTG_BSESSVLD;
UDC_IRQ_EN_REG = UDC_DS_CHG_IE; UDC_IRQ_EN_REG = UDC_DS_CHG_IE;
} }
static void pullup_disable(struct omap_udc *udc) static void pullup_disable(struct omap_udc *udc)
{ {
if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx()) if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx())
OTG_CTRL_REG &= ~OTG_BSESSVLD; OTG_CTRL_REG &= ~OTG_BSESSVLD;
UDC_IRQ_EN_REG = UDC_DS_CHG_IE; UDC_IRQ_EN_REG = UDC_DS_CHG_IE;
UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; UDC_SYSCON1_REG &= ~UDC_PULLUP_EN;
...@@ -1386,7 +1386,7 @@ static void update_otg(struct omap_udc *udc) ...@@ -1386,7 +1386,7 @@ static void update_otg(struct omap_udc *udc)
{ {
u16 devstat; u16 devstat;
if (!gadget_is_otg(udc->gadget)) if (!gadget_is_otg(&udc->gadget))
return; return;
if (OTG_CTRL_REG & OTG_ID) if (OTG_CTRL_REG & OTG_ID)
......
...@@ -52,10 +52,10 @@ ...@@ -52,10 +52,10 @@
#include <asm/arch/irqs.h> #include <asm/arch/irqs.h>
#include <asm/arch/hardware.h> #include <asm/arch/hardware.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-gpio.h> #include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-udc.h>
#include <asm/arch/udc.h> #include <asm/plat-s3c24xx/regs-udc.h>
#include <asm/plat-s3c24xx/udc.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -1511,7 +1511,11 @@ static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev) ...@@ -1511,7 +1511,11 @@ static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev)
unsigned int value; unsigned int value;
dprintk(DEBUG_NORMAL, "%s()\n", __func__); dprintk(DEBUG_NORMAL, "%s()\n", __func__);
/* some cpus cannot read from an line configured to IRQ! */
s3c2410_gpio_cfgpin(udc_info->vbus_pin, S3C2410_GPIO_INPUT);
value = s3c2410_gpio_getpin(udc_info->vbus_pin); value = s3c2410_gpio_getpin(udc_info->vbus_pin);
s3c2410_gpio_cfgpin(udc_info->vbus_pin, S3C2410_GPIO_SFN2);
if (udc_info->vbus_pin_inverted) if (udc_info->vbus_pin_inverted)
value = !value; value = !value;
...@@ -1872,9 +1876,9 @@ static int s3c2410_udc_probe(struct platform_device *pdev) ...@@ -1872,9 +1876,9 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
if (udc_info && udc_info->vbus_pin > 0) { if (udc_info && udc_info->vbus_pin > 0) {
irq = s3c2410_gpio_getirq(udc_info->vbus_pin); irq = s3c2410_gpio_getirq(udc_info->vbus_pin);
retval = request_irq(irq, s3c2410_udc_vbus_irq, retval = request_irq(irq, s3c2410_udc_vbus_irq,
IRQF_DISABLED | IRQF_TRIGGER_RISING IRQF_DISABLED | IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING, | IRQF_TRIGGER_FALLING | IRQF_SHARED,
gadget_name, udc); gadget_name, udc);
if (retval != 0) { if (retval != 0) {
dev_err(dev, "can't get vbus irq %i, err %d\n", dev_err(dev, "can't get vbus irq %i, err %d\n",
......
...@@ -156,7 +156,7 @@ config USB_OHCI_HCD_PCI ...@@ -156,7 +156,7 @@ config USB_OHCI_HCD_PCI
config USB_OHCI_HCD_SSB config USB_OHCI_HCD_SSB
bool "OHCI support for Broadcom SSB OHCI core" bool "OHCI support for Broadcom SSB OHCI core"
depends on USB_OHCI_HCD && (SSB = y || SSB = CONFIG_USB_OHCI_HCD) && EXPERIMENTAL depends on USB_OHCI_HCD && (SSB = y || SSB = USB_OHCI_HCD) && EXPERIMENTAL
default n default n
---help--- ---help---
Support for the Sonics Silicon Backplane (SSB) attached Support for the Sonics Silicon Backplane (SSB) attached
......
...@@ -575,12 +575,15 @@ static int ehci_run (struct usb_hcd *hcd) ...@@ -575,12 +575,15 @@ static int ehci_run (struct usb_hcd *hcd)
* from the companions to the EHCI controller. If any of the * from the companions to the EHCI controller. If any of the
* companions are in the middle of a port reset at the time, it * companions are in the middle of a port reset at the time, it
* could cause trouble. Write-locking ehci_cf_port_reset_rwsem * could cause trouble. Write-locking ehci_cf_port_reset_rwsem
* guarantees that no resets are in progress. * guarantees that no resets are in progress. After we set CF,
* a short delay lets the hardware catch up; new resets shouldn't
* be started before the port switching actions could complete.
*/ */
down_write(&ehci_cf_port_reset_rwsem); down_write(&ehci_cf_port_reset_rwsem);
hcd->state = HC_STATE_RUNNING; hcd->state = HC_STATE_RUNNING;
ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
msleep(5);
up_write(&ehci_cf_port_reset_rwsem); up_write(&ehci_cf_port_reset_rwsem);
temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
......
...@@ -819,7 +819,7 @@ static int mts_usb_probe(struct usb_interface *intf, ...@@ -819,7 +819,7 @@ static int mts_usb_probe(struct usb_interface *intf,
goto out_kfree2; goto out_kfree2;
new_desc->host->hostdata[0] = (unsigned long)new_desc; new_desc->host->hostdata[0] = (unsigned long)new_desc;
if (scsi_add_host(new_desc->host, NULL)) { if (scsi_add_host(new_desc->host, &dev->dev)) {
err_retval = -EIO; err_retval = -EIO;
goto out_host_put; goto out_host_put;
} }
......
...@@ -79,12 +79,22 @@ MODULE_DEVICE_TABLE(usb, device_table); ...@@ -79,12 +79,22 @@ MODULE_DEVICE_TABLE(usb, device_table);
#define COMMAND_TIMEOUT (2*HZ) /* 60 second timeout for a command */ #define COMMAND_TIMEOUT (2*HZ) /* 60 second timeout for a command */
/*
* The locking scheme is a vanilla 3-lock:
* adu_device.buflock: A spinlock, covers what IRQs touch.
* adutux_mutex: A Static lock to cover open_count. It would also cover
* any globals, but we don't have them in 2.6.
* adu_device.mtx: A mutex to hold across sleepers like copy_from_user.
* It covers all of adu_device, except the open_count
* and what .buflock covers.
*/
/* Structure to hold all of our device specific stuff */ /* Structure to hold all of our device specific stuff */
struct adu_device { struct adu_device {
struct mutex mtx; /* locks this structure */ struct mutex mtx;
struct usb_device* udev; /* save off the usb device pointer */ struct usb_device* udev; /* save off the usb device pointer */
struct usb_interface* interface; struct usb_interface* interface;
unsigned char minor; /* the starting minor number for this device */ unsigned int minor; /* the starting minor number for this device */
char serial_number[8]; char serial_number[8];
int open_count; /* number of times this port has been opened */ int open_count; /* number of times this port has been opened */
...@@ -107,8 +117,11 @@ struct adu_device { ...@@ -107,8 +117,11 @@ struct adu_device {
char* interrupt_out_buffer; char* interrupt_out_buffer;
struct usb_endpoint_descriptor* interrupt_out_endpoint; struct usb_endpoint_descriptor* interrupt_out_endpoint;
struct urb* interrupt_out_urb; struct urb* interrupt_out_urb;
int out_urb_finished;
}; };
static DEFINE_MUTEX(adutux_mutex);
static struct usb_driver adu_driver; static struct usb_driver adu_driver;
static void adu_debug_data(int level, const char *function, int size, static void adu_debug_data(int level, const char *function, int size,
...@@ -132,27 +145,31 @@ static void adu_debug_data(int level, const char *function, int size, ...@@ -132,27 +145,31 @@ static void adu_debug_data(int level, const char *function, int size,
*/ */
static void adu_abort_transfers(struct adu_device *dev) static void adu_abort_transfers(struct adu_device *dev)
{ {
dbg(2," %s : enter", __FUNCTION__); unsigned long flags;
if (dev == NULL) { dbg(2," %s : enter", __FUNCTION__);
dbg(1," %s : dev is null", __FUNCTION__);
goto exit;
}
if (dev->udev == NULL) { if (dev->udev == NULL) {
dbg(1," %s : udev is null", __FUNCTION__); dbg(1," %s : udev is null", __FUNCTION__);
goto exit; goto exit;
} }
dbg(2," %s : udev state %d", __FUNCTION__, dev->udev->state);
if (dev->udev->state == USB_STATE_NOTATTACHED) {
dbg(1," %s : udev is not attached", __FUNCTION__);
goto exit;
}
/* shutdown transfer */ /* shutdown transfer */
usb_unlink_urb(dev->interrupt_in_urb);
usb_unlink_urb(dev->interrupt_out_urb); /* XXX Anchor these instead */
spin_lock_irqsave(&dev->buflock, flags);
if (!dev->read_urb_finished) {
spin_unlock_irqrestore(&dev->buflock, flags);
usb_kill_urb(dev->interrupt_in_urb);
} else
spin_unlock_irqrestore(&dev->buflock, flags);
spin_lock_irqsave(&dev->buflock, flags);
if (!dev->out_urb_finished) {
spin_unlock_irqrestore(&dev->buflock, flags);
usb_kill_urb(dev->interrupt_out_urb);
} else
spin_unlock_irqrestore(&dev->buflock, flags);
exit: exit:
dbg(2," %s : leave", __FUNCTION__); dbg(2," %s : leave", __FUNCTION__);
...@@ -162,8 +179,6 @@ static void adu_delete(struct adu_device *dev) ...@@ -162,8 +179,6 @@ static void adu_delete(struct adu_device *dev)
{ {
dbg(2, "%s enter", __FUNCTION__); dbg(2, "%s enter", __FUNCTION__);
adu_abort_transfers(dev);
/* free data structures */ /* free data structures */
usb_free_urb(dev->interrupt_in_urb); usb_free_urb(dev->interrupt_in_urb);
usb_free_urb(dev->interrupt_out_urb); usb_free_urb(dev->interrupt_out_urb);
...@@ -239,7 +254,10 @@ static void adu_interrupt_out_callback(struct urb *urb) ...@@ -239,7 +254,10 @@ static void adu_interrupt_out_callback(struct urb *urb)
goto exit; goto exit;
} }
wake_up_interruptible(&dev->write_wait); spin_lock(&dev->buflock);
dev->out_urb_finished = 1;
wake_up(&dev->write_wait);
spin_unlock(&dev->buflock);
exit: exit:
adu_debug_data(5, __FUNCTION__, urb->actual_length, adu_debug_data(5, __FUNCTION__, urb->actual_length,
...@@ -252,12 +270,17 @@ static int adu_open(struct inode *inode, struct file *file) ...@@ -252,12 +270,17 @@ static int adu_open(struct inode *inode, struct file *file)
struct adu_device *dev = NULL; struct adu_device *dev = NULL;
struct usb_interface *interface; struct usb_interface *interface;
int subminor; int subminor;
int retval = 0; int retval;
dbg(2,"%s : enter", __FUNCTION__); dbg(2,"%s : enter", __FUNCTION__);
subminor = iminor(inode); subminor = iminor(inode);
if ((retval = mutex_lock_interruptible(&adutux_mutex))) {
dbg(2, "%s : mutex lock failed", __FUNCTION__);
goto exit_no_lock;
}
interface = usb_find_interface(&adu_driver, subminor); interface = usb_find_interface(&adu_driver, subminor);
if (!interface) { if (!interface) {
err("%s - error, can't find device for minor %d", err("%s - error, can't find device for minor %d",
...@@ -267,54 +290,54 @@ static int adu_open(struct inode *inode, struct file *file) ...@@ -267,54 +290,54 @@ static int adu_open(struct inode *inode, struct file *file)
} }
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
if (!dev) { if (!dev || !dev->udev) {
retval = -ENODEV; retval = -ENODEV;
goto exit_no_device; goto exit_no_device;
} }
/* lock this device */ /* check that nobody else is using the device */
if ((retval = mutex_lock_interruptible(&dev->mtx))) { if (dev->open_count) {
dbg(2, "%s : mutex lock failed", __FUNCTION__); retval = -EBUSY;
goto exit_no_device; goto exit_no_device;
} }
/* increment our usage count for the device */
++dev->open_count; ++dev->open_count;
dbg(2,"%s : open count %d", __FUNCTION__, dev->open_count); dbg(2,"%s : open count %d", __FUNCTION__, dev->open_count);
/* save device in the file's private structure */ /* save device in the file's private structure */
file->private_data = dev; file->private_data = dev;
if (dev->open_count == 1) { /* initialize in direction */
/* initialize in direction */ dev->read_buffer_length = 0;
dev->read_buffer_length = 0;
/* fixup first read by having urb waiting for it */ /* fixup first read by having urb waiting for it */
usb_fill_int_urb(dev->interrupt_in_urb,dev->udev, usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
usb_rcvintpipe(dev->udev, usb_rcvintpipe(dev->udev,
dev->interrupt_in_endpoint->bEndpointAddress), dev->interrupt_in_endpoint->bEndpointAddress),
dev->interrupt_in_buffer, dev->interrupt_in_buffer,
le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize), le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
adu_interrupt_in_callback, dev, adu_interrupt_in_callback, dev,
dev->interrupt_in_endpoint->bInterval); dev->interrupt_in_endpoint->bInterval);
/* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */ dev->read_urb_finished = 0;
dev->read_urb_finished = 0; if (usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL))
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); dev->read_urb_finished = 1;
if (retval) /* we ignore failure */
--dev->open_count; /* end of fixup for first read */
}
mutex_unlock(&dev->mtx); /* initialize out direction */
dev->out_urb_finished = 1;
retval = 0;
exit_no_device: exit_no_device:
mutex_unlock(&adutux_mutex);
exit_no_lock:
dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval); dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval);
return retval; return retval;
} }
static int adu_release_internal(struct adu_device *dev) static void adu_release_internal(struct adu_device *dev)
{ {
int retval = 0;
dbg(2," %s : enter", __FUNCTION__); dbg(2," %s : enter", __FUNCTION__);
/* decrement our usage count for the device */ /* decrement our usage count for the device */
...@@ -326,12 +349,11 @@ static int adu_release_internal(struct adu_device *dev) ...@@ -326,12 +349,11 @@ static int adu_release_internal(struct adu_device *dev)
} }
dbg(2," %s : leave", __FUNCTION__); dbg(2," %s : leave", __FUNCTION__);
return retval;
} }
static int adu_release(struct inode *inode, struct file *file) static int adu_release(struct inode *inode, struct file *file)
{ {
struct adu_device *dev = NULL; struct adu_device *dev;
int retval = 0; int retval = 0;
dbg(2," %s : enter", __FUNCTION__); dbg(2," %s : enter", __FUNCTION__);
...@@ -343,15 +365,13 @@ static int adu_release(struct inode *inode, struct file *file) ...@@ -343,15 +365,13 @@ static int adu_release(struct inode *inode, struct file *file)
} }
dev = file->private_data; dev = file->private_data;
if (dev == NULL) { if (dev == NULL) {
dbg(1," %s : object is NULL", __FUNCTION__); dbg(1," %s : object is NULL", __FUNCTION__);
retval = -ENODEV; retval = -ENODEV;
goto exit; goto exit;
} }
/* lock our device */ mutex_lock(&adutux_mutex); /* not interruptible */
mutex_lock(&dev->mtx); /* not interruptible */
if (dev->open_count <= 0) { if (dev->open_count <= 0) {
dbg(1," %s : device not opened", __FUNCTION__); dbg(1," %s : device not opened", __FUNCTION__);
...@@ -359,19 +379,15 @@ static int adu_release(struct inode *inode, struct file *file) ...@@ -359,19 +379,15 @@ static int adu_release(struct inode *inode, struct file *file)
goto exit; goto exit;
} }
adu_release_internal(dev);
if (dev->udev == NULL) { if (dev->udev == NULL) {
/* the device was unplugged before the file was released */ /* the device was unplugged before the file was released */
mutex_unlock(&dev->mtx); if (!dev->open_count) /* ... and we're the last user */
adu_delete(dev); adu_delete(dev);
dev = NULL;
} else {
/* do the work */
retval = adu_release_internal(dev);
} }
exit: exit:
if (dev) mutex_unlock(&adutux_mutex);
mutex_unlock(&dev->mtx);
dbg(2," %s : leave, return value %d", __FUNCTION__, retval); dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
return retval; return retval;
} }
...@@ -393,12 +409,12 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, ...@@ -393,12 +409,12 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
dev = file->private_data; dev = file->private_data;
dbg(2," %s : dev=%p", __FUNCTION__, dev); dbg(2," %s : dev=%p", __FUNCTION__, dev);
/* lock this object */
if (mutex_lock_interruptible(&dev->mtx)) if (mutex_lock_interruptible(&dev->mtx))
return -ERESTARTSYS; return -ERESTARTSYS;
/* verify that the device wasn't unplugged */ /* verify that the device wasn't unplugged */
if (dev->udev == NULL || dev->minor == 0) { if (dev->udev == NULL) {
retval = -ENODEV; retval = -ENODEV;
err("No device or device unplugged %d", retval); err("No device or device unplugged %d", retval);
goto exit; goto exit;
...@@ -452,7 +468,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, ...@@ -452,7 +468,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
should_submit = 1; should_submit = 1;
} else { } else {
/* even the primary was empty - we may need to do IO */ /* even the primary was empty - we may need to do IO */
if (dev->interrupt_in_urb->status == -EINPROGRESS) { if (!dev->read_urb_finished) {
/* somebody is doing IO */ /* somebody is doing IO */
spin_unlock_irqrestore(&dev->buflock, flags); spin_unlock_irqrestore(&dev->buflock, flags);
dbg(2," %s : submitted already", __FUNCTION__); dbg(2," %s : submitted already", __FUNCTION__);
...@@ -460,6 +476,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, ...@@ -460,6 +476,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
/* we must initiate input */ /* we must initiate input */
dbg(2," %s : initiate input", __FUNCTION__); dbg(2," %s : initiate input", __FUNCTION__);
dev->read_urb_finished = 0; dev->read_urb_finished = 0;
spin_unlock_irqrestore(&dev->buflock, flags);
usb_fill_int_urb(dev->interrupt_in_urb,dev->udev, usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
usb_rcvintpipe(dev->udev, usb_rcvintpipe(dev->udev,
...@@ -469,15 +486,12 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, ...@@ -469,15 +486,12 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
adu_interrupt_in_callback, adu_interrupt_in_callback,
dev, dev,
dev->interrupt_in_endpoint->bInterval); dev->interrupt_in_endpoint->bInterval);
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
if (!retval) { if (retval) {
spin_unlock_irqrestore(&dev->buflock, flags); dev->read_urb_finished = 1;
dbg(2," %s : submitted OK", __FUNCTION__);
} else {
if (retval == -ENOMEM) { if (retval == -ENOMEM) {
retval = bytes_read ? bytes_read : -ENOMEM; retval = bytes_read ? bytes_read : -ENOMEM;
} }
spin_unlock_irqrestore(&dev->buflock, flags);
dbg(2," %s : submit failed", __FUNCTION__); dbg(2," %s : submit failed", __FUNCTION__);
goto exit; goto exit;
} }
...@@ -486,10 +500,14 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, ...@@ -486,10 +500,14 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
/* we wait for I/O to complete */ /* we wait for I/O to complete */
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&dev->read_wait, &wait); add_wait_queue(&dev->read_wait, &wait);
if (!dev->read_urb_finished) spin_lock_irqsave(&dev->buflock, flags);
if (!dev->read_urb_finished) {
spin_unlock_irqrestore(&dev->buflock, flags);
timeout = schedule_timeout(COMMAND_TIMEOUT); timeout = schedule_timeout(COMMAND_TIMEOUT);
else } else {
spin_unlock_irqrestore(&dev->buflock, flags);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
}
remove_wait_queue(&dev->read_wait, &wait); remove_wait_queue(&dev->read_wait, &wait);
if (timeout <= 0) { if (timeout <= 0) {
...@@ -509,19 +527,23 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, ...@@ -509,19 +527,23 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
retval = bytes_read; retval = bytes_read;
/* if the primary buffer is empty then use it */ /* if the primary buffer is empty then use it */
if (should_submit && !dev->interrupt_in_urb->status==-EINPROGRESS) { spin_lock_irqsave(&dev->buflock, flags);
if (should_submit && dev->read_urb_finished) {
dev->read_urb_finished = 0;
spin_unlock_irqrestore(&dev->buflock, flags);
usb_fill_int_urb(dev->interrupt_in_urb,dev->udev, usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
usb_rcvintpipe(dev->udev, usb_rcvintpipe(dev->udev,
dev->interrupt_in_endpoint->bEndpointAddress), dev->interrupt_in_endpoint->bEndpointAddress),
dev->interrupt_in_buffer, dev->interrupt_in_buffer,
le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize), le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
adu_interrupt_in_callback, adu_interrupt_in_callback,
dev, dev,
dev->interrupt_in_endpoint->bInterval); dev->interrupt_in_endpoint->bInterval);
/* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */ if (usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL) != 0)
dev->read_urb_finished = 0; dev->read_urb_finished = 1;
usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
/* we ignore failure */ /* we ignore failure */
} else {
spin_unlock_irqrestore(&dev->buflock, flags);
} }
exit: exit:
...@@ -535,24 +557,24 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, ...@@ -535,24 +557,24 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
static ssize_t adu_write(struct file *file, const __user char *buffer, static ssize_t adu_write(struct file *file, const __user char *buffer,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
DECLARE_WAITQUEUE(waita, current);
struct adu_device *dev; struct adu_device *dev;
size_t bytes_written = 0; size_t bytes_written = 0;
size_t bytes_to_write; size_t bytes_to_write;
size_t buffer_size; size_t buffer_size;
unsigned long flags;
int retval; int retval;
int timeout = 0;
dbg(2," %s : enter, count = %Zd", __FUNCTION__, count); dbg(2," %s : enter, count = %Zd", __FUNCTION__, count);
dev = file->private_data; dev = file->private_data;
/* lock this object */
retval = mutex_lock_interruptible(&dev->mtx); retval = mutex_lock_interruptible(&dev->mtx);
if (retval) if (retval)
goto exit_nolock; goto exit_nolock;
/* verify that the device wasn't unplugged */ /* verify that the device wasn't unplugged */
if (dev->udev == NULL || dev->minor == 0) { if (dev->udev == NULL) {
retval = -ENODEV; retval = -ENODEV;
err("No device or device unplugged %d", retval); err("No device or device unplugged %d", retval);
goto exit; goto exit;
...@@ -564,42 +586,37 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, ...@@ -564,42 +586,37 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
goto exit; goto exit;
} }
while (count > 0) { while (count > 0) {
if (dev->interrupt_out_urb->status == -EINPROGRESS) { add_wait_queue(&dev->write_wait, &waita);
timeout = COMMAND_TIMEOUT; set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irqsave(&dev->buflock, flags);
if (!dev->out_urb_finished) {
spin_unlock_irqrestore(&dev->buflock, flags);
while (timeout > 0) { mutex_unlock(&dev->mtx);
if (signal_pending(current)) { if (signal_pending(current)) {
dbg(1," %s : interrupted", __FUNCTION__); dbg(1," %s : interrupted", __FUNCTION__);
set_current_state(TASK_RUNNING);
retval = -EINTR; retval = -EINTR;
goto exit; goto exit_onqueue;
} }
mutex_unlock(&dev->mtx); if (schedule_timeout(COMMAND_TIMEOUT) == 0) {
timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout); dbg(1, "%s - command timed out.", __FUNCTION__);
retval = -ETIMEDOUT;
goto exit_onqueue;
}
remove_wait_queue(&dev->write_wait, &waita);
retval = mutex_lock_interruptible(&dev->mtx); retval = mutex_lock_interruptible(&dev->mtx);
if (retval) { if (retval) {
retval = bytes_written ? bytes_written : retval; retval = bytes_written ? bytes_written : retval;
goto exit_nolock; goto exit_nolock;
} }
if (timeout > 0) {
break;
}
dbg(1," %s : interrupted timeout: %d", __FUNCTION__, timeout);
}
dbg(1," %s : final timeout: %d", __FUNCTION__, timeout);
if (timeout == 0) {
dbg(1, "%s - command timed out.", __FUNCTION__);
retval = -ETIMEDOUT;
goto exit;
}
dbg(4," %s : in progress, count = %Zd", __FUNCTION__, count);
dbg(4," %s : in progress, count = %Zd", __FUNCTION__, count);
} else { } else {
spin_unlock_irqrestore(&dev->buflock, flags);
set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->write_wait, &waita);
dbg(4," %s : sending, count = %Zd", __FUNCTION__, count); dbg(4," %s : sending, count = %Zd", __FUNCTION__, count);
/* write the data into interrupt_out_buffer from userspace */ /* write the data into interrupt_out_buffer from userspace */
...@@ -622,11 +639,12 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, ...@@ -622,11 +639,12 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
bytes_to_write, bytes_to_write,
adu_interrupt_out_callback, adu_interrupt_out_callback,
dev, dev,
dev->interrupt_in_endpoint->bInterval); dev->interrupt_out_endpoint->bInterval);
/* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */
dev->interrupt_out_urb->actual_length = bytes_to_write; dev->interrupt_out_urb->actual_length = bytes_to_write;
dev->out_urb_finished = 0;
retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
if (retval < 0) { if (retval < 0) {
dev->out_urb_finished = 1;
err("Couldn't submit interrupt_out_urb %d", retval); err("Couldn't submit interrupt_out_urb %d", retval);
goto exit; goto exit;
} }
...@@ -637,16 +655,17 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, ...@@ -637,16 +655,17 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
bytes_written += bytes_to_write; bytes_written += bytes_to_write;
} }
} }
mutex_unlock(&dev->mtx);
retval = bytes_written; return bytes_written;
exit: exit:
/* unlock the device */
mutex_unlock(&dev->mtx); mutex_unlock(&dev->mtx);
exit_nolock: exit_nolock:
dbg(2," %s : leave, return value %d", __FUNCTION__, retval); dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
return retval;
exit_onqueue:
remove_wait_queue(&dev->write_wait, &waita);
return retval; return retval;
} }
...@@ -831,25 +850,22 @@ static void adu_disconnect(struct usb_interface *interface) ...@@ -831,25 +850,22 @@ static void adu_disconnect(struct usb_interface *interface)
dbg(2," %s : enter", __FUNCTION__); dbg(2," %s : enter", __FUNCTION__);
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
mutex_lock(&dev->mtx); /* not interruptible */
dev->udev = NULL; /* poison */
minor = dev->minor; minor = dev->minor;
/* give back our minor */
usb_deregister_dev(interface, &adu_class); usb_deregister_dev(interface, &adu_class);
dev->minor = 0; mutex_unlock(&dev->mtx);
mutex_lock(&dev->mtx); /* not interruptible */ mutex_lock(&adutux_mutex);
usb_set_intfdata(interface, NULL);
/* if the device is not opened, then we clean up right now */ /* if the device is not opened, then we clean up right now */
dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); dbg(2," %s : open count %d", __FUNCTION__, dev->open_count);
if (!dev->open_count) { if (!dev->open_count)
mutex_unlock(&dev->mtx);
adu_delete(dev); adu_delete(dev);
} else {
dev->udev = NULL; mutex_unlock(&adutux_mutex);
mutex_unlock(&dev->mtx);
}
dev_info(&interface->dev, "ADU device adutux%d now disconnected\n", dev_info(&interface->dev, "ADU device adutux%d now disconnected\n",
(minor - ADU_MINOR_BASE)); (minor - ADU_MINOR_BASE));
......
...@@ -144,12 +144,14 @@ static void led_disconnect(struct usb_interface *interface) ...@@ -144,12 +144,14 @@ static void led_disconnect(struct usb_interface *interface)
struct usb_led *dev; struct usb_led *dev;
dev = usb_get_intfdata (interface); dev = usb_get_intfdata (interface);
usb_set_intfdata (interface, NULL);
device_remove_file(&interface->dev, &dev_attr_blue); device_remove_file(&interface->dev, &dev_attr_blue);
device_remove_file(&interface->dev, &dev_attr_red); device_remove_file(&interface->dev, &dev_attr_red);
device_remove_file(&interface->dev, &dev_attr_green); device_remove_file(&interface->dev, &dev_attr_green);
/* first remove the files, then set the pointer to NULL */
usb_set_intfdata (interface, NULL);
usb_put_dev(dev->udev); usb_put_dev(dev->udev);
kfree(dev); kfree(dev);
......
...@@ -327,6 +327,7 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb) ...@@ -327,6 +327,7 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb)
struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
int status = urb->status; int status = urb->status;
unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
...@@ -339,11 +340,11 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb) ...@@ -339,11 +340,11 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb)
usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
/* Throttle the device if requested by tty */ /* Throttle the device if requested by tty */
spin_lock(&port->lock); spin_lock_irqsave(&port->lock, flags);
if (!(port->throttled = port->throttle_req)) if (!(port->throttled = port->throttle_req))
/* Handle data and continue reading from device */ /* Handle data and continue reading from device */
flush_and_resubmit_read_urb(port); flush_and_resubmit_read_urb(port);
spin_unlock(&port->lock); spin_unlock_irqrestore(&port->lock, flags);
} }
EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
......
...@@ -2711,7 +2711,7 @@ static int mos7840_startup(struct usb_serial *serial) ...@@ -2711,7 +2711,7 @@ static int mos7840_startup(struct usb_serial *serial)
status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
if (status < 0) { if (status < 0) {
dbg("Writing ZLP_REG5 failed status-0x%x\n", status); dbg("Writing ZLP_REG5 failed status-0x%x\n", status);
return -1; goto error;
} else } else
dbg("ZLP_REG5 Writing success status%d\n", status); dbg("ZLP_REG5 Writing success status%d\n", status);
......
...@@ -86,6 +86,7 @@ static struct usb_device_id id_table [] = { ...@@ -86,6 +86,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) }, { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) }, { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
{ USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -104,3 +104,6 @@ ...@@ -104,3 +104,6 @@
#define WS002IN_VENDOR_ID 0x11f6 #define WS002IN_VENDOR_ID 0x11f6
#define WS002IN_PRODUCT_ID 0x2001 #define WS002IN_PRODUCT_ID 0x2001
/* Corega CG-USBRS232R Serial Adapter */
#define COREGA_VENDOR_ID 0x07aa
#define COREGA_PRODUCT_ID 0x002a
...@@ -136,6 +136,8 @@ static struct usb_device_id id_table_3port [] = { ...@@ -136,6 +136,8 @@ static struct usb_device_id id_table_3port [] = {
{ USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
{ USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/ { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/
......
...@@ -177,6 +177,10 @@ static int slave_configure(struct scsi_device *sdev) ...@@ -177,6 +177,10 @@ static int slave_configure(struct scsi_device *sdev)
* is an occasional series of retries that will all fail. */ * is an occasional series of retries that will all fail. */
sdev->retry_hwerror = 1; sdev->retry_hwerror = 1;
/* USB disks should allow restart. Some drives spin down
* automatically, requiring a START-STOP UNIT command. */
sdev->allow_restart = 1;
} else { } else {
/* Non-disk-type devices don't need to blacklist any pages /* Non-disk-type devices don't need to blacklist any pages
......
...@@ -342,11 +342,11 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100, ...@@ -342,11 +342,11 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100,
US_FL_FIX_CAPACITY), US_FL_FIX_CAPACITY),
/* Reported by Graber and Mike Pagano <mpagano-kernel@mpagano.com> */ /* Reported by Graber and Mike Pagano <mpagano-kernel@mpagano.com> */
UNUSUAL_DEV( 0x04b0, 0x040f, 0x0200, 0x0200, UNUSUAL_DEV( 0x04b0, 0x040f, 0x0100, 0x0200,
"NIKON", "NIKON",
"NIKON DSC D200", "NIKON DSC D200",
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY), US_FL_FIX_CAPACITY),
/* Reported by Emil Larsson <emil@swip.net> */ /* Reported by Emil Larsson <emil@swip.net> */
UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101, UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101,
...@@ -731,6 +731,13 @@ UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102, ...@@ -731,6 +731,13 @@ UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102,
US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
#endif #endif
/* Reported by RTE <raszilki@yandex.ru> */
UNUSUAL_DEV( 0x058f, 0x6387, 0x0141, 0x0141,
"JetFlash",
"TS1GJF2A/120",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_MAX_SECTORS_64 ),
/* Fabrizio Fellini <fello@libero.it> */ /* Fabrizio Fellini <fello@libero.it> */
UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210,
"Fujifilm", "Fujifilm",
......
...@@ -157,6 +157,7 @@ struct usb_interface { ...@@ -157,6 +157,7 @@ struct usb_interface {
* bound to */ * bound to */
enum usb_interface_condition condition; /* state of binding */ enum usb_interface_condition condition; /* state of binding */
unsigned is_active:1; /* the interface is not suspended */ unsigned is_active:1; /* the interface is not suspended */
unsigned sysfs_files_created:1; /* the sysfs attributes exist */
unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
struct device dev; /* interface specific device info */ struct device dev; /* interface specific device info */
......
...@@ -102,7 +102,8 @@ struct usbdevfs_urb { ...@@ -102,7 +102,8 @@ struct usbdevfs_urb {
int start_frame; int start_frame;
int number_of_packets; int number_of_packets;
int error_count; int error_count;
unsigned int signr; /* signal to be sent on error, -1 if none should be sent */ unsigned int signr; /* signal to be sent on completion,
or 0 if none should be sent. */
void *usercontext; void *usercontext;
struct usbdevfs_iso_packet_desc iso_frame_desc[0]; struct usbdevfs_iso_packet_desc iso_frame_desc[0];
}; };
......
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