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 ...
This commit is contained in:
Коммит
bb0851ff9d
|
@ -278,6 +278,14 @@ optional. The methods' jobs are quite simple:
|
|||
(although the interfaces will be in the same altsettings as
|
||||
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
|
||||
Documentation/usb/persist.txt) and it can also be used under certain
|
||||
circumstances when CONFIG_USB_PERSIST is not enabled. Currently, if a
|
||||
|
|
101
MAINTAINERS
101
MAINTAINERS
|
@ -323,8 +323,7 @@ S: Maintained
|
|||
ALCATEL SPEEDTOUCH USB DRIVER
|
||||
P: Duncan Sands
|
||||
M: duncan.sands@free.fr
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
W: http://www.linux-usb.org/SpeedTouch/
|
||||
S: Maintained
|
||||
|
||||
|
@ -1043,7 +1042,7 @@ S: Maintained
|
|||
CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER
|
||||
P: Lennert Buytenhek
|
||||
M: kernel@wantstofly.org
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
CIRRUS LOGIC CS4280/CS461x SOUNDDRIVER
|
||||
|
@ -1552,7 +1551,7 @@ S: Maintained
|
|||
FREESCALE HIGHSPEED USB DEVICE DRIVER
|
||||
P: Li Yang
|
||||
M: leoli@freescale.com
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
L: linuxppc-dev@ozlabs.org
|
||||
S: Maintained
|
||||
|
||||
|
@ -3810,22 +3809,20 @@ S: Maintained
|
|||
USB ACM DRIVER
|
||||
P: Oliver Neukum
|
||||
M: oliver@neukum.name
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
USB BLOCK DRIVER (UB ub)
|
||||
P: Pete Zaitcev
|
||||
M: zaitcev@redhat.com
|
||||
L: linux-kernel@vger.kernel.org
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
USB CDC ETHERNET DRIVER
|
||||
P: Greg Kroah-Hartman
|
||||
M: greg@kroah.com
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://www.kroah.com/linux-usb/
|
||||
|
||||
|
@ -3839,13 +3836,13 @@ S: Maintained
|
|||
USB EHCI DRIVER
|
||||
P: David Brownell
|
||||
M: dbrownell@users.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
|
||||
USB ET61X[12]51 DRIVER
|
||||
P: Luca Risolia
|
||||
M: luca.risolia@studio.unibo.it
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
L: video4linux-list@redhat.com
|
||||
W: http://www.linux-projects.org
|
||||
S: Maintained
|
||||
|
@ -3853,41 +3850,33 @@ S: Maintained
|
|||
USB GADGET/PERIPHERAL SUBSYSTEM
|
||||
P: David Brownell
|
||||
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
|
||||
S: Maintained
|
||||
|
||||
USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
|
||||
P: Jiri Kosina
|
||||
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
|
||||
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
|
||||
P: Olav Kongas
|
||||
M: ok@artecdesign.ee
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
USB KAWASAKI LSI DRIVER
|
||||
P: Oliver Neukum
|
||||
M: oliver@neukum.name
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
USB MASS STORAGE DRIVER
|
||||
P: Matthew Dharm
|
||||
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
|
||||
S: Maintained
|
||||
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
|
||||
P: David Brownell
|
||||
M: dbrownell@users.sourceforge.net
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
|
||||
USB OPTION-CARD DRIVER
|
||||
P: Matthias Urlichs
|
||||
M: smurf@smurf.noris.de
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
USB OV511 DRIVER
|
||||
P: Mark McClelland
|
||||
M: mmcclell@bigfoot.com
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
W: http://alpha.dyndns.org/ov511/
|
||||
S: Maintained
|
||||
|
||||
USB PEGASUS DRIVER
|
||||
P: Petko Manolov
|
||||
M: petkan@users.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
L: netdev@vger.kernel.org
|
||||
W: http://pegasus2.sourceforge.net/
|
||||
S: Maintained
|
||||
|
@ -3924,14 +3911,13 @@ S: Maintained
|
|||
USB PRINTER DRIVER (usblp)
|
||||
P: Pete Zaitcev
|
||||
M: zaitcev@redhat.com
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
USB RTL8150 DRIVER
|
||||
P: Petko Manolov
|
||||
M: petkan@users.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
L: netdev@vger.kernel.org
|
||||
W: http://pegasus2.sourceforge.net/
|
||||
S: Maintained
|
||||
|
@ -3939,8 +3925,7 @@ S: Maintained
|
|||
USB SE401 DRIVER
|
||||
P: Jeroen Vreeken
|
||||
M: pe1rxq@amsat.org
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
W: http://www.chello.nl/~j.vreeken/se401/
|
||||
S: Maintained
|
||||
|
||||
|
@ -3954,72 +3939,59 @@ USB SERIAL DIGI ACCELEPORT DRIVER
|
|||
P: Peter Berger and Al Borchers
|
||||
M: pberger@brimson.com
|
||||
M: alborchers@steinerpoint.com
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
USB SERIAL DRIVER
|
||||
P: Greg Kroah-Hartman
|
||||
M: gregkh@suse.de
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
USB SERIAL BELKIN F5U103 DRIVER
|
||||
P: William Greathouse
|
||||
M: wgreathouse@smva.com
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
USB SERIAL CYPRESS M8 DRIVER
|
||||
P: Lonnie Mendez
|
||||
M: dignome@gmail.com
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://geocities.com/i0xox0i
|
||||
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
|
||||
P: Wolfgang Muees
|
||||
M: wolfgang@iksw-muees.de
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
|
||||
P: Gary Brubaker
|
||||
M: xavyer@ix.netcom.com
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
USB SERIAL KEYSPAN DRIVER
|
||||
P: Greg Kroah-Hartman
|
||||
M: greg@kroah.com
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
W: http://www.kroah.com/linux/
|
||||
S: Maintained
|
||||
|
||||
USB SERIAL WHITEHEAT DRIVER
|
||||
P: Support Department
|
||||
M: support@connecttech.com
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
W: http://www.connecttech.com
|
||||
S: Supported
|
||||
|
||||
USB SN9C1xx DRIVER
|
||||
P: Luca Risolia
|
||||
M: luca.risolia@studio.unibo.it
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
L: video4linux-list@redhat.com
|
||||
W: http://www.linux-projects.org
|
||||
S: Maintained
|
||||
|
@ -4027,8 +3999,7 @@ S: Maintained
|
|||
USB SUBSYSTEM
|
||||
P: Greg Kroah-Hartman
|
||||
M: gregkh@suse.de
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
W: http://www.linux-usb.org
|
||||
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
|
||||
S: Supported
|
||||
|
@ -4036,8 +4007,7 @@ S: Supported
|
|||
USB UHCI DRIVER
|
||||
P: Alan Stern
|
||||
M: stern@rowland.harvard.edu
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
USB "USBNET" DRIVER FRAMEWORK
|
||||
|
@ -4050,7 +4020,7 @@ S: Maintained
|
|||
USB W996[87]CF DRIVER
|
||||
P: Luca Risolia
|
||||
M: luca.risolia@studio.unibo.it
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
L: video4linux-list@redhat.com
|
||||
W: http://www.linux-projects.org
|
||||
S: Maintained
|
||||
|
@ -4058,7 +4028,7 @@ S: Maintained
|
|||
USB ZC0301 DRIVER
|
||||
P: Luca Risolia
|
||||
M: luca.risolia@studio.unibo.it
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
L: video4linux-list@redhat.com
|
||||
W: http://www.linux-projects.org
|
||||
S: Maintained
|
||||
|
@ -4066,15 +4036,14 @@ S: Maintained
|
|||
USB ZD1201 DRIVER
|
||||
P: Jeroen Vreeken
|
||||
M: pe1rxq@amsat.org
|
||||
L: linux-usb-users@lists.sourceforge.net
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
W: http://linux-lc100020.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
USB ZR364XX DRIVER
|
||||
P: Antoine Jacquet
|
||||
M: royale@zerezo.com
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linux-usb@vger.kernel.org
|
||||
L: video4linux-list@redhat.com
|
||||
W: http://royale.zerezo.com/zr364xx/
|
||||
S: Maintained
|
||||
|
|
|
@ -39,12 +39,12 @@ first subdirectory in the list below that it fits into.
|
|||
|
||||
image/ - This is for still image drivers, like scanners or
|
||||
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.
|
||||
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
|
||||
subsystem.
|
||||
net/ - This is for network drivers.
|
||||
../net/ - This is for network drivers.
|
||||
serial/ - This is for USB to serial drivers.
|
||||
storage/ - This is for USB mass-storage drivers.
|
||||
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)
|
|||
{
|
||||
struct usb_device *usb_dev;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
/* driver is often null here; dev_dbg() would oops */
|
||||
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)
|
|||
usb_dev->descriptor.bDeviceProtocol))
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1311,8 +1311,8 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
|
|||
hcd = bus_to_hcd(udev->bus);
|
||||
|
||||
/* No more submits can occur */
|
||||
rescan:
|
||||
spin_lock_irq(&hcd_urb_list_lock);
|
||||
rescan:
|
||||
list_for_each_entry (urb, &ep->urb_list, urb_list) {
|
||||
int is_in;
|
||||
|
||||
|
@ -1345,6 +1345,7 @@ rescan:
|
|||
usb_put_urb (urb);
|
||||
|
||||
/* list contents may have changed */
|
||||
spin_lock(&hcd_urb_list_lock);
|
||||
goto rescan;
|
||||
}
|
||||
spin_unlock_irq(&hcd_urb_list_lock);
|
||||
|
|
|
@ -335,7 +335,7 @@ static void kick_khubd(struct usb_hub *hub)
|
|||
to_usb_interface(hub->intfdev)->pm_usage_cnt = 1;
|
||||
|
||||
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);
|
||||
wake_up(&khubd_wait);
|
||||
}
|
||||
|
|
|
@ -1172,7 +1172,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
|
|||
struct usb_host_interface *alt;
|
||||
int ret;
|
||||
int manual = 0;
|
||||
int changed;
|
||||
|
||||
if (dev->state == USB_STATE_SUSPENDED)
|
||||
return -EHOSTUNREACH;
|
||||
|
@ -1212,8 +1211,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
|
|||
*/
|
||||
|
||||
/* prevent submissions using previous endpoint settings */
|
||||
changed = (iface->cur_altsetting != alt);
|
||||
if (changed && device_is_registered(&iface->dev))
|
||||
if (iface->cur_altsetting != alt && device_is_registered(&iface->dev))
|
||||
usb_remove_sysfs_intf_files(iface);
|
||||
usb_disable_interface(dev, iface);
|
||||
|
||||
|
@ -1250,7 +1248,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
|
|||
* (Likewise, EP0 never "halts" on well designed devices.)
|
||||
*/
|
||||
usb_enable_interface(dev, iface);
|
||||
if (changed && device_is_registered(&iface->dev))
|
||||
if (device_is_registered(&iface->dev))
|
||||
usb_create_sysfs_intf_files(iface);
|
||||
|
||||
return 0;
|
||||
|
@ -1348,34 +1346,10 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|||
struct usb_interface *intf;
|
||||
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);
|
||||
usb_dev = interface_to_usbdev(intf);
|
||||
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",
|
||||
alt->desc.bInterfaceClass,
|
||||
alt->desc.bInterfaceSubClass,
|
||||
|
@ -1641,12 +1615,6 @@ free_interfaces:
|
|||
intf->dev.bus_id, ret);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -735,6 +735,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
|
|||
struct usb_host_interface *alt = intf->cur_altsetting;
|
||||
int retval;
|
||||
|
||||
if (intf->sysfs_files_created)
|
||||
return 0;
|
||||
retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
@ -746,6 +748,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
|
|||
if (intf->intf_assoc)
|
||||
retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp);
|
||||
usb_create_intf_ep_files(intf, udev);
|
||||
intf->sysfs_files_created = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -753,8 +756,11 @@ void usb_remove_sysfs_intf_files(struct usb_interface *intf)
|
|||
{
|
||||
struct device *dev = &intf->dev;
|
||||
|
||||
if (!intf->sysfs_files_created)
|
||||
return;
|
||||
usb_remove_intf_ep_files(intf);
|
||||
device_remove_file(dev, &dev_attr_interface);
|
||||
sysfs_remove_group(&dev->kobj, &intf_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)
|
|||
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 = {
|
||||
.name = "usb_device",
|
||||
.release = usb_release_dev,
|
||||
.uevent = usb_dev_uevent,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
@ -1241,14 +1241,14 @@ static void pullup_enable(struct omap_udc *udc)
|
|||
udc->gadget.dev.parent->power.power_state = PMSG_ON;
|
||||
udc->gadget.dev.power.power_state = PMSG_ON;
|
||||
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;
|
||||
UDC_IRQ_EN_REG = UDC_DS_CHG_IE;
|
||||
}
|
||||
|
||||
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;
|
||||
UDC_IRQ_EN_REG = UDC_DS_CHG_IE;
|
||||
UDC_SYSCON1_REG &= ~UDC_PULLUP_EN;
|
||||
|
@ -1386,7 +1386,7 @@ static void update_otg(struct omap_udc *udc)
|
|||
{
|
||||
u16 devstat;
|
||||
|
||||
if (!gadget_is_otg(udc->gadget))
|
||||
if (!gadget_is_otg(&udc->gadget))
|
||||
return;
|
||||
|
||||
if (OTG_CTRL_REG & OTG_ID)
|
||||
|
|
|
@ -52,10 +52,10 @@
|
|||
#include <asm/arch/irqs.h>
|
||||
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/regs-clock.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>
|
||||
|
||||
|
@ -1511,7 +1511,11 @@ static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev)
|
|||
unsigned int value;
|
||||
|
||||
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);
|
||||
s3c2410_gpio_cfgpin(udc_info->vbus_pin, S3C2410_GPIO_SFN2);
|
||||
|
||||
if (udc_info->vbus_pin_inverted)
|
||||
value = !value;
|
||||
|
@ -1872,9 +1876,9 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
|
|||
if (udc_info && udc_info->vbus_pin > 0) {
|
||||
irq = s3c2410_gpio_getirq(udc_info->vbus_pin);
|
||||
retval = request_irq(irq, s3c2410_udc_vbus_irq,
|
||||
IRQF_DISABLED | IRQF_TRIGGER_RISING
|
||||
| IRQF_TRIGGER_FALLING,
|
||||
gadget_name, udc);
|
||||
IRQF_DISABLED | IRQF_TRIGGER_RISING
|
||||
| IRQF_TRIGGER_FALLING | IRQF_SHARED,
|
||||
gadget_name, udc);
|
||||
|
||||
if (retval != 0) {
|
||||
dev_err(dev, "can't get vbus irq %i, err %d\n",
|
||||
|
|
|
@ -156,7 +156,7 @@ config USB_OHCI_HCD_PCI
|
|||
|
||||
config USB_OHCI_HCD_SSB
|
||||
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
|
||||
---help---
|
||||
Support for the Sonics Silicon Backplane (SSB) attached
|
||||
|
|
|
@ -575,12 +575,15 @@ static int ehci_run (struct usb_hcd *hcd)
|
|||
* from the companions to the EHCI controller. If any of the
|
||||
* companions are in the middle of a port reset at the time, it
|
||||
* 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);
|
||||
hcd->state = HC_STATE_RUNNING;
|
||||
ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
|
||||
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
|
||||
msleep(5);
|
||||
up_write(&ehci_cf_port_reset_rwsem);
|
||||
|
||||
temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
|
||||
|
|
|
@ -819,7 +819,7 @@ static int mts_usb_probe(struct usb_interface *intf,
|
|||
goto out_kfree2;
|
||||
|
||||
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;
|
||||
goto out_host_put;
|
||||
}
|
||||
|
|
|
@ -79,12 +79,22 @@ MODULE_DEVICE_TABLE(usb, device_table);
|
|||
|
||||
#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 */
|
||||
struct adu_device {
|
||||
struct mutex mtx; /* locks this structure */
|
||||
struct mutex mtx;
|
||||
struct usb_device* udev; /* save off the usb device pointer */
|
||||
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];
|
||||
|
||||
int open_count; /* number of times this port has been opened */
|
||||
|
@ -107,8 +117,11 @@ struct adu_device {
|
|||
char* interrupt_out_buffer;
|
||||
struct usb_endpoint_descriptor* interrupt_out_endpoint;
|
||||
struct urb* interrupt_out_urb;
|
||||
int out_urb_finished;
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(adutux_mutex);
|
||||
|
||||
static struct usb_driver adu_driver;
|
||||
|
||||
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)
|
||||
{
|
||||
dbg(2," %s : enter", __FUNCTION__);
|
||||
unsigned long flags;
|
||||
|
||||
if (dev == NULL) {
|
||||
dbg(1," %s : dev is null", __FUNCTION__);
|
||||
goto exit;
|
||||
}
|
||||
dbg(2," %s : enter", __FUNCTION__);
|
||||
|
||||
if (dev->udev == NULL) {
|
||||
dbg(1," %s : udev is null", __FUNCTION__);
|
||||
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 */
|
||||
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:
|
||||
dbg(2," %s : leave", __FUNCTION__);
|
||||
|
@ -162,8 +179,6 @@ static void adu_delete(struct adu_device *dev)
|
|||
{
|
||||
dbg(2, "%s enter", __FUNCTION__);
|
||||
|
||||
adu_abort_transfers(dev);
|
||||
|
||||
/* free data structures */
|
||||
usb_free_urb(dev->interrupt_in_urb);
|
||||
usb_free_urb(dev->interrupt_out_urb);
|
||||
|
@ -239,7 +254,10 @@ static void adu_interrupt_out_callback(struct urb *urb)
|
|||
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:
|
||||
|
||||
adu_debug_data(5, __FUNCTION__, urb->actual_length,
|
||||
|
@ -252,12 +270,17 @@ static int adu_open(struct inode *inode, struct file *file)
|
|||
struct adu_device *dev = NULL;
|
||||
struct usb_interface *interface;
|
||||
int subminor;
|
||||
int retval = 0;
|
||||
int retval;
|
||||
|
||||
dbg(2,"%s : enter", __FUNCTION__);
|
||||
|
||||
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);
|
||||
if (!interface) {
|
||||
err("%s - error, can't find device for minor %d",
|
||||
|
@ -267,54 +290,54 @@ static int adu_open(struct inode *inode, struct file *file)
|
|||
}
|
||||
|
||||
dev = usb_get_intfdata(interface);
|
||||
if (!dev) {
|
||||
if (!dev || !dev->udev) {
|
||||
retval = -ENODEV;
|
||||
goto exit_no_device;
|
||||
}
|
||||
|
||||
/* lock this device */
|
||||
if ((retval = mutex_lock_interruptible(&dev->mtx))) {
|
||||
dbg(2, "%s : mutex lock failed", __FUNCTION__);
|
||||
/* check that nobody else is using the device */
|
||||
if (dev->open_count) {
|
||||
retval = -EBUSY;
|
||||
goto exit_no_device;
|
||||
}
|
||||
|
||||
/* increment our usage count for the device */
|
||||
++dev->open_count;
|
||||
dbg(2,"%s : open count %d", __FUNCTION__, dev->open_count);
|
||||
|
||||
/* save device in the file's private structure */
|
||||
file->private_data = dev;
|
||||
|
||||
if (dev->open_count == 1) {
|
||||
/* initialize in direction */
|
||||
dev->read_buffer_length = 0;
|
||||
/* initialize in direction */
|
||||
dev->read_buffer_length = 0;
|
||||
|
||||
/* fixup first read by having urb waiting for it */
|
||||
usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
|
||||
usb_rcvintpipe(dev->udev,
|
||||
dev->interrupt_in_endpoint->bEndpointAddress),
|
||||
dev->interrupt_in_buffer,
|
||||
le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
|
||||
adu_interrupt_in_callback, dev,
|
||||
dev->interrupt_in_endpoint->bInterval);
|
||||
/* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */
|
||||
dev->read_urb_finished = 0;
|
||||
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
|
||||
if (retval)
|
||||
--dev->open_count;
|
||||
}
|
||||
mutex_unlock(&dev->mtx);
|
||||
/* fixup first read by having urb waiting for it */
|
||||
usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
|
||||
usb_rcvintpipe(dev->udev,
|
||||
dev->interrupt_in_endpoint->bEndpointAddress),
|
||||
dev->interrupt_in_buffer,
|
||||
le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
|
||||
adu_interrupt_in_callback, dev,
|
||||
dev->interrupt_in_endpoint->bInterval);
|
||||
dev->read_urb_finished = 0;
|
||||
if (usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL))
|
||||
dev->read_urb_finished = 1;
|
||||
/* we ignore failure */
|
||||
/* end of fixup for first read */
|
||||
|
||||
/* initialize out direction */
|
||||
dev->out_urb_finished = 1;
|
||||
|
||||
retval = 0;
|
||||
|
||||
exit_no_device:
|
||||
mutex_unlock(&adutux_mutex);
|
||||
exit_no_lock:
|
||||
dbg(2,"%s : leave, return value %d ", __FUNCTION__, 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__);
|
||||
|
||||
/* decrement our usage count for the device */
|
||||
|
@ -326,12 +349,11 @@ static int adu_release_internal(struct adu_device *dev)
|
|||
}
|
||||
|
||||
dbg(2," %s : leave", __FUNCTION__);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int adu_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct adu_device *dev = NULL;
|
||||
struct adu_device *dev;
|
||||
int retval = 0;
|
||||
|
||||
dbg(2," %s : enter", __FUNCTION__);
|
||||
|
@ -343,15 +365,13 @@ static int adu_release(struct inode *inode, struct file *file)
|
|||
}
|
||||
|
||||
dev = file->private_data;
|
||||
|
||||
if (dev == NULL) {
|
||||
dbg(1," %s : object is NULL", __FUNCTION__);
|
||||
retval = -ENODEV;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* lock our device */
|
||||
mutex_lock(&dev->mtx); /* not interruptible */
|
||||
mutex_lock(&adutux_mutex); /* not interruptible */
|
||||
|
||||
if (dev->open_count <= 0) {
|
||||
dbg(1," %s : device not opened", __FUNCTION__);
|
||||
|
@ -359,19 +379,15 @@ static int adu_release(struct inode *inode, struct file *file)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
adu_release_internal(dev);
|
||||
if (dev->udev == NULL) {
|
||||
/* the device was unplugged before the file was released */
|
||||
mutex_unlock(&dev->mtx);
|
||||
adu_delete(dev);
|
||||
dev = NULL;
|
||||
} else {
|
||||
/* do the work */
|
||||
retval = adu_release_internal(dev);
|
||||
if (!dev->open_count) /* ... and we're the last user */
|
||||
adu_delete(dev);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (dev)
|
||||
mutex_unlock(&dev->mtx);
|
||||
mutex_unlock(&adutux_mutex);
|
||||
dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
|
||||
return retval;
|
||||
}
|
||||
|
@ -393,12 +409,12 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||
|
||||
dev = file->private_data;
|
||||
dbg(2," %s : dev=%p", __FUNCTION__, dev);
|
||||
/* lock this object */
|
||||
|
||||
if (mutex_lock_interruptible(&dev->mtx))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
/* verify that the device wasn't unplugged */
|
||||
if (dev->udev == NULL || dev->minor == 0) {
|
||||
if (dev->udev == NULL) {
|
||||
retval = -ENODEV;
|
||||
err("No device or device unplugged %d", retval);
|
||||
goto exit;
|
||||
|
@ -452,7 +468,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||
should_submit = 1;
|
||||
} else {
|
||||
/* 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 */
|
||||
spin_unlock_irqrestore(&dev->buflock, flags);
|
||||
dbg(2," %s : submitted already", __FUNCTION__);
|
||||
|
@ -460,6 +476,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||
/* we must initiate input */
|
||||
dbg(2," %s : initiate input", __FUNCTION__);
|
||||
dev->read_urb_finished = 0;
|
||||
spin_unlock_irqrestore(&dev->buflock, flags);
|
||||
|
||||
usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
|
||||
usb_rcvintpipe(dev->udev,
|
||||
|
@ -469,15 +486,12 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||
adu_interrupt_in_callback,
|
||||
dev,
|
||||
dev->interrupt_in_endpoint->bInterval);
|
||||
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
|
||||
if (!retval) {
|
||||
spin_unlock_irqrestore(&dev->buflock, flags);
|
||||
dbg(2," %s : submitted OK", __FUNCTION__);
|
||||
} else {
|
||||
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
|
||||
if (retval) {
|
||||
dev->read_urb_finished = 1;
|
||||
if (retval == -ENOMEM) {
|
||||
retval = bytes_read ? bytes_read : -ENOMEM;
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->buflock, flags);
|
||||
dbg(2," %s : submit failed", __FUNCTION__);
|
||||
goto exit;
|
||||
}
|
||||
|
@ -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 */
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
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);
|
||||
else
|
||||
} else {
|
||||
spin_unlock_irqrestore(&dev->buflock, flags);
|
||||
set_current_state(TASK_RUNNING);
|
||||
}
|
||||
remove_wait_queue(&dev->read_wait, &wait);
|
||||
|
||||
if (timeout <= 0) {
|
||||
|
@ -509,19 +527,23 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||
|
||||
retval = bytes_read;
|
||||
/* 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_rcvintpipe(dev->udev,
|
||||
dev->interrupt_in_endpoint->bEndpointAddress),
|
||||
dev->interrupt_in_buffer,
|
||||
le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
|
||||
adu_interrupt_in_callback,
|
||||
dev,
|
||||
dev->interrupt_in_endpoint->bInterval);
|
||||
/* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */
|
||||
dev->read_urb_finished = 0;
|
||||
usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
|
||||
dev->interrupt_in_buffer,
|
||||
le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
|
||||
adu_interrupt_in_callback,
|
||||
dev,
|
||||
dev->interrupt_in_endpoint->bInterval);
|
||||
if (usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL) != 0)
|
||||
dev->read_urb_finished = 1;
|
||||
/* we ignore failure */
|
||||
} else {
|
||||
spin_unlock_irqrestore(&dev->buflock, flags);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
@ -535,24 +557,24 @@ exit:
|
|||
static ssize_t adu_write(struct file *file, const __user char *buffer,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
DECLARE_WAITQUEUE(waita, current);
|
||||
struct adu_device *dev;
|
||||
size_t bytes_written = 0;
|
||||
size_t bytes_to_write;
|
||||
size_t buffer_size;
|
||||
unsigned long flags;
|
||||
int retval;
|
||||
int timeout = 0;
|
||||
|
||||
dbg(2," %s : enter, count = %Zd", __FUNCTION__, count);
|
||||
|
||||
dev = file->private_data;
|
||||
|
||||
/* lock this object */
|
||||
retval = mutex_lock_interruptible(&dev->mtx);
|
||||
if (retval)
|
||||
goto exit_nolock;
|
||||
|
||||
/* verify that the device wasn't unplugged */
|
||||
if (dev->udev == NULL || dev->minor == 0) {
|
||||
if (dev->udev == NULL) {
|
||||
retval = -ENODEV;
|
||||
err("No device or device unplugged %d", retval);
|
||||
goto exit;
|
||||
|
@ -564,42 +586,37 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
while (count > 0) {
|
||||
if (dev->interrupt_out_urb->status == -EINPROGRESS) {
|
||||
timeout = COMMAND_TIMEOUT;
|
||||
add_wait_queue(&dev->write_wait, &waita);
|
||||
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) {
|
||||
if (signal_pending(current)) {
|
||||
dbg(1," %s : interrupted", __FUNCTION__);
|
||||
retval = -EINTR;
|
||||
goto exit;
|
||||
}
|
||||
mutex_unlock(&dev->mtx);
|
||||
timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout);
|
||||
if (signal_pending(current)) {
|
||||
dbg(1," %s : interrupted", __FUNCTION__);
|
||||
set_current_state(TASK_RUNNING);
|
||||
retval = -EINTR;
|
||||
goto exit_onqueue;
|
||||
}
|
||||
if (schedule_timeout(COMMAND_TIMEOUT) == 0) {
|
||||
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);
|
||||
if (retval) {
|
||||
retval = bytes_written ? bytes_written : retval;
|
||||
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 {
|
||||
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);
|
||||
|
||||
/* 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,
|
|||
bytes_to_write,
|
||||
adu_interrupt_out_callback,
|
||||
dev,
|
||||
dev->interrupt_in_endpoint->bInterval);
|
||||
/* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */
|
||||
dev->interrupt_out_endpoint->bInterval);
|
||||
dev->interrupt_out_urb->actual_length = bytes_to_write;
|
||||
dev->out_urb_finished = 0;
|
||||
retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
|
||||
if (retval < 0) {
|
||||
dev->out_urb_finished = 1;
|
||||
err("Couldn't submit interrupt_out_urb %d", retval);
|
||||
goto exit;
|
||||
}
|
||||
|
@ -637,16 +655,17 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
|
|||
bytes_written += bytes_to_write;
|
||||
}
|
||||
}
|
||||
|
||||
retval = bytes_written;
|
||||
mutex_unlock(&dev->mtx);
|
||||
return bytes_written;
|
||||
|
||||
exit:
|
||||
/* unlock the device */
|
||||
mutex_unlock(&dev->mtx);
|
||||
exit_nolock:
|
||||
|
||||
dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
|
||||
return retval;
|
||||
|
||||
exit_onqueue:
|
||||
remove_wait_queue(&dev->write_wait, &waita);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -831,25 +850,22 @@ static void adu_disconnect(struct usb_interface *interface)
|
|||
dbg(2," %s : enter", __FUNCTION__);
|
||||
|
||||
dev = usb_get_intfdata(interface);
|
||||
usb_set_intfdata(interface, NULL);
|
||||
|
||||
mutex_lock(&dev->mtx); /* not interruptible */
|
||||
dev->udev = NULL; /* poison */
|
||||
minor = dev->minor;
|
||||
|
||||
/* give back our minor */
|
||||
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 */
|
||||
dbg(2," %s : open count %d", __FUNCTION__, dev->open_count);
|
||||
if (!dev->open_count) {
|
||||
mutex_unlock(&dev->mtx);
|
||||
if (!dev->open_count)
|
||||
adu_delete(dev);
|
||||
} else {
|
||||
dev->udev = NULL;
|
||||
mutex_unlock(&dev->mtx);
|
||||
}
|
||||
|
||||
mutex_unlock(&adutux_mutex);
|
||||
|
||||
dev_info(&interface->dev, "ADU device adutux%d now disconnected\n",
|
||||
(minor - ADU_MINOR_BASE));
|
||||
|
|
|
@ -144,12 +144,14 @@ static void led_disconnect(struct usb_interface *interface)
|
|||
struct usb_led *dev;
|
||||
|
||||
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_red);
|
||||
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);
|
||||
|
||||
kfree(dev);
|
||||
|
|
|
@ -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;
|
||||
unsigned char *data = urb->transfer_buffer;
|
||||
int status = urb->status;
|
||||
unsigned long flags;
|
||||
|
||||
dbg("%s - port %d", __FUNCTION__, port->number);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/* Throttle the device if requested by tty */
|
||||
spin_lock(&port->lock);
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
if (!(port->throttled = port->throttle_req))
|
||||
/* Handle data and continue reading from device */
|
||||
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);
|
||||
|
||||
|
|
|
@ -2711,7 +2711,7 @@ static int mos7840_startup(struct usb_serial *serial)
|
|||
status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
|
||||
if (status < 0) {
|
||||
dbg("Writing ZLP_REG5 failed status-0x%x\n", status);
|
||||
return -1;
|
||||
goto error;
|
||||
} else
|
||||
dbg("ZLP_REG5 Writing success status%d\n", status);
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ static struct usb_device_id id_table [] = {
|
|||
{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
|
||||
{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
|
||||
{ USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
|
|
@ -104,3 +104,6 @@
|
|||
#define WS002IN_VENDOR_ID 0x11f6
|
||||
#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 [] = {
|
|||
{ USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */
|
||||
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
|
||||
{ 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, 0x0021) }, /* Sierra Wireless AirCard 597E */
|
||||
{ USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/
|
||||
|
|
|
@ -177,6 +177,10 @@ static int slave_configure(struct scsi_device *sdev)
|
|||
* is an occasional series of retries that will all fail. */
|
||||
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 {
|
||||
|
||||
/* Non-disk-type devices don't need to blacklist any pages
|
||||
|
|
|
@ -342,11 +342,11 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100,
|
|||
US_FL_FIX_CAPACITY),
|
||||
|
||||
/* Reported by Graber and Mike Pagano <mpagano-kernel@mpagano.com> */
|
||||
UNUSUAL_DEV( 0x04b0, 0x040f, 0x0200, 0x0200,
|
||||
"NIKON",
|
||||
"NIKON DSC D200",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_FIX_CAPACITY),
|
||||
UNUSUAL_DEV( 0x04b0, 0x040f, 0x0100, 0x0200,
|
||||
"NIKON",
|
||||
"NIKON DSC D200",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_FIX_CAPACITY),
|
||||
|
||||
/* Reported by Emil Larsson <emil@swip.net> */
|
||||
UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101,
|
||||
|
@ -731,6 +731,13 @@ UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102,
|
|||
US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
|
||||
#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> */
|
||||
UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210,
|
||||
"Fujifilm",
|
||||
|
|
|
@ -157,6 +157,7 @@ struct usb_interface {
|
|||
* bound to */
|
||||
enum usb_interface_condition condition; /* state of binding */
|
||||
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 */
|
||||
|
||||
struct device dev; /* interface specific device info */
|
||||
|
|
|
@ -102,7 +102,8 @@ struct usbdevfs_urb {
|
|||
int start_frame;
|
||||
int number_of_packets;
|
||||
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;
|
||||
struct usbdevfs_iso_packet_desc iso_frame_desc[0];
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче