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

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (103 commits)
  usbcore: remove unused argument in autosuspend
  USB: keep count of unsuspended children
  USB hub: simplify remote-wakeup handling
  USB: struct usb_device: change flag to bitflag
  OHCI: make autostop conditional on CONFIG_PM
  USB: Add autosuspend support to the hub driver
  EHCI: Fix root-hub and port suspend/resume problems
  USB: create a new thread for every USB device found during the probe sequence
  USB: add driver for the USB debug devices
  USB: added dynamic major number for USB endpoints
  USB: pegasus error path not resetting task's state
  USB: endianness fix for asix.c
  USB: build the appledisplay driver
  USB serial: replace kmalloc+memset with kzalloc
  USB: hid-core: canonical defines for Apple USB device IDs
  USB: idmouse cleanup
  USB: make drivers/usb/core/driver.c:usb_device_match() static
  USB: lh7a40x_udc remove double declaration
  USB: pxa2xx_udc recognizes ixp425 rev b0 chip
  usbtouchscreen: add support for DMC TSC-10/25 devices
  ...
This commit is contained in:
Linus Torvalds 2006-12-01 16:41:58 -08:00
commit 9641219825
98 changed files with 1269 additions and 856 deletions

View file

@ -345,8 +345,7 @@ static inline void skel_delete (struct usb_skel *dev)
usb_buffer_free (dev->udev, dev->bulk_out_size,
dev->bulk_out_buffer,
dev->write_urb->transfer_dma);
if (dev->write_urb != NULL)
usb_free_urb (dev->write_urb);
usb_free_urb (dev->write_urb);
kfree (dev);
}
</programlisting>

View file

@ -561,8 +561,7 @@ static struct notifier_block usb_pcwd_notifier = {
*/
static inline void usb_pcwd_delete (struct usb_pcwd_private *usb_pcwd)
{
if (usb_pcwd->intr_urb != NULL)
usb_free_urb (usb_pcwd->intr_urb);
usb_free_urb(usb_pcwd->intr_urb);
if (usb_pcwd->intr_buffer != NULL)
usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size,
usb_pcwd->intr_buffer, usb_pcwd->intr_dma);

View file

@ -178,9 +178,9 @@ static int iforce_usb_probe(struct usb_interface *intf,
fail:
if (iforce) {
if (iforce->irq) usb_free_urb(iforce->irq);
if (iforce->out) usb_free_urb(iforce->out);
if (iforce->ctrl) usb_free_urb(iforce->ctrl);
usb_free_urb(iforce->irq);
usb_free_urb(iforce->out);
usb_free_urb(iforce->ctrl);
kfree(iforce);
}

View file

@ -815,14 +815,11 @@ static int gigaset_probe(struct usb_interface *interface,
return 0;
error:
if (ucs->read_urb)
usb_kill_urb(ucs->read_urb);
usb_kill_urb(ucs->read_urb);
kfree(ucs->bulk_out_buffer);
if (ucs->bulk_out_urb != NULL)
usb_free_urb(ucs->bulk_out_urb);
usb_free_urb(ucs->bulk_out_urb);
kfree(cs->inbuf[0].rcvbuf);
if (ucs->read_urb != NULL)
usb_free_urb(ucs->read_urb);
usb_free_urb(ucs->read_urb);
usb_set_intfdata(interface, NULL);
ucs->read_urb = ucs->bulk_out_urb = NULL;
cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL;
@ -850,11 +847,9 @@ static void gigaset_disconnect(struct usb_interface *interface)
usb_kill_urb(ucs->bulk_out_urb); /* FIXME: only if active? */
kfree(ucs->bulk_out_buffer);
if (ucs->bulk_out_urb != NULL)
usb_free_urb(ucs->bulk_out_urb);
usb_free_urb(ucs->bulk_out_urb);
kfree(cs->inbuf[0].rcvbuf);
if (ucs->read_urb != NULL)
usb_free_urb(ucs->read_urb);
usb_free_urb(ucs->read_urb);
ucs->read_urb = ucs->bulk_out_urb = NULL;
cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL;

View file

@ -275,8 +275,7 @@ static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2)
int i;
for (i=0; i<STREAM_URB_COUNT; i++)
if (cinergyt2->stream_urb[i])
usb_free_urb(cinergyt2->stream_urb[i]);
usb_free_urb(cinergyt2->stream_urb[i]);
usb_buffer_free(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE,
cinergyt2->streambuf, cinergyt2->streambuf_dmahandle);
@ -320,8 +319,7 @@ static void cinergyt2_stop_stream_xfer (struct cinergyt2 *cinergyt2)
cinergyt2_control_stream_transfer(cinergyt2, 0);
for (i=0; i<STREAM_URB_COUNT; i++)
if (cinergyt2->stream_urb[i])
usb_kill_urb(cinergyt2->stream_urb[i]);
usb_kill_urb(cinergyt2->stream_urb[i]);
}
static int cinergyt2_start_stream_xfer (struct cinergyt2 *cinergyt2)

View file

@ -1135,8 +1135,7 @@ static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
dprintk("%s\n", __FUNCTION__);
for (i = 0; i < ISO_BUF_COUNT; i++)
if (dec->iso_urb[i])
usb_free_urb(dec->iso_urb[i]);
usb_free_urb(dec->iso_urb[i]);
pci_free_consistent(NULL,
ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *

View file

@ -1953,8 +1953,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
return hdw;
fail:
if (hdw) {
if (hdw->ctl_read_urb) usb_free_urb(hdw->ctl_read_urb);
if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb);
usb_free_urb(hdw->ctl_read_urb);
usb_free_urb(hdw->ctl_write_urb);
if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer);
if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer);
if (hdw->controls) kfree(hdw->controls);
@ -2575,12 +2575,10 @@ static void pvr2_ctl_timeout(unsigned long data)
struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
hdw->ctl_timeout_flag = !0;
if (hdw->ctl_write_pend_flag && hdw->ctl_write_urb) {
if (hdw->ctl_write_pend_flag)
usb_unlink_urb(hdw->ctl_write_urb);
}
if (hdw->ctl_read_pend_flag && hdw->ctl_read_urb) {
if (hdw->ctl_read_pend_flag)
usb_unlink_urb(hdw->ctl_read_urb);
}
}
}

View file

@ -289,7 +289,7 @@ static void pvr2_buffer_done(struct pvr2_buffer *bp)
pvr2_buffer_set_none(bp);
bp->signature = 0;
bp->stream = NULL;
if (bp->purb) usb_free_urb(bp->purb);
usb_free_urb(bp->purb);
pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/"
" bufferDone %p",bp);
}

View file

@ -866,11 +866,9 @@ int pwc_isoc_init(struct pwc_device *pdev)
}
if (ret) {
/* De-allocate in reverse order */
while (i >= 0) {
if (pdev->sbuf[i].urb != NULL)
usb_free_urb(pdev->sbuf[i].urb);
while (i--) {
usb_free_urb(pdev->sbuf[i].urb);
pdev->sbuf[i].urb = NULL;
i--;
}
return ret;
}

View file

@ -775,7 +775,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
return 0;
free_urbs:
for (i = 0; (i < SN9C102_URBS) && cam->urb[i]; i++)
for (i = 0; i < SN9C102_URBS; i++)
usb_free_urb(cam->urb[i]);
free_buffers:

View file

@ -190,8 +190,7 @@ static int qcm_alloc_int_urb(struct qcm *cam)
static void qcm_free_int(struct qcm *cam)
{
if (cam->button_urb)
usb_free_urb(cam->button_urb);
usb_free_urb(cam->button_urb);
}
#endif /* CONFIG_INPUT */

View file

@ -489,7 +489,7 @@ static int zc0301_start_transfer(struct zc0301_device* cam)
return 0;
free_urbs:
for (i = 0; (i < ZC0301_URBS) && cam->urb[i]; i++)
for (i = 0; i < ZC0301_URBS; i++)
usb_free_urb(cam->urb[i]);
free_buffers:

View file

@ -1793,10 +1793,8 @@ static int irda_usb_probe(struct usb_interface *intf,
err_out_2:
usb_free_urb(self->tx_urb);
err_out_1:
for (i = 0; i < self->max_rx_urb; i++) {
if (self->rx_urb[i])
usb_free_urb(self->rx_urb[i]);
}
for (i = 0; i < self->max_rx_urb; i++)
usb_free_urb(self->rx_urb[i]);
free_netdev(net);
err_out:
return ret;

View file

@ -1828,10 +1828,8 @@ static int zd1201_probe(struct usb_interface *interface,
/* Leave the device in reset state */
zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
err_zd:
if (zd->tx_urb)
usb_free_urb(zd->tx_urb);
if (zd->rx_urb)
usb_free_urb(zd->rx_urb);
usb_free_urb(zd->tx_urb);
usb_free_urb(zd->rx_urb);
kfree(zd);
return err;
}

View file

@ -834,8 +834,8 @@ static int speedtch_bind(struct usbatm_data *usbatm,
const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc;
if ((endpoint_desc->bEndpointAddress == target_address)) {
use_isoc = (endpoint_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_ISOC;
use_isoc =
usb_endpoint_xfer_isoc(endpoint_desc);
break;
}
}

View file

@ -401,9 +401,8 @@ static int uea_send_modem_cmd(struct usb_device *usb,
int ret = -ENOMEM;
u8 *xfer_buff;
xfer_buff = kmalloc(size, GFP_KERNEL);
xfer_buff = kmemdup(buff, size, GFP_KERNEL);
if (xfer_buff) {
memcpy(xfer_buff, buff, size);
ret = usb_control_msg(usb,
usb_sndctrlpipe(usb, 0),
LOAD_INTERNAL,
@ -595,14 +594,12 @@ static int uea_idma_write(struct uea_softc *sc, void *data, u32 size)
u8 *xfer_buff;
int bytes_read;
xfer_buff = kmalloc(size, GFP_KERNEL);
xfer_buff = kmemdup(data, size, GFP_KERNEL);
if (!xfer_buff) {
uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
return ret;
}
memcpy(xfer_buff, data, size);
ret = usb_bulk_msg(sc->usb_dev,
usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE),
xfer_buff, size, &bytes_read, BULK_TIMEOUT);
@ -765,12 +762,11 @@ static int uea_request(struct uea_softc *sc,
u8 *xfer_buff;
int ret = -ENOMEM;
xfer_buff = kmalloc(size, GFP_KERNEL);
xfer_buff = kmemdup(data, size, GFP_KERNEL);
if (!xfer_buff) {
uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
return ret;
}
memcpy(xfer_buff, data, size);
ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0),
UCDC_SEND_ENCAPSULATED_COMMAND,

View file

@ -892,7 +892,7 @@ static int acm_probe (struct usb_interface *intf,
/* workaround for switched endpoints */
if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) {
if (!usb_endpoint_dir_in(epread)) {
/* descriptors are swapped */
struct usb_endpoint_descriptor *t;
dev_dbg(&intf->dev,"The data interface has switched endpoints");

View file

@ -72,6 +72,21 @@ config USB_SUSPEND
If you are unsure about this, say N here.
config USB_MULTITHREAD_PROBE
bool "USB Multi-threaded probe (EXPERIMENTAL)"
depends on USB && EXPERIMENTAL
default n
help
Say Y here if you want the USB core to spawn a new thread for
every USB device that is probed. This can cause a small speedup
in boot times on systems with a lot of different USB devices.
This option should be safe to enable, but if any odd probing
problems are found, please disable it, or dynamically turn it
off in the /sys/module/usbcore/parameters/multithread_probe
file
When in doubt, say N.
config USB_OTG
bool

View file

@ -175,12 +175,13 @@ static char *usb_dump_endpoint_descriptor (
)
{
char dir, unit, *type;
unsigned interval, in, bandwidth = 1;
unsigned interval, bandwidth = 1;
if (start > end)
return start;
in = (desc->bEndpointAddress & USB_DIR_IN);
dir = in ? 'I' : 'O';
dir = usb_endpoint_dir_in(desc) ? 'I' : 'O';
if (speed == USB_SPEED_HIGH) {
switch (le16_to_cpu(desc->wMaxPacketSize) & (0x03 << 11)) {
case 1 << 11: bandwidth = 2; break;
@ -204,7 +205,7 @@ static char *usb_dump_endpoint_descriptor (
break;
case USB_ENDPOINT_XFER_BULK:
type = "Bulk";
if (speed == USB_SPEED_HIGH && !in) /* uframes per NAK */
if (speed == USB_SPEED_HIGH && dir == 'O') /* uframes per NAK */
interval = desc->bInterval;
else
interval = 0;

View file

@ -561,7 +561,7 @@ static int usbdev_open(struct inode *inode, struct file *file)
dev = inode->i_private;
if (!dev)
goto out;
ret = usb_autoresume_device(dev, 1);
ret = usb_autoresume_device(dev);
if (ret)
goto out;
@ -609,7 +609,7 @@ static int usbdev_release(struct inode *inode, struct file *file)
releaseintf(ps, ifnum);
}
destroy_all_async(ps);
usb_autosuspend_device(dev, 1);
usb_autosuspend_device(dev);
usb_unlock_device(dev);
usb_put_dev(dev);
put_pid(ps->disc_pid);

View file

@ -205,7 +205,7 @@ static int usb_probe_interface(struct device *dev)
if (id) {
dev_dbg(dev, "%s - got id\n", __FUNCTION__);
error = usb_autoresume_device(udev, 1);
error = usb_autoresume_device(udev);
if (error)
return error;
@ -229,7 +229,7 @@ static int usb_probe_interface(struct device *dev)
} else
intf->condition = USB_INTERFACE_BOUND;
usb_autosuspend_device(udev, 1);
usb_autosuspend_device(udev);
}
return error;
@ -247,7 +247,7 @@ static int usb_unbind_interface(struct device *dev)
/* Autoresume for set_interface call below */
udev = interface_to_usbdev(intf);
error = usb_autoresume_device(udev, 1);
error = usb_autoresume_device(udev);
/* release all urbs for this interface */
usb_disable_interface(interface_to_usbdev(intf), intf);
@ -265,7 +265,7 @@ static int usb_unbind_interface(struct device *dev)
intf->needs_remote_wakeup = 0;
if (!error)
usb_autosuspend_device(udev, 1);
usb_autosuspend_device(udev);
return 0;
}
@ -408,6 +408,16 @@ static int usb_match_one_id(struct usb_interface *interface,
(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
return 0;
/* The interface class, subclass, and protocol should never be
* checked for a match if the device class is Vendor Specific,
* unless the match record specifies the Vendor ID. */
if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
!(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
(id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS |
USB_DEVICE_ID_MATCH_INT_PROTOCOL)))
return 0;
if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
(id->bInterfaceClass != intf->desc.bInterfaceClass))
return 0;
@ -476,7 +486,17 @@ static int usb_match_one_id(struct usb_interface *interface,
* most general; they let drivers bind to any interface on a
* multiple-function device. Use the USB_INTERFACE_INFO
* macro, or its siblings, to match class-per-interface style
* devices (as recorded in bDeviceClass).
* devices (as recorded in bInterfaceClass).
*
* Note that an entry created by USB_INTERFACE_INFO won't match
* any interface if the device class is set to Vendor-Specific.
* This is deliberate; according to the USB spec the meanings of
* the interface class/subclass/protocol for these devices are also
* vendor-specific, and hence matching against a standard product
* class wouldn't work anyway. If you really want to use an
* interface-based match for such a device, create a match record
* that also specifies the vendor ID. (Unforunately there isn't a
* standard macro for creating records like this.)
*
* Within those groups, remember that not all combinations are
* meaningful. For example, don't give a product version range
@ -505,7 +525,7 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface,
}
EXPORT_SYMBOL_GPL_FUTURE(usb_match_id);
int usb_device_match(struct device *dev, struct device_driver *drv)
static int usb_device_match(struct device *dev, struct device_driver *drv)
{
/* devices and interfaces are handled separately */
if (is_usb_device(dev)) {
@ -790,7 +810,7 @@ EXPORT_SYMBOL_GPL_FUTURE(usb_deregister);
#ifdef CONFIG_PM
/* Caller has locked udev's pm_mutex */
static int suspend_device(struct usb_device *udev, pm_message_t msg)
static int usb_suspend_device(struct usb_device *udev, pm_message_t msg)
{
struct usb_device_driver *udriver;
int status = 0;
@ -817,7 +837,7 @@ static int suspend_device(struct usb_device *udev, pm_message_t msg)
}
/* Caller has locked udev's pm_mutex */
static int resume_device(struct usb_device *udev)
static int usb_resume_device(struct usb_device *udev)
{
struct usb_device_driver *udriver;
int status = 0;
@ -843,7 +863,7 @@ static int resume_device(struct usb_device *udev)
}
/* Caller has locked intf's usb_device's pm mutex */
static int suspend_interface(struct usb_interface *intf, pm_message_t msg)
static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
{
struct usb_driver *driver;
int status = 0;
@ -880,7 +900,7 @@ static int suspend_interface(struct usb_interface *intf, pm_message_t msg)
}
/* Caller has locked intf's usb_device's pm_mutex */
static int resume_interface(struct usb_interface *intf)
static int usb_resume_interface(struct usb_interface *intf)
{
struct usb_driver *driver;
int status = 0;
@ -920,6 +940,44 @@ static int resume_interface(struct usb_interface *intf)
return status;
}
#ifdef CONFIG_USB_SUSPEND
/* Internal routine to check whether we may autosuspend a device. */
static int autosuspend_check(struct usb_device *udev)
{
int i;
struct usb_interface *intf;
/* For autosuspend, fail fast if anything is in use.
* Also fail if any interfaces require remote wakeup but it
* isn't available. */
udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
if (udev->pm_usage_cnt > 0)
return -EBUSY;
if (udev->actconfig) {
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
intf = udev->actconfig->interface[i];
if (!is_active(intf))
continue;
if (intf->pm_usage_cnt > 0)
return -EBUSY;
if (intf->needs_remote_wakeup &&
!udev->do_remote_wakeup) {
dev_dbg(&udev->dev, "remote wakeup needed "
"for autosuspend\n");
return -EOPNOTSUPP;
}
}
}
return 0;
}
#else
#define autosuspend_check(udev) 0
#endif
/**
* usb_suspend_both - suspend a USB device and its interfaces
* @udev: the usb_device to suspend
@ -971,52 +1029,34 @@ int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
/* For autosuspend, fail fast if anything is in use.
* Also fail if any interfaces require remote wakeup but it
* isn't available. */
if (udev->auto_pm) {
if (udev->pm_usage_cnt > 0)
return -EBUSY;
if (udev->actconfig) {
for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
intf = udev->actconfig->interface[i];
if (!is_active(intf))
continue;
if (intf->pm_usage_cnt > 0)
return -EBUSY;
if (intf->needs_remote_wakeup &&
!udev->do_remote_wakeup) {
dev_dbg(&udev->dev,
"remote wakeup needed for autosuspend\n");
return -EOPNOTSUPP;
}
}
i = 0;
}
status = autosuspend_check(udev);
if (status < 0)
return status;
}
/* Suspend all the interfaces and then udev itself */
if (udev->actconfig) {
for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
intf = udev->actconfig->interface[i];
status = suspend_interface(intf, msg);
status = usb_suspend_interface(intf, msg);
if (status != 0)
break;
}
}
if (status == 0)
status = suspend_device(udev, msg);
status = usb_suspend_device(udev, msg);
/* If the suspend failed, resume interfaces that did get suspended */
if (status != 0) {
while (--i >= 0) {
intf = udev->actconfig->interface[i];
resume_interface(intf);
usb_resume_interface(intf);
}
/* If the suspend succeeded, propagate it up the tree */
} else if (parent)
usb_autosuspend_device(parent, 0);
usb_autosuspend_device(parent);
// dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
return status;
@ -1064,9 +1104,25 @@ int usb_resume_both(struct usb_device *udev)
/* Propagate the resume up the tree, if necessary */
if (udev->state == USB_STATE_SUSPENDED) {
if (parent) {
usb_pm_lock(parent);
parent->auto_pm = 1;
status = usb_resume_both(parent);
status = usb_autoresume_device(parent);
if (status == 0) {
status = usb_resume_device(udev);
if (status) {
usb_autosuspend_device(parent);
/* It's possible usb_resume_device()
* failed after the port was
* unsuspended, causing udev to be
* logically disconnected. We don't
* want usb_disconnect() to autosuspend
* the parent again, so tell it that
* udev disconnected while still
* suspended. */
if (udev->state ==
USB_STATE_NOTATTACHED)
udev->discon_suspended = 1;
}
}
} else {
/* We can't progagate beyond the USB subsystem,
@ -1075,24 +1131,20 @@ int usb_resume_both(struct usb_device *udev)
if (udev->dev.parent->power.power_state.event !=
PM_EVENT_ON)
status = -EHOSTUNREACH;
}
if (status == 0)
status = resume_device(udev);
if (parent)
usb_pm_unlock(parent);
else
status = usb_resume_device(udev);
}
} else {
/* Needed only for setting udev->dev.power.power_state.event
* and for possible debugging message. */
status = resume_device(udev);
status = usb_resume_device(udev);
}
/* Now the parent won't suspend until we are finished */
if (status == 0 && udev->actconfig) {
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
intf = udev->actconfig->interface[i];
resume_interface(intf);
usb_resume_interface(intf);
}
}
@ -1102,39 +1154,53 @@ int usb_resume_both(struct usb_device *udev)
#ifdef CONFIG_USB_SUSPEND
/* Internal routine to adjust a device's usage counter and change
* its autosuspend state.
*/
static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
{
int status = 0;
usb_pm_lock(udev);
udev->pm_usage_cnt += inc_usage_cnt;
WARN_ON(udev->pm_usage_cnt < 0);
if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) {
udev->auto_pm = 1;
status = usb_resume_both(udev);
if (status != 0)
udev->pm_usage_cnt -= inc_usage_cnt;
} else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0)
queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
USB_AUTOSUSPEND_DELAY);
usb_pm_unlock(udev);
return status;
}
/**
* usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces
* @udev: the usb_device to autosuspend
* @dec_usage_cnt: flag to decrement @udev's PM-usage counter
*
* This routine should be called when a core subsystem is finished using
* @udev and wants to allow it to autosuspend. Examples would be when
* @udev's device file in usbfs is closed or after a configuration change.
*
* @dec_usage_cnt should be 1 if the subsystem previously incremented
* @udev's usage counter (such as by passing 1 to usb_autoresume_device);
* otherwise it should be 0.
*
* If the usage counter for @udev or any of its active interfaces is greater
* than 0, the autosuspend request will not be queued. (If an interface
* driver does not support autosuspend then its usage counter is permanently
* positive.) Likewise, if an interface driver requires remote-wakeup
* capability during autosuspend but remote wakeup is disabled, the
* autosuspend will fail.
* @udev's usage counter is decremented. If it or any of the usage counters
* for an active interface is greater than 0, no autosuspend request will be
* queued. (If an interface driver does not support autosuspend then its
* usage counter is permanently positive.) Furthermore, if an interface
* driver requires remote-wakeup capability during autosuspend but remote
* wakeup is disabled, the autosuspend will fail.
*
* Often the caller will hold @udev's device lock, but this is not
* necessary.
*
* This routine can run only in process context.
*/
void usb_autosuspend_device(struct usb_device *udev, int dec_usage_cnt)
void usb_autosuspend_device(struct usb_device *udev)
{
usb_pm_lock(udev);
udev->pm_usage_cnt -= dec_usage_cnt;
if (udev->pm_usage_cnt <= 0)
queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
USB_AUTOSUSPEND_DELAY);
usb_pm_unlock(udev);
int status;
status = usb_autopm_do_device(udev, -1);
// dev_dbg(&udev->dev, "%s: cnt %d\n",
// __FUNCTION__, udev->pm_usage_cnt);
}
@ -1142,44 +1208,59 @@ void usb_autosuspend_device(struct usb_device *udev, int dec_usage_cnt)
/**
* usb_autoresume_device - immediately autoresume a USB device and its interfaces
* @udev: the usb_device to autoresume
* @inc_usage_cnt: flag to increment @udev's PM-usage counter
*
* This routine should be called when a core subsystem wants to use @udev
* and needs to guarantee that it is not suspended. In addition, the
* caller can prevent @udev from being autosuspended subsequently. (Note
* that this will not prevent suspend events originating in the PM core.)
* Examples would be when @udev's device file in usbfs is opened (autosuspend
* should be prevented until the file is closed) or when a remote-wakeup
* request is received (later autosuspends should not be prevented).
* and needs to guarantee that it is not suspended. No autosuspend will
* occur until usb_autosuspend_device is called. (Note that this will not
* prevent suspend events originating in the PM core.) Examples would be
* when @udev's device file in usbfs is opened or when a remote-wakeup
* request is received.
*
* @inc_usage_cnt should be 1 to increment @udev's usage counter and prevent
* autosuspends. This prevention will persist until the usage counter is
* decremented again (such as by passing 1 to usb_autosuspend_device).
* Otherwise @inc_usage_cnt should be 0 to leave the usage counter unchanged.
* Regardless, if the autoresume fails then the usage counter is not
* incremented.
* @udev's usage counter is incremented to prevent subsequent autosuspends.
* However if the autoresume fails then the usage counter is re-decremented.
*
* Often the caller will hold @udev's device lock, but this is not
* necessary (and attempting it might cause deadlock).
*
* This routine can run only in process context.
*/
int usb_autoresume_device(struct usb_device *udev, int inc_usage_cnt)
int usb_autoresume_device(struct usb_device *udev)
{
int status;
usb_pm_lock(udev);
udev->pm_usage_cnt += inc_usage_cnt;
udev->auto_pm = 1;
status = usb_resume_both(udev);
if (status != 0)
udev->pm_usage_cnt -= inc_usage_cnt;
usb_pm_unlock(udev);
status = usb_autopm_do_device(udev, 1);
// dev_dbg(&udev->dev, "%s: status %d cnt %d\n",
// __FUNCTION__, status, udev->pm_usage_cnt);
return status;
}
/* Internal routine to adjust an interface's usage counter and change
* its device's autosuspend state.
*/
static int usb_autopm_do_interface(struct usb_interface *intf,
int inc_usage_cnt)
{
struct usb_device *udev = interface_to_usbdev(intf);
int status = 0;
usb_pm_lock(udev);
if (intf->condition == USB_INTERFACE_UNBOUND)
status = -ENODEV;
else {
intf->pm_usage_cnt += inc_usage_cnt;
if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) {
udev->auto_pm = 1;
status = usb_resume_both(udev);
if (status != 0)
intf->pm_usage_cnt -= inc_usage_cnt;
} else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0)
queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
USB_AUTOSUSPEND_DELAY);
}
usb_pm_unlock(udev);
return status;
}
/**
* usb_autopm_put_interface - decrement a USB interface's PM-usage counter
* @intf: the usb_interface whose counter should be decremented
@ -1213,17 +1294,11 @@ int usb_autoresume_device(struct usb_device *udev, int inc_usage_cnt)
*/
void usb_autopm_put_interface(struct usb_interface *intf)
{
struct usb_device *udev = interface_to_usbdev(intf);
int status;
usb_pm_lock(udev);
if (intf->condition != USB_INTERFACE_UNBOUND &&
--intf->pm_usage_cnt <= 0) {
queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
USB_AUTOSUSPEND_DELAY);
}
usb_pm_unlock(udev);
// dev_dbg(&intf->dev, "%s: cnt %d\n",
// __FUNCTION__, intf->pm_usage_cnt);
status = usb_autopm_do_interface(intf, -1);
// dev_dbg(&intf->dev, "%s: status %d cnt %d\n",
// __FUNCTION__, status, intf->pm_usage_cnt);
}
EXPORT_SYMBOL_GPL(usb_autopm_put_interface);
@ -1260,26 +1335,37 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface);
*/
int usb_autopm_get_interface(struct usb_interface *intf)
{
struct usb_device *udev = interface_to_usbdev(intf);
int status;
int status;
usb_pm_lock(udev);
if (intf->condition == USB_INTERFACE_UNBOUND)
status = -ENODEV;
else {
++intf->pm_usage_cnt;
udev->auto_pm = 1;
status = usb_resume_both(udev);
if (status != 0)
--intf->pm_usage_cnt;
}
usb_pm_unlock(udev);
status = usb_autopm_do_interface(intf, 1);
// dev_dbg(&intf->dev, "%s: status %d cnt %d\n",
// __FUNCTION__, status, intf->pm_usage_cnt);
return status;
}
EXPORT_SYMBOL_GPL(usb_autopm_get_interface);
/**
* usb_autopm_set_interface - set a USB interface's autosuspend state
* @intf: the usb_interface whose state should be set
*
* This routine sets the autosuspend state of @intf's device according
* to @intf's usage counter, which the caller must have set previously.
* If the counter is <= 0, the device is autosuspended (if it isn't
* already suspended and if nothing else prevents the autosuspend). If
* the counter is > 0, the device is autoresumed (if it isn't already
* awake).
*/
int usb_autopm_set_interface(struct usb_interface *intf)
{
int status;
status = usb_autopm_do_interface(intf, 0);
// dev_dbg(&intf->dev, "%s: status %d cnt %d\n",
// __FUNCTION__, status, intf->pm_usage_cnt);
return status;
}
EXPORT_SYMBOL_GPL(usb_autopm_set_interface);
#endif /* CONFIG_USB_SUSPEND */
static int usb_suspend(struct device *dev, pm_message_t message)

View file

@ -10,15 +10,20 @@
*/
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/idr.h>
#include <linux/usb.h>
#include "usb.h"
/* endpoint stuff */
#define MAX_ENDPOINT_MINORS (64*128*32)
static int usb_endpoint_major;
static DEFINE_IDR(endpoint_idr);
struct ep_device {
struct usb_endpoint_descriptor *desc;
struct usb_device *udev;
struct device dev;
int minor;
};
#define to_ep_device(_dev) \
container_of(_dev, struct ep_device, dev)
@ -152,6 +157,55 @@ static struct attribute_group ep_dev_attr_grp = {
.attrs = ep_dev_attrs,
};
static int usb_endpoint_major_init(void)
{
dev_t dev;
int error;
error = alloc_chrdev_region(&dev, 0, MAX_ENDPOINT_MINORS,
"usb_endpoint");
if (error) {
err("unable to get a dynamic major for usb endpoints");
return error;
}
usb_endpoint_major = MAJOR(dev);
return error;
}
static void usb_endpoint_major_cleanup(void)
{
unregister_chrdev_region(MKDEV(usb_endpoint_major, 0),
MAX_ENDPOINT_MINORS);
}
static int endpoint_get_minor(struct ep_device *ep_dev)
{
static DEFINE_MUTEX(minor_lock);
int retval = -ENOMEM;
int id;
mutex_lock(&minor_lock);
if (idr_pre_get(&endpoint_idr, GFP_KERNEL) == 0)
goto exit;
retval = idr_get_new(&endpoint_idr, ep_dev, &id);
if (retval < 0) {
if (retval == -EAGAIN)
retval = -ENOMEM;
goto exit;
}
ep_dev->minor = id & MAX_ID_MASK;
exit:
mutex_unlock(&minor_lock);
return retval;
}
static void endpoint_free_minor(struct ep_device *ep_dev)
{
idr_remove(&endpoint_idr, ep_dev->minor);
}
static struct endpoint_class {
struct kref kref;
struct class *class;
@ -176,11 +230,20 @@ static int init_endpoint_class(void)
ep_class->class = class_create(THIS_MODULE, "usb_endpoint");
if (IS_ERR(ep_class->class)) {
result = IS_ERR(ep_class->class);
kfree(ep_class);
ep_class = NULL;
goto exit;
goto class_create_error;
}
result = usb_endpoint_major_init();
if (result)
goto endpoint_major_error;
goto exit;
endpoint_major_error:
class_destroy(ep_class->class);
class_create_error:
kfree(ep_class);
ep_class = NULL;
exit:
return result;
}
@ -191,6 +254,7 @@ static void release_endpoint_class(struct kref *kref)
class_destroy(ep_class->class);
kfree(ep_class);
ep_class = NULL;
usb_endpoint_major_cleanup();
}
static void destroy_endpoint_class(void)
@ -213,7 +277,6 @@ int usb_create_ep_files(struct device *parent,
{
char name[8];
struct ep_device *ep_dev;
int minor;
int retval;
retval = init_endpoint_class();
@ -226,12 +289,16 @@ int usb_create_ep_files(struct device *parent,
goto error_alloc;
}
/* fun calculation to determine the minor of this endpoint */
minor = (((udev->bus->busnum - 1) * 128) * 16) + (udev->devnum - 1);
retval = endpoint_get_minor(ep_dev);
if (retval) {
dev_err(parent, "can not allocate minor number for %s",
ep_dev->dev.bus_id);
goto error_register;
}
ep_dev->desc = &endpoint->desc;
ep_dev->udev = udev;
ep_dev->dev.devt = MKDEV(442, minor); // FIXME fake number...
ep_dev->dev.devt = MKDEV(usb_endpoint_major, ep_dev->minor);
ep_dev->dev.class = ep_class->class;
ep_dev->dev.parent = parent;
ep_dev->dev.release = ep_device_release;
@ -241,7 +308,7 @@ int usb_create_ep_files(struct device *parent,
retval = device_register(&ep_dev->dev);
if (retval)
goto error_register;
goto error_chrdev;
retval = sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
if (retval)
goto error_group;
@ -261,6 +328,9 @@ int usb_create_ep_files(struct device *parent,
destroy_endpoint_class();
return retval;
error_chrdev:
endpoint_free_minor(ep_dev);
error_register:
kfree(ep_dev);
error_alloc:
@ -271,14 +341,16 @@ int usb_create_ep_files(struct device *parent,
void usb_remove_ep_files(struct usb_host_endpoint *endpoint)
{
struct ep_device *ep_dev = endpoint->ep_dev;
if (endpoint->ep_dev) {
if (ep_dev) {
char name[8];
sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress);
sysfs_remove_link(&endpoint->ep_dev->dev.parent->kobj, name);
sysfs_remove_group(&endpoint->ep_dev->dev.kobj, &ep_dev_attr_grp);
device_unregister(&endpoint->ep_dev->dev);
sysfs_remove_link(&ep_dev->dev.parent->kobj, name);
sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
endpoint_free_minor(ep_dev);
device_unregister(&ep_dev->dev);
endpoint->ep_dev = NULL;
destroy_endpoint_class();
}

View file

@ -256,7 +256,9 @@ static const u8 hs_rh_config_descriptor [] = {
0x05, /* __u8 ep_bDescriptorType; Endpoint */
0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
0x03, /* __u8 ep_bmAttributes; Interrupt */
0x02, 0x00, /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
/* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
* see hub.c:hub_configure() for details. */
(USB_MAXCHILDREN + 1 + 7) / 8, 0x00,
0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */
};

View file

@ -31,6 +31,47 @@
#include "hcd.h"
#include "hub.h"
struct usb_hub {
struct device *intfdev; /* the "interface" device */
struct usb_device *hdev;
struct urb *urb; /* for interrupt polling pipe */
/* buffer for urb ... with extra space in case of babble */
char (*buffer)[8];
dma_addr_t buffer_dma; /* DMA address for buffer */
union {
struct usb_hub_status hub;
struct usb_port_status port;
} *status; /* buffer for status reports */
int error; /* last reported error */
int nerrors; /* track consecutive errors */
struct list_head event_list; /* hubs w/data or errs ready */
unsigned long event_bits[1]; /* status change bitmask */
unsigned long change_bits[1]; /* ports with logical connect
status change */
unsigned long busy_bits[1]; /* ports being reset or
resumed */
#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
#error event_bits[] is too short!
#endif
struct usb_hub_descriptor *descriptor; /* class descriptor */
struct usb_tt tt; /* Transaction Translator */
unsigned mA_per_port; /* current for each child */
unsigned limited_power:1;
unsigned quiescing:1;
unsigned activating:1;
unsigned has_indicators:1;
u8 indicator[USB_MAXCHILDREN];
struct work_struct leds;
};
/* Protect struct usb_device->state and ->children members
* Note: Both are also protected by ->dev.sem, except that ->state can
* change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
@ -45,6 +86,16 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
static struct task_struct *khubd_task;
/* multithreaded probe logic */
static int multithread_probe =
#ifdef CONFIG_USB_MULTITHREAD_PROBE
1;
#else
0;
#endif
module_param(multithread_probe, bool, S_IRUGO);
MODULE_PARM_DESC(multithread_probe, "Run each USB device probe in a new thread");
/* cycle leds on hubs that aren't blinking for attention */
static int blinkenlights = 0;
module_param (blinkenlights, bool, S_IRUGO);
@ -276,6 +327,9 @@ static void kick_khubd(struct usb_hub *hub)
{
unsigned long flags;
/* Suppress autosuspend until khubd runs */
to_usb_interface(hub->intfdev)->pm_usage_cnt = 1;
spin_lock_irqsave(&hub_event_lock, flags);
if (list_empty(&hub->event_list)) {
list_add_tail(&hub->event_list, &hub_event_list);
@ -457,7 +511,6 @@ static void hub_quiesce(struct usb_hub *hub)
/* (nonblocking) khubd and related activity won't re-trigger */
hub->quiescing = 1;
hub->activating = 0;
hub->resume_root_hub = 0;
/* (blocking) stop khubd and related activity */
usb_kill_urb(hub->urb);
@ -473,7 +526,7 @@ static void hub_activate(struct usb_hub *hub)
hub->quiescing = 0;
hub->activating = 1;
hub->resume_root_hub = 0;
status = usb_submit_urb(hub->urb, GFP_NOIO);
if (status < 0)
dev_err(hub->intfdev, "activate --> %d\n", status);
@ -759,7 +812,12 @@ static int hub_configure(struct usb_hub *hub,
dev_dbg(hub_dev, "%sover-current condition exists\n",
(hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
/* set up the interrupt endpoint */
/* set up the interrupt endpoint
* We use the EP's maxpacket size instead of (PORTS+1+7)/8
* bytes as USB2.0[11.12.3] says because some hubs are known
* to send more data (and thus cause overflow). For root hubs,
* maxpktsize is defined in hcd.c's fake endpoint descriptors
* to be big enough for at least USB_MAXCHILDREN ports. */
pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(hdev, pipe, usb_pipeout(pipe));
@ -883,6 +941,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
INIT_WORK(&hub->leds, led_work, hub);
usb_set_intfdata (intf, hub);
intf->needs_remote_wakeup = 1;
if (hdev->speed == USB_SPEED_HIGH)
highspeed_hubs++;
@ -980,6 +1039,8 @@ static void recursively_mark_NOTATTACHED(struct usb_device *udev)
if (udev->children[i])
recursively_mark_NOTATTACHED(udev->children[i]);
}
if (udev->state == USB_STATE_SUSPENDED)
udev->discon_suspended = 1;
udev->state = USB_STATE_NOTATTACHED;
}
@ -1169,6 +1230,14 @@ void usb_disconnect(struct usb_device **pdev)
*pdev = NULL;
spin_unlock_irq(&device_state_lock);
/* Decrement the parent's count of unsuspended children */
if (udev->parent) {
usb_pm_lock(udev);
if (!udev->discon_suspended)
usb_autosuspend_device(udev->parent);
usb_pm_unlock(udev);
}
put_device(&udev->dev);
}
@ -1191,29 +1260,17 @@ static inline void show_string(struct usb_device *udev, char *id, char *string)
static int __usb_port_suspend(struct usb_device *, int port1);
#endif
/**
* usb_new_device - perform initial device setup (usbcore-internal)
* @udev: newly addressed device (in ADDRESS state)
*
* This is called with devices which have been enumerated, but not yet
* configured. The device descriptor is available, but not descriptors
* for any device configuration. The caller must have locked either
* the parent hub (if udev is a normal device) or else the
* usb_bus_list_lock (if udev is a root hub). The parent's pointer to
* udev has already been installed, but udev is not yet visible through
* sysfs or other filesystem code.
*
* Returns 0 for success (device is configured and listed, with its
* interfaces, in sysfs); else a negative errno value.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Only the hub driver or root-hub registrar should ever call this.
*/
int usb_new_device(struct usb_device *udev)
static int __usb_new_device(void *void_data)
{
struct usb_device *udev = void_data;
int err;
/* Lock ourself into memory in order to keep a probe sequence
* sleeping in a new thread from allowing us to be unloaded.
*/
if (!try_module_get(THIS_MODULE))
return -EINVAL;
err = usb_get_configuration(udev);
if (err < 0) {
dev_err(&udev->dev, "can't read configurations, error %d\n",
@ -1309,13 +1366,56 @@ int usb_new_device(struct usb_device *udev)
goto fail;
}
return 0;
/* Increment the parent's count of unsuspended children */
if (udev->parent)
usb_autoresume_device(udev->parent);
exit:
module_put(THIS_MODULE);
return err;
fail:
usb_set_device_state(udev, USB_STATE_NOTATTACHED);
return err;
goto exit;
}
/**
* usb_new_device - perform initial device setup (usbcore-internal)
* @udev: newly addressed device (in ADDRESS state)
*
* This is called with devices which have been enumerated, but not yet
* configured. The device descriptor is available, but not descriptors
* for any device configuration. The caller must have locked either
* the parent hub (if udev is a normal device) or else the
* usb_bus_list_lock (if udev is a root hub). The parent's pointer to
* udev has already been installed, but udev is not yet visible through
* sysfs or other filesystem code.
*
* The return value for this function depends on if the
* multithread_probe variable is set or not. If it's set, it will
* return a if the probe thread was successfully created or not. If the
* variable is not set, it will return if the device is configured
* properly or not. interfaces, in sysfs); else a negative errno value.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Only the hub driver or root-hub registrar should ever call this.
*/
int usb_new_device(struct usb_device *udev)
{
struct task_struct *probe_task;
int ret = 0;
if (multithread_probe) {
probe_task = kthread_run(__usb_new_device, udev,
"usb-probe-%s", udev->devnum);
if (IS_ERR(probe_task))
ret = PTR_ERR(probe_task);
} else
ret = __usb_new_device(udev);
return ret;
}
static int hub_port_status(struct usb_hub *hub, int port1,
u16 *status, u16 *change)
@ -1323,10 +1423,12 @@ static int hub_port_status(struct usb_hub *hub, int port1,
int ret;
ret = get_port_status(hub->hdev, port1, &hub->status->port);
if (ret < 0)
if (ret < 4) {
dev_err (hub->intfdev,
"%s failed (err = %d)\n", __FUNCTION__, ret);
else {
if (ret >= 0)
ret = -EIO;
} else {
*status = le16_to_cpu(hub->status->port.wPortStatus);
*change = le16_to_cpu(hub->status->port.wPortChange);
ret = 0;
@ -1674,6 +1776,12 @@ static int
hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
{
int status;
u16 portchange, portstatus;
/* Skip the initial Clear-Suspend step for a remote wakeup */
status = hub_port_status(hub, port1, &portstatus, &portchange);
if (status == 0 && !(portstatus & USB_PORT_STAT_SUSPEND))
goto SuspendCleared;
// dev_dbg(hub->intfdev, "resume port %d\n", port1);
@ -1687,9 +1795,6 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
"can't resume port %d, status %d\n",
port1, status);
} else {
u16 devstatus;
u16 portchange;
/* drive resume for at least 20 msec */
if (udev)
dev_dbg(&udev->dev, "usb %sresume\n",
@ -1704,16 +1809,15 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
* stop resume signaling. Then finish the resume
* sequence.
*/
devstatus = portchange = 0;
status = hub_port_status(hub, port1,
&devstatus, &portchange);
status = hub_port_status(hub, port1, &portstatus, &portchange);
SuspendCleared:
if (status < 0
|| (devstatus & LIVE_FLAGS) != LIVE_FLAGS
|| (devstatus & USB_PORT_STAT_SUSPEND) != 0
|| (portstatus & LIVE_FLAGS) != LIVE_FLAGS
|| (portstatus & USB_PORT_STAT_SUSPEND) != 0
) {
dev_dbg(hub->intfdev,
"port %d status %04x.%04x after resume, %d\n",
port1, portchange, devstatus, status);
port1, portchange, portstatus, status);
if (status >= 0)
status = -ENODEV;
} else {
@ -1774,23 +1878,16 @@ static int remote_wakeup(struct usb_device *udev)
{
int status = 0;
/* All this just to avoid sending a port-resume message
* to the parent hub! */
usb_lock_device(udev);
usb_pm_lock(udev);
if (udev->state == USB_STATE_SUSPENDED) {
dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");
/* TRSMRCY = 10 msec */
msleep(10);
status = finish_port_resume(udev);
if (status == 0)
udev->dev.power.power_state.event = PM_EVENT_ON;
}
usb_pm_unlock(udev);
status = usb_autoresume_device(udev);
if (status == 0)
usb_autoresume_device(udev, 0);
/* Give the interface drivers a chance to do something,
* then autosuspend the device again. */
if (status == 0)
usb_autosuspend_device(udev);
}
usb_unlock_device(udev);
return status;
}
@ -1854,6 +1951,8 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
}
}
dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
/* "global suspend" of the downstream HC-to-USB interface */
if (!hdev->parent) {
struct usb_bus *bus = hdev->bus;
@ -1876,10 +1975,12 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
static int hub_resume(struct usb_interface *intf)
{
struct usb_device *hdev = interface_to_usbdev(intf);
struct usb_hub *hub = usb_get_intfdata (intf);
struct usb_device *hdev = hub->hdev;
int status;
dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
/* "global resume" of the downstream HC-to-USB interface */
if (!hdev->parent) {
struct usb_bus *bus = hdev->bus;
@ -1918,7 +2019,6 @@ void usb_resume_root_hub(struct usb_device *hdev)
{
struct usb_hub *hub = hdev_to_hub(hdev);
hub->resume_root_hub = 1;
kick_khubd(hub);
}
@ -2555,16 +2655,13 @@ static void hub_events(void)
intf = to_usb_interface(hub->intfdev);
hub_dev = &intf->dev;
i = hub->resume_root_hub;
dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x%s\n",
dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
hdev->state, hub->descriptor
? hub->descriptor->bNbrPorts
: 0,
/* NOTE: expects max 15 ports... */
(u16) hub->change_bits[0],
(u16) hub->event_bits[0],
i ? ", resume root" : "");
(u16) hub->event_bits[0]);
usb_get_intf(intf);
spin_unlock_irq(&hub_event_lock);
@ -2585,16 +2682,16 @@ static void hub_events(void)
goto loop;
}
/* Is this is a root hub wanting to reactivate the downstream
* ports? If so, be sure the interface resumes even if its
* stub "device" node was never suspended.
*/
if (i)
usb_autoresume_device(hdev, 0);
/* If this is an inactive or suspended hub, do nothing */
if (hub->quiescing)
/* Autoresume */
ret = usb_autopm_get_interface(intf);
if (ret) {
dev_dbg(hub_dev, "Can't autoresume: %d\n", ret);
goto loop;
}
/* If this is an inactive hub, do nothing */
if (hub->quiescing)
goto loop_autopm;
if (hub->error) {
dev_dbg (hub_dev, "resetting for error %d\n",
@ -2604,7 +2701,7 @@ static void hub_events(void)
if (ret) {
dev_dbg (hub_dev,
"error resetting hub: %d\n", ret);
goto loop;
goto loop_autopm;
}
hub->nerrors = 0;
@ -2732,6 +2829,10 @@ static void hub_events(void)
if (!hdev->parent && !hub->busy_bits[0])
usb_enable_root_hub_irq(hdev->bus);
loop_autopm:
/* Allow autosuspend if we're not going to run again */
if (list_empty(&hub->event_list))
usb_autopm_enable(intf);
loop:
usb_unlock_device(hdev);
usb_put_intf(intf);
@ -2773,6 +2874,7 @@ static struct usb_driver hub_driver = {
.post_reset = hub_post_reset,
.ioctl = hub_ioctl,
.id_table = hub_id_table,
.supports_autosuspend = 1,
};
int usb_hub_init(void)
@ -2997,7 +3099,7 @@ int usb_reset_composite_device(struct usb_device *udev,
}
/* Prevent autosuspend during the reset */
usb_autoresume_device(udev, 1);
usb_autoresume_device(udev);
if (iface && iface->condition != USB_INTERFACE_BINDING)
iface = NULL;
@ -3040,7 +3142,7 @@ int usb_reset_composite_device(struct usb_device *udev,
}
}
usb_autosuspend_device(udev, 1);
usb_autosuspend_device(udev);
return ret;
}
EXPORT_SYMBOL(usb_reset_composite_device);

View file

@ -192,45 +192,4 @@ struct usb_tt_clear {
extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe);
struct usb_hub {
struct device *intfdev; /* the "interface" device */
struct usb_device *hdev;
struct urb *urb; /* for interrupt polling pipe */
/* buffer for urb ... with extra space in case of babble */
char (*buffer)[8];
dma_addr_t buffer_dma; /* DMA address for buffer */
union {
struct usb_hub_status hub;
struct usb_port_status port;
} *status; /* buffer for status reports */
int error; /* last reported error */
int nerrors; /* track consecutive errors */
struct list_head event_list; /* hubs w/data or errs ready */
unsigned long event_bits[1]; /* status change bitmask */
unsigned long change_bits[1]; /* ports with logical connect
status change */
unsigned long busy_bits[1]; /* ports being reset or
resumed */
#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
#error event_bits[] is too short!
#endif
struct usb_hub_descriptor *descriptor; /* class descriptor */
struct usb_tt tt; /* Transaction Translator */
unsigned mA_per_port; /* current for each child */
unsigned limited_power:1;
unsigned quiescing:1;
unsigned activating:1;
unsigned resume_root_hub:1;
unsigned has_indicators:1;
enum hub_led_mode indicator[USB_MAXCHILDREN];
struct work_struct leds;
};
#endif /* __LINUX_HUB_H */

View file

@ -764,7 +764,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
err = -EINVAL;
goto errout;
} else {
dev->have_langid = -1;
dev->have_langid = 1;
dev->string_langid = tbuf[2] | (tbuf[3]<< 8);
/* always use the first langid listed */
dev_dbg (&dev->dev, "default language 0x%04x\n",
@ -1398,7 +1398,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
}
/* Wake up the device so we can send it the Set-Config request */
ret = usb_autoresume_device(dev, 1);
ret = usb_autoresume_device(dev);
if (ret)
goto free_interfaces;
@ -1421,7 +1421,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
dev->actconfig = cp;
if (!cp) {
usb_set_device_state(dev, USB_STATE_ADDRESS);
usb_autosuspend_device(dev, 1);
usb_autosuspend_device(dev);
goto free_interfaces;
}
usb_set_device_state(dev, USB_STATE_CONFIGURED);
@ -1490,7 +1490,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
usb_create_sysfs_intf_files (intf);
}
usb_autosuspend_device(dev, 1);
usb_autosuspend_device(dev);
return 0;
}

View file

@ -200,13 +200,6 @@ static void ksuspend_usb_cleanup(void)
destroy_workqueue(ksuspend_usb_wq);
}
#else
#define ksuspend_usb_init() 0
#define ksuspend_usb_cleanup() do {} while (0)
#endif
#ifdef CONFIG_USB_SUSPEND
/* usb_autosuspend_work - callback routine to autosuspend a USB device */
@ -225,7 +218,14 @@ static void usb_autosuspend_work(void *_udev)
static void usb_autosuspend_work(void *_udev)
{}
#endif
#endif /* CONFIG_USB_SUSPEND */
#else
#define ksuspend_usb_init() 0
#define ksuspend_usb_cleanup() do {} while (0)
#endif /* CONFIG_PM */
/**
* usb_alloc_dev - usb device constructor (usbcore-internal)
@ -537,138 +537,6 @@ int usb_get_current_frame_number(struct usb_device *dev)
return usb_hcd_get_frame_number (dev);
}
/**
* usb_endpoint_dir_in - check if the endpoint has IN direction
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type IN, otherwise it returns false.
*/
int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
}
/**
* usb_endpoint_dir_out - check if the endpoint has OUT direction
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type OUT, otherwise it returns false.
*/
int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
}
/**
* usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type bulk, otherwise it returns false.
*/
int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_BULK);
}
/**
* usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type interrupt, otherwise it returns
* false.
*/
int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_INT);
}
/**
* usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type isochronous, otherwise it returns
* false.
*/
int usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_ISOC);
}
/**
* usb_endpoint_is_bulk_in - check if the endpoint is bulk IN
* @epd: endpoint to be checked
*
* Returns true if the endpoint has bulk transfer type and IN direction,
* otherwise it returns false.
*/
int usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd));
}
/**
* usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT
* @epd: endpoint to be checked
*
* Returns true if the endpoint has bulk transfer type and OUT direction,
* otherwise it returns false.
*/
int usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd));
}
/**
* usb_endpoint_is_int_in - check if the endpoint is interrupt IN
* @epd: endpoint to be checked
*
* Returns true if the endpoint has interrupt transfer type and IN direction,
* otherwise it returns false.
*/
int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd));
}
/**
* usb_endpoint_is_int_out - check if the endpoint is interrupt OUT
* @epd: endpoint to be checked
*
* Returns true if the endpoint has interrupt transfer type and OUT direction,
* otherwise it returns false.
*/
int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd));
}
/**
* usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN
* @epd: endpoint to be checked
*
* Returns true if the endpoint has isochronous transfer type and IN direction,
* otherwise it returns false.
*/
int usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd));
}
/**
* usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT
* @epd: endpoint to be checked
*
* Returns true if the endpoint has isochronous transfer type and OUT direction,
* otherwise it returns false.
*/
int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd));
}
/*-------------------------------------------------------------------*/
/*
* __usb_get_extra_descriptor() finds a descriptor of specific type in the
@ -1102,18 +970,6 @@ EXPORT_SYMBOL(__usb_get_extra_descriptor);
EXPORT_SYMBOL(usb_find_device);
EXPORT_SYMBOL(usb_get_current_frame_number);
EXPORT_SYMBOL_GPL(usb_endpoint_dir_in);
EXPORT_SYMBOL_GPL(usb_endpoint_dir_out);
EXPORT_SYMBOL_GPL(usb_endpoint_xfer_bulk);
EXPORT_SYMBOL_GPL(usb_endpoint_xfer_int);
EXPORT_SYMBOL_GPL(usb_endpoint_xfer_isoc);
EXPORT_SYMBOL_GPL(usb_endpoint_is_bulk_in);
EXPORT_SYMBOL_GPL(usb_endpoint_is_bulk_out);
EXPORT_SYMBOL_GPL(usb_endpoint_is_int_in);
EXPORT_SYMBOL_GPL(usb_endpoint_is_int_out);
EXPORT_SYMBOL_GPL(usb_endpoint_is_isoc_in);
EXPORT_SYMBOL_GPL(usb_endpoint_is_isoc_out);
EXPORT_SYMBOL (usb_buffer_alloc);
EXPORT_SYMBOL (usb_buffer_free);

View file

@ -64,14 +64,13 @@ static inline void usb_pm_unlock(struct usb_device *udev) {}
#define USB_AUTOSUSPEND_DELAY (HZ*2)
extern void usb_autosuspend_device(struct usb_device *udev, int dec_busy_cnt);
extern int usb_autoresume_device(struct usb_device *udev, int inc_busy_cnt);
extern void usb_autosuspend_device(struct usb_device *udev);
extern int usb_autoresume_device(struct usb_device *udev);
#else
#define usb_autosuspend_device(udev, dec_busy_cnt) do {} while (0)
static inline int usb_autoresume_device(struct usb_device *udev,
int inc_busy_cnt)
#define usb_autosuspend_device(udev) do {} while (0)
static inline int usb_autoresume_device(struct usb_device *udev)
{
return 0;
}

View file

@ -1894,13 +1894,13 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
if (!eth_is_promisc (dev)) {
u8 *dest = skb->data;
if (dest [0] & 0x01) {
if (is_multicast_ether_addr(dest)) {
u16 type;
/* ignores USB_CDC_PACKET_TYPE_MULTICAST and host
* SET_ETHERNET_MULTICAST_FILTERS requests
*/
if (memcmp (dest, net->broadcast, ETH_ALEN) == 0)
if (is_broadcast_ether_addr(dest))
type = USB_CDC_PACKET_TYPE_BROADCAST;
else
type = USB_CDC_PACKET_TYPE_ALL_MULTICAST;

View file

@ -83,7 +83,6 @@ static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t);
static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *);
static int lh7a40x_set_halt(struct usb_ep *ep, int);
static int lh7a40x_fifo_status(struct usb_ep *ep);
static int lh7a40x_fifo_status(struct usb_ep *ep);
static void lh7a40x_fifo_flush(struct usb_ep *ep);
static void lh7a40x_ep0_kick(struct lh7a40x_udc *dev, struct lh7a40x_ep *ep);
static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr);

View file

@ -1040,6 +1040,7 @@ net2280_queue (struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
} /* else the irq handler advances the queue. */
ep->responded = 1;
if (req)
list_add_tail (&req->queue, &ep->queue);
done:
@ -2188,7 +2189,8 @@ static void handle_ep_small (struct net2280_ep *ep)
ep->stopped = 1;
set_halt (ep);
mode = 2;
} else if (!req && !ep->stopped)
} else if (ep->responded &&
!req && !ep->stopped)
write_fifo (ep, NULL);
}
} else {
@ -2203,7 +2205,7 @@ static void handle_ep_small (struct net2280_ep *ep)
} else if (((t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT))
&& req
&& req->req.actual == req->req.length)
|| !req) {
|| (ep->responded && !req)) {
ep->dev->protocol_stall = 1;
set_halt (ep);
ep->stopped = 1;
@ -2469,6 +2471,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
/* we made the hardware handle most lowlevel requests;
* everything else goes uplevel to the gadget code.
*/
ep->responded = 1;
switch (u.r.bRequest) {
case USB_REQ_GET_STATUS: {
struct net2280_ep *e;
@ -2537,6 +2540,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
u.r.bRequestType, u.r.bRequest,
w_value, w_index, w_length,
readl (&ep->regs->ep_cfg));
ep->responded = 0;
spin_unlock (&dev->lock);
tmp = dev->driver->setup (&dev->gadget, &u.r);
spin_lock (&dev->lock);

View file

@ -110,7 +110,8 @@ struct net2280_ep {
out_overflow : 1,
stopped : 1,
is_in : 1,
is_iso : 1;
is_iso : 1,
responded : 1;
};
static inline void allow_status (struct net2280_ep *ep)

View file

@ -2472,6 +2472,7 @@ static struct pxa2xx_udc memory = {
#define PXA210_B1 0x00000123
#define PXA210_B0 0x00000122
#define IXP425_A0 0x000001c1
#define IXP425_B0 0x000001f1
#define IXP465_AD 0x00000200
/*
@ -2509,6 +2510,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
break;
#elif defined(CONFIG_ARCH_IXP4XX)
case IXP425_A0:
case IXP425_B0:
case IXP465_AD:
dev->has_cfr = 1;
out_dma = 0;

View file

@ -126,6 +126,11 @@ static unsigned park = 0;
module_param (park, uint, S_IRUGO);
MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
/* for flakey hardware, ignore overcurrent indicators */
static int ignore_oc = 0;
module_param (ignore_oc, bool, S_IRUGO);
MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
/*-------------------------------------------------------------------------*/
@ -541,9 +546,10 @@ static int ehci_run (struct usb_hcd *hcd)
temp = HC_VERSION(readl (&ehci->caps->hc_capbase));
ehci_info (ehci,
"USB %x.%x started, EHCI %x.%02x, driver %s\n",
"USB %x.%x started, EHCI %x.%02x, driver %s%s\n",
((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
temp >> 8, temp & 0xff, DRIVER_VERSION);
temp >> 8, temp & 0xff, DRIVER_VERSION,
ignore_oc ? ", overcurrent ignored" : "");
writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */
@ -613,9 +619,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
unsigned i = HCS_N_PORTS (ehci->hcs_params);
/* resume root hub? */
status = readl (&ehci->regs->command);
if (!(status & CMD_RUN))
writel (status | CMD_RUN, &ehci->regs->command);
if (!(readl(&ehci->regs->command) & CMD_RUN))
usb_hcd_resume_root_hub(hcd);
while (i--) {
int pstatus = readl (&ehci->regs->port_status [i]);
@ -632,7 +637,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
*/
ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
usb_hcd_resume_root_hub(hcd);
}
}

View file

@ -34,6 +34,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
int port;
int mask;
if (time_before (jiffies, ehci->next_statechange))
msleep(5);
@ -51,14 +52,25 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
ehci->reclaim_ready = 1;
ehci_work(ehci);
/* suspend any active/unsuspended ports, maybe allow wakeup */
/* Unlike other USB host controller types, EHCI doesn't have
* any notion of "global" or bus-wide suspend. The driver has
* to manually suspend all the active unsuspended ports, and
* then manually resume them in the bus_resume() routine.
*/
ehci->bus_suspended = 0;
while (port--) {
u32 __iomem *reg = &ehci->regs->port_status [port];
u32 t1 = readl (reg) & ~PORT_RWC_BITS;
u32 t2 = t1;
if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
/* keep track of which ports we suspend */
if ((t1 & PORT_PE) && !(t1 & PORT_OWNER) &&
!(t1 & PORT_SUSPEND)) {
t2 |= PORT_SUSPEND;
set_bit(port, &ehci->bus_suspended);
}
/* enable remote wakeup on all ports */
if (device_may_wakeup(&hcd->self.root_hub->dev))
t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
else
@ -76,6 +88,13 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
ehci_halt (ehci);
hcd->state = HC_STATE_SUSPENDED;
/* allow remote wakeup */
mask = INTR_MASK;
if (!device_may_wakeup(&hcd->self.root_hub->dev))
mask &= ~STS_PCD;
writel(mask, &ehci->regs->intr_enable);
readl(&ehci->regs->intr_enable);
ehci->next_statechange = jiffies + msecs_to_jiffies(10);
spin_unlock_irq (&ehci->lock);
return 0;
@ -88,7 +107,6 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
u32 temp;
int i;
int intr_enable;
if (time_before (jiffies, ehci->next_statechange))
msleep(5);
@ -100,31 +118,30 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
* the last user of the controller, not reset/pm hardware keeping
* state we gave to it.
*/
temp = readl(&ehci->regs->intr_enable);
ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss");
/* re-init operational registers in case we lost power */
if (readl (&ehci->regs->intr_enable) == 0) {
/* at least some APM implementations will try to deliver
* IRQs right away, so delay them until we're ready.
*/
intr_enable = 1;
writel (0, &ehci->regs->segment);
writel (ehci->periodic_dma, &ehci->regs->frame_list);
writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next);
} else
intr_enable = 0;
ehci_dbg(ehci, "resume root hub%s\n",
intr_enable ? " after power loss" : "");
/* at least some APM implementations will try to deliver
* IRQs right away, so delay them until we're ready.
*/
writel(0, &ehci->regs->intr_enable);
/* re-init operational registers */
writel(0, &ehci->regs->segment);
writel(ehci->periodic_dma, &ehci->regs->frame_list);
writel((u32) ehci->async->qh_dma, &ehci->regs->async_next);
/* restore CMD_RUN, framelist size, and irq threshold */
writel (ehci->command, &ehci->regs->command);
/* take ports out of suspend */
/* manually resume the ports we suspended during bus_suspend() */
i = HCS_N_PORTS (ehci->hcs_params);
while (i--) {
temp = readl (&ehci->regs->port_status [i]);
temp &= ~(PORT_RWC_BITS
| PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
if (temp & PORT_SUSPEND) {
if (test_bit(i, &ehci->bus_suspended) &&
(temp & PORT_SUSPEND)) {
ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
temp |= PORT_RESUME;
}
@ -134,11 +151,12 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
mdelay (20);
while (i--) {
temp = readl (&ehci->regs->port_status [i]);
if ((temp & PORT_SUSPEND) == 0)
continue;
temp &= ~(PORT_RWC_BITS | PORT_RESUME);
writel (temp, &ehci->regs->port_status [i]);
ehci_vdbg (ehci, "resumed port %d\n", i + 1);
if (test_bit(i, &ehci->bus_suspended) &&
(temp & PORT_SUSPEND)) {
temp &= ~(PORT_RWC_BITS | PORT_RESUME);
writel (temp, &ehci->regs->port_status [i]);
ehci_vdbg (ehci, "resumed port %d\n", i + 1);
}
}
(void) readl (&ehci->regs->command);
@ -157,8 +175,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
hcd->state = HC_STATE_RUNNING;
/* Now we can safely re-enable irqs */
if (intr_enable)
writel (INTR_MASK, &ehci->regs->intr_enable);
writel(INTR_MASK, &ehci->regs->intr_enable);
spin_unlock_irq (&ehci->lock);
return 0;
@ -218,6 +235,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
u32 temp, status = 0;
u32 mask;
int ports, i, retval = 1;
unsigned long flags;
@ -233,6 +251,18 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
retval++;
}
/* Some boards (mostly VIA?) report bogus overcurrent indications,
* causing massive log spam unless we completely ignore them. It
* may be relevant that VIA VT8235 controlers, where PORT_POWER is
* always set, seem to clear PORT_OCC and PORT_CSC when writing to
* PORT_POWER; that's surprising, but maybe within-spec.
*/
if (!ignore_oc)
mask = PORT_CSC | PORT_PEC | PORT_OCC;
else
mask = PORT_CSC | PORT_PEC;
// PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND
/* no hub change reports (bit 0) for now (power, ...) */
/* port N changes (bit N)? */
@ -250,8 +280,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
}
if (!(temp & PORT_CONNECT))
ehci->reset_done [i] = 0;
if ((temp & (PORT_CSC | PORT_PEC | PORT_OCC)) != 0
// PORT_STAT_C_SUSPEND?
if ((temp & mask) != 0
|| ((temp & PORT_RESUME) != 0
&& time_after (jiffies,
ehci->reset_done [i]))) {
@ -319,6 +348,7 @@ static int ehci_hub_control (
u32 temp, status;
unsigned long flags;
int retval = 0;
unsigned selector;
/*
* FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR.
@ -417,7 +447,7 @@ static int ehci_hub_control (
status |= 1 << USB_PORT_FEAT_C_CONNECTION;
if (temp & PORT_PEC)
status |= 1 << USB_PORT_FEAT_C_ENABLE;
if (temp & PORT_OCC)
if ((temp & PORT_OCC) && !ignore_oc)
status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
/* whoever resumes must GetPortStatus to complete it!! */
@ -506,6 +536,8 @@ static int ehci_hub_control (
}
break;
case SetPortFeature:
selector = wIndex >> 8;
wIndex &= 0xff;
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
@ -559,6 +591,22 @@ static int ehci_hub_control (
}
writel (temp, &ehci->regs->port_status [wIndex]);
break;
/* For downstream facing ports (these): one hub port is put
* into test mode according to USB2 11.24.2.13, then the hub
* must be reset (which for root hub now means rmmod+modprobe,
* or else system reboot). See EHCI 2.3.9 and 4.14 for info
* about the EHCI-specific stuff.
*/
case USB_PORT_FEAT_TEST:
if (!selector || selector > 5)
goto error;
ehci_quiesce(ehci);
ehci_halt(ehci);
temp |= selector << 16;
writel (temp, &ehci->regs->port_status [wIndex]);
break;
default:
goto error;
}

View file

@ -257,9 +257,7 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
static int ehci_pci_resume(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
unsigned port;
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
int retval = -EINVAL;
// maybe restore FLADJ
@ -269,27 +267,19 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
/* Mark hardware accessible again as we are out of D3 state by now */
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
/* If CF is clear, we lost PCI Vaux power and need to restart. */
if (readl(&ehci->regs->configured_flag) != FLAG_CF)
goto restart;
/* If any port is suspended (or owned by the companion),
* we know we can/must resume the HC (and mustn't reset it).
* We just defer that to the root hub code.
/* If CF is still set, we maintained PCI Vaux power.
* Just undo the effect of ehci_pci_suspend().
*/
for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) {
u32 status;
port--;
status = readl(&ehci->regs->port_status [port]);
if (!(status & PORT_POWER))
continue;
if (status & (PORT_SUSPEND | PORT_RESUME | PORT_OWNER)) {
usb_hcd_resume_root_hub(hcd);
return 0;
}
if (readl(&ehci->regs->configured_flag) == FLAG_CF) {
int mask = INTR_MASK;
if (!device_may_wakeup(&hcd->self.root_hub->dev))
mask &= ~STS_PCD;
writel(mask, &ehci->regs->intr_enable);
readl(&ehci->regs->intr_enable);
return 0;
}
restart:
ehci_dbg(ehci, "lost power, restarting\n");
usb_root_hub_lost_power(hcd->self.root_hub);
@ -307,13 +297,15 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
ehci_work(ehci);
spin_unlock_irq(&ehci->lock);
/* restart; khubd will disconnect devices */
retval = ehci_run(hcd);
/* here we "know" root ports should always stay powered */
ehci_port_power(ehci, 1);
return retval;
writel(ehci->command, &ehci->regs->command);
writel(FLAG_CF, &ehci->regs->configured_flag);
readl(&ehci->regs->command); /* unblock posted writes */
hcd->state = HC_STATE_SUSPENDED;
return 0;
}
#endif

View file

@ -74,6 +74,7 @@ struct ehci_hcd { /* one per controller */
/* per root hub port */
unsigned long reset_done [EHCI_MAX_ROOT_PORTS];
unsigned long bus_suspended;
/* per-HC memory pools (could be per-bus, but ...) */
struct dma_pool *qh_pool; /* qh per active urb */

View file

@ -729,6 +729,16 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
ohci->next_statechange = jiffies + STATECHANGE_DELAY;
ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC,
&regs->intrstatus);
/* NOTE: Vendors didn't always make the same implementation
* choices for RHSC. Many followed the spec; RHSC triggers
* on an edge, like setting and maybe clearing a port status
* change bit. With others it's level-triggered, active
* until khubd clears all the port status change bits. We'll
* always disable it here and rely on polling until khubd
* re-enables it.
*/
ohci_writel(ohci, OHCI_INTR_RHSC, &regs->intrdisable);
usb_hcd_poll_rh_status(hcd);
}

View file

@ -41,7 +41,11 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
spin_lock_irq(&ohci->lock);
if (!ohci->autostop)
del_timer(&hcd->rh_timer); /* Prevent next poll */
ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
spin_unlock_irq(&ohci->lock);
}
#define OHCI_SCHED_ENABLES \
@ -50,6 +54,9 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd)
static void dl_done_list (struct ohci_hcd *);
static void finish_unlinks (struct ohci_hcd *, u16);
#ifdef CONFIG_PM
static int ohci_restart(struct ohci_hcd *ohci);
static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop)
__releases(ohci->lock)
__acquires(ohci->lock)
@ -132,8 +139,6 @@ static inline struct ed *find_head (struct ed *ed)
return ed;
}
static int ohci_restart (struct ohci_hcd *ohci);
/* caller has locked the root hub */
static int ohci_rh_resume (struct ohci_hcd *ohci)
__releases(ohci->lock)
@ -169,7 +174,7 @@ __acquires(ohci->lock)
break;
case OHCI_USB_RESUME:
/* HCFS changes sometime after INTR_RD */
ohci_info(ohci, "%swakeup\n",
ohci_dbg(ohci, "%swakeup root hub\n",
autostopped ? "auto-" : "");
break;
case OHCI_USB_OPER:
@ -181,7 +186,6 @@ __acquires(ohci->lock)
ohci_dbg (ohci, "lost power\n");
status = -EBUSY;
}
#ifdef CONFIG_PM
if (status == -EBUSY) {
if (!autostopped) {
spin_unlock_irq (&ohci->lock);
@ -191,25 +195,12 @@ __acquires(ohci->lock)
}
return status;
}
#endif
if (status != -EINPROGRESS)
return status;
if (autostopped)
goto skip_resume;
spin_unlock_irq (&ohci->lock);
temp = ohci->num_ports;
while (temp--) {
u32 stat = ohci_readl (ohci,
&ohci->regs->roothub.portstatus [temp]);
/* force global, not selective, resume */
if (!(stat & RH_PS_PSS))
continue;
ohci_writel (ohci, RH_PS_POCI,
&ohci->regs->roothub.portstatus [temp]);
}
/* Some controllers (lucent erratum) need extra-long delays */
msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1);
@ -217,6 +208,7 @@ __acquires(ohci->lock)
temp &= OHCI_CTRL_HCFS;
if (temp != OHCI_USB_RESUME) {
ohci_err (ohci, "controller won't resume\n");
spin_lock_irq(&ohci->lock);
return -EBUSY;
}
@ -296,8 +288,6 @@ __acquires(ohci->lock)
return 0;
}
#ifdef CONFIG_PM
static int ohci_bus_suspend (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
@ -335,6 +325,83 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
return rc;
}
/* Carry out polling-, autostop-, and autoresume-related state changes */
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
int any_connected)
{
int poll_rh = 1;
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_OPER:
/* keep on polling until we know a device is connected
* and RHSC is enabled */
if (!ohci->autostop) {
if (any_connected ||
!device_may_wakeup(&ohci_to_hcd(ohci)
->self.root_hub->dev)) {
if (ohci_readl(ohci, &ohci->regs->intrenable) &
OHCI_INTR_RHSC)
poll_rh = 0;
} else {
ohci->autostop = 1;
ohci->next_statechange = jiffies + HZ;
}
/* if no devices have been attached for one second, autostop */
} else {
if (changed || any_connected) {
ohci->autostop = 0;
ohci->next_statechange = jiffies +
STATECHANGE_DELAY;
} else if (time_after_eq(jiffies,
ohci->next_statechange)
&& !ohci->ed_rm_list
&& !(ohci->hc_control &
OHCI_SCHED_ENABLES)) {
ohci_rh_suspend(ohci, 1);
}
}
break;
/* if there is a port change, autostart or ask to be resumed */
case OHCI_USB_SUSPEND:
case OHCI_USB_RESUME:
if (changed) {
if (ohci->autostop)
ohci_rh_resume(ohci);
else
usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
} else {
/* everything is idle, no need for polling */
poll_rh = 0;
}
break;
}
return poll_rh;
}
#else /* CONFIG_PM */
static inline int ohci_rh_resume(struct ohci_hcd *ohci)
{
return 0;
}
/* Carry out polling-related state changes.
* autostop isn't used when CONFIG_PM is turned off.
*/
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
int any_connected)
{
int poll_rh = 1;
/* keep on polling until RHSC is enabled */
if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
poll_rh = 0;
return poll_rh;
}
#endif /* CONFIG_PM */
/*-------------------------------------------------------------------------*/
@ -346,7 +413,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int i, changed = 0, length = 1;
int any_connected = 0, rhsc_enabled = 1;
int any_connected = 0;
unsigned long flags;
spin_lock_irqsave (&ohci->lock, flags);
@ -387,67 +454,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
}
}
/* NOTE: vendors didn't always make the same implementation
* choices for RHSC. Sometimes it triggers on an edge (like
* setting and maybe clearing a port status change bit); and
* it's level-triggered on other silicon, active until khubd
* clears all active port status change bits. If it's still
* set (level-triggered) we must disable it and rely on
* polling until khubd re-enables it.
*/
if (ohci_readl (ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC) {
ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable);
(void) ohci_readl (ohci, &ohci->regs->intrdisable);
rhsc_enabled = 0;
}
hcd->poll_rh = 1;
/* carry out appropriate state changes */
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_OPER:
/* keep on polling until we know a device is connected
* and RHSC is enabled */
if (!ohci->autostop) {
if (any_connected) {
if (rhsc_enabled)
hcd->poll_rh = 0;
} else {
ohci->autostop = 1;
ohci->next_statechange = jiffies + HZ;
}
/* if no devices have been attached for one second, autostop */
} else {
if (changed || any_connected) {
ohci->autostop = 0;
ohci->next_statechange = jiffies +
STATECHANGE_DELAY;
} else if (device_may_wakeup(&hcd->self.root_hub->dev)
&& time_after_eq(jiffies,
ohci->next_statechange)
&& !ohci->ed_rm_list
&& !(ohci->hc_control &
OHCI_SCHED_ENABLES)) {
ohci_rh_suspend (ohci, 1);
}
}
break;
/* if there is a port change, autostart or ask to be resumed */
case OHCI_USB_SUSPEND:
case OHCI_USB_RESUME:
if (changed) {
if (ohci->autostop)
ohci_rh_resume (ohci);
else
usb_hcd_resume_root_hub (hcd);
} else {
/* everything is idle, no need for polling */
hcd->poll_rh = 0;
}
break;
}
hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed,
any_connected);
done:
spin_unlock_irqrestore (&ohci->lock, flags);

View file

@ -71,7 +71,7 @@ static int distrust_firmware = 1;
module_param(distrust_firmware, bool, 0);
MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren"
"t setup");
DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait);
static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait);
/*
* u132_module_lock exists to protect access to global variables
*
@ -205,11 +205,7 @@ struct u132 {
struct u132_port port[MAX_U132_PORTS];
struct u132_endp *endp[MAX_U132_ENDPS];
};
int usb_ftdi_elan_read_reg(struct platform_device *pdev, u32 *data);
int usb_ftdi_elan_read_pcimem(struct platform_device *pdev, u8 addressofs,
u8 width, u32 *data);
int usb_ftdi_elan_write_pcimem(struct platform_device *pdev, u8 addressofs,
u8 width, u32 data);
/*
* these cannot be inlines because we need the structure offset!!
* Does anyone have a better way?????

View file

@ -796,7 +796,7 @@ static int mts_usb_probe(struct usb_interface *intf,
new_desc->context.scsi_status = kmalloc(1, GFP_KERNEL);
if (!new_desc->context.scsi_status)
goto out_kfree2;
goto out_free_urb;
new_desc->usb_dev = dev;
new_desc->usb_intf = intf;
@ -822,18 +822,20 @@ static int mts_usb_probe(struct usb_interface *intf,
new_desc->host = scsi_host_alloc(&mts_scsi_host_template,
sizeof(new_desc));
if (!new_desc->host)
goto out_free_urb;
goto out_kfree2;
new_desc->host->hostdata[0] = (unsigned long)new_desc;
if (scsi_add_host(new_desc->host, NULL)) {
err_retval = -EIO;
goto out_free_urb;
goto out_host_put;
}
scsi_scan_host(new_desc->host);
usb_set_intfdata(intf, new_desc);
return 0;
out_host_put:
scsi_host_put(new_desc->host);
out_kfree2:
kfree(new_desc->context.scsi_status);
out_free_urb:

View file

@ -221,6 +221,7 @@ config USB_TOUCHSCREEN
- ITM
- some other eTurboTouch
- Gunze AHL61
- DMC TSC-10/25
Have a look at <http://linux.chapter7.ch/touchkit/> for
a usage description and the required user-space stuff.
@ -258,6 +259,11 @@ config USB_TOUCHSCREEN_GUNZE
bool "Gunze AHL61 device support" if EMBEDDED
depends on USB_TOUCHSCREEN
config USB_TOUCHSCREEN_DMC_TSC10
default y
bool "DMC TSC-10/25 device support" if EMBEDDED
depends on USB_TOUCHSCREEN
config USB_YEALINK
tristate "Yealink usb-p1k voip phone"
depends on USB && INPUT && EXPERIMENTAL

View file

@ -630,11 +630,8 @@ static int ati_remote_alloc_buffers(struct usb_device *udev,
*/
static void ati_remote_free_buffers(struct ati_remote *ati_remote)
{
if (ati_remote->irq_urb)
usb_free_urb(ati_remote->irq_urb);
if (ati_remote->out_urb)
usb_free_urb(ati_remote->out_urb);
usb_free_urb(ati_remote->irq_urb);
usb_free_urb(ati_remote->out_urb);
usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
ati_remote->inbuf, ati_remote->inbuf_dma);

View file

@ -372,8 +372,7 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
int i;
for (i = 0; i < 2; i++) {
if (ar2->urb[i])
usb_free_urb(ar2->urb[i]);
usb_free_urb(ar2->urb[i]);
if (ar2->buf[i])
usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);

View file

@ -968,20 +968,29 @@ static void hid_retry_timeout(unsigned long _hid)
hid_io_error(hid);
}
/* Workqueue routine to reset the device */
/* Workqueue routine to reset the device or clear a halt */
static void hid_reset(void *_hid)
{
struct hid_device *hid = (struct hid_device *) _hid;
int rc_lock, rc;
int rc_lock, rc = 0;
dev_dbg(&hid->intf->dev, "resetting device\n");
rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
if (rc_lock >= 0) {
rc = usb_reset_composite_device(hid->dev, hid->intf);
if (rc_lock)
usb_unlock_device(hid->dev);
if (test_bit(HID_CLEAR_HALT, &hid->iofl)) {
dev_dbg(&hid->intf->dev, "clear halt\n");
rc = usb_clear_halt(hid->dev, hid->urbin->pipe);
clear_bit(HID_CLEAR_HALT, &hid->iofl);
hid_start_in(hid);
}
else if (test_bit(HID_RESET_PENDING, &hid->iofl)) {
dev_dbg(&hid->intf->dev, "resetting device\n");
rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
if (rc_lock >= 0) {
rc = usb_reset_composite_device(hid->dev, hid->intf);
if (rc_lock)
usb_unlock_device(hid->dev);
}
clear_bit(HID_RESET_PENDING, &hid->iofl);
}
clear_bit(HID_RESET_PENDING, &hid->iofl);
switch (rc) {
case 0:
@ -1023,9 +1032,8 @@ static void hid_io_error(struct hid_device *hid)
/* Retries failed, so do a port reset */
if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) {
if (schedule_work(&hid->reset_work))
goto done;
clear_bit(HID_RESET_PENDING, &hid->iofl);
schedule_work(&hid->reset_work);
goto done;
}
}
@ -1049,6 +1057,11 @@ static void hid_irq_in(struct urb *urb)
hid->retry_delay = 0;
hid_input_report(HID_INPUT_REPORT, urb, 1);
break;
case -EPIPE: /* stall */
clear_bit(HID_IN_RUNNING, &hid->iofl);
set_bit(HID_CLEAR_HALT, &hid->iofl);
schedule_work(&hid->reset_work);
return;
case -ECONNRESET: /* unlink */
case -ENOENT:
case -ESHUTDOWN: /* unplug */
@ -1627,6 +1640,19 @@ void hid_init_reports(struct hid_device *hid)
#define USB_VENDOR_ID_APPLE 0x05ac
#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
#define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215
#define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216
#define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217
#define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218
#define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219
#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a
#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b
#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
#define USB_VENDOR_ID_CHERRY 0x046a
#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
@ -1794,17 +1820,19 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION },
{ USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
{ USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
{ USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x021B, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE },
@ -1985,7 +2013,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
interval = hid_mousepoll_interval;
if (endpoint->bEndpointAddress & USB_DIR_IN) {
if (usb_endpoint_dir_in(endpoint)) {
if (hid->urbin)
continue;
if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
@ -2067,13 +2095,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
return hid;
fail:
if (hid->urbin)
usb_free_urb(hid->urbin);
if (hid->urbout)
usb_free_urb(hid->urbout);
if (hid->urbctrl)
usb_free_urb(hid->urbctrl);
usb_free_urb(hid->urbin);
usb_free_urb(hid->urbout);
usb_free_urb(hid->urbctrl);
hid_free_buffers(dev, hid);
hid_free_device(hid);
@ -2104,8 +2128,7 @@ static void hid_disconnect(struct usb_interface *intf)
usb_free_urb(hid->urbin);
usb_free_urb(hid->urbctrl);
if (hid->urbout)
usb_free_urb(hid->urbout);
usb_free_urb(hid->urbout);
hid_free_buffers(hid->dev, hid);
hid_free_device(hid);

View file

@ -385,6 +385,7 @@ struct hid_control_fifo {
#define HID_IN_RUNNING 3
#define HID_RESET_PENDING 4
#define HID_SUSPENDED 5
#define HID_CLEAR_HALT 6
struct hid_input {
struct list_head list;

View file

@ -208,10 +208,8 @@ static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
{
if (kbd->irq)
usb_free_urb(kbd->irq);
if (kbd->led)
usb_free_urb(kbd->led);
usb_free_urb(kbd->irq);
usb_free_urb(kbd->led);
if (kbd->new)
usb_buffer_free(dev, 8, kbd->new, kbd->new_dma);
if (kbd->cr)
@ -236,9 +234,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
return -ENODEV;
endpoint = &interface->endpoint[0].desc;
if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -ENODEV;
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
if (!usb_endpoint_is_int_in(endpoint))
return -ENODEV;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);

View file

@ -126,9 +126,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
return -ENODEV;
endpoint = &interface->endpoint[0].desc;
if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -ENODEV;
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
if (!usb_endpoint_is_int_in(endpoint))
return -ENODEV;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);

View file

@ -8,6 +8,7 @@
* - PanJit TouchSet
* - eTurboTouch
* - Gunze AHL61
* - DMC TSC-10/25
*
* Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
* Copyright (C) by Todd E. Johnson (mtouchusb.c)
@ -30,6 +31,8 @@
* - ITM parts are from itmtouch.c
* - 3M parts are from mtouchusb.c
* - PanJit parts are from an unmerged driver by Lanslott Gish
* - DMC TSC 10/25 are from Holger Schurig, with ideas from an unmerged
* driver from Marius Vollmer
*
*****************************************************************************/
@ -44,7 +47,7 @@
#include <linux/usb/input.h>
#define DRIVER_VERSION "v0.4"
#define DRIVER_VERSION "v0.5"
#define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>"
#define DRIVER_DESC "USB Touchscreen Driver"
@ -103,6 +106,7 @@ enum {
DEVTYPE_ITM,
DEVTYPE_ETURBO,
DEVTYPE_GUNZE,
DEVTYPE_DMC_TSC10,
};
static struct usb_device_id usbtouch_devices[] = {
@ -139,6 +143,10 @@ static struct usb_device_id usbtouch_devices[] = {
{USB_DEVICE(0x0637, 0x0001), .driver_info = DEVTYPE_GUNZE},
#endif
#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10
{USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10},
#endif
{}
};
@ -312,6 +320,80 @@ static int gunze_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *
}
#endif
/*****************************************************************************
* DMC TSC-10/25 Part
*
* Documentation about the controller and it's protocol can be found at
* http://www.dmccoltd.com/files/controler/tsc10usb_pi_e.pdf
* http://www.dmccoltd.com/files/controler/tsc25_usb_e.pdf
*/
#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10
/* supported data rates. currently using 130 */
#define TSC10_RATE_POINT 0x50
#define TSC10_RATE_30 0x40
#define TSC10_RATE_50 0x41
#define TSC10_RATE_80 0x42
#define TSC10_RATE_100 0x43
#define TSC10_RATE_130 0x44
#define TSC10_RATE_150 0x45
/* commands */
#define TSC10_CMD_RESET 0x55
#define TSC10_CMD_RATE 0x05
#define TSC10_CMD_DATA1 0x01
static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
{
struct usb_device *dev = usbtouch->udev;
int ret;
unsigned char buf[2];
/* reset */
buf[0] = buf[1] = 0xFF;
ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
TSC10_CMD_RESET,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, 0, buf, 2, USB_CTRL_SET_TIMEOUT);
if (ret < 0)
return ret;
if (buf[0] != 0x06 || buf[1] != 0x00)
return -ENODEV;
/* set coordinate output rate */
buf[0] = buf[1] = 0xFF;
ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
TSC10_CMD_RATE,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT);
if (ret < 0)
return ret;
if (buf[0] != 0x06 || buf[1] != 0x00)
return -ENODEV;
/* start sending data */
ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
TSC10_CMD_DATA1,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
if (ret < 0)
return ret;
return 0;
}
static int dmc_tsc10_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press)
{
*x = ((pkt[2] & 0x03) << 8) | pkt[1];
*y = ((pkt[4] & 0x03) << 8) | pkt[3];
*touch = pkt[0] & 0x01;
return 1;
}
#endif
/*****************************************************************************
* the different device descriptors
*/
@ -389,6 +471,18 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
.read_data = gunze_read_data,
},
#endif
#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10
[DEVTYPE_DMC_TSC10] = {
.min_xc = 0x0,
.max_xc = 0x03ff,
.min_yc = 0x0,
.max_yc = 0x03ff,
.rept_size = 5,
.init = dmc_tsc10_init,
.read_data = dmc_tsc10_read_data,
},
#endif
};

View file

@ -110,7 +110,6 @@ struct wacom_combo {
};
extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo);
extern void wacom_sys_irq(struct urb *urb);
extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data);
extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data);
extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data);

View file

@ -42,7 +42,7 @@ static struct input_dev * get_input_dev(struct wacom_combo *wcombo)
return wcombo->wacom->dev;
}
void wacom_sys_irq(struct urb *urb)
static void wacom_sys_irq(struct urb *urb)
{
struct wacom *wacom = urb->context;
struct wacom_combo wcombo;

View file

@ -859,10 +859,8 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -EIO;
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
return -EIO;
if (!usb_endpoint_is_int_in(endpoint))
return -ENODEV;
yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL);
if (!yld)

View file

@ -4,6 +4,7 @@
#
obj-$(CONFIG_USB_ADUTUX) += adutux.o
obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o
obj-$(CONFIG_USB_AUERSWALD) += auerswald.o
obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
obj-$(CONFIG_USB_CYTHERM) += cytherm.o

View file

@ -216,10 +216,7 @@ static int appledisplay_probe(struct usb_interface *iface,
iface_desc = iface->cur_altsetting;
for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
endpoint = &iface_desc->endpoint[i].desc;
if (!int_in_endpointAddr &&
(endpoint->bEndpointAddress & USB_DIR_IN) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_INT)) {
if (!int_in_endpointAddr && usb_endpoint_is_int_in(endpoint)) {
/* we found an interrupt in endpoint */
int_in_endpointAddr = endpoint->bEndpointAddress;
break;

View file

@ -704,9 +704,7 @@ static void auerbuf_free (pauerbuf_t bp)
{
kfree(bp->bufp);
kfree(bp->dr);
if (bp->urbp) {
usb_free_urb(bp->urbp);
}
usb_free_urb(bp->urbp);
kfree(bp);
}
@ -1155,8 +1153,7 @@ static void auerswald_int_release (pauerswald_t cp)
dbg ("auerswald_int_release");
/* stop the int endpoint */
if (cp->inturbp)
usb_kill_urb (cp->inturbp);
usb_kill_urb (cp->inturbp);
/* deallocate memory */
auerswald_int_free (cp);

View file

@ -53,13 +53,12 @@ static void __exit emi26_exit (void);
static int emi26_writememory (struct usb_device *dev, int address, unsigned char *data, int length, __u8 request)
{
int result;
unsigned char *buffer = kmalloc (length, GFP_KERNEL);
unsigned char *buffer = kmemdup(data, length, GFP_KERNEL);
if (!buffer) {
err("emi26: kmalloc(%d) failed.", length);
return -ENOMEM;
}
memcpy (buffer, data, length);
/* Note: usb_control_msg returns negative value on error or length of the
* data that was written! */
result = usb_control_msg (dev, usb_sndctrlpipe(dev, 0), request, 0x40, address, 0, buffer, length, 300);

View file

@ -61,13 +61,12 @@ static void __exit emi62_exit (void);
static int emi62_writememory (struct usb_device *dev, int address, unsigned char *data, int length, __u8 request)
{
int result;
unsigned char *buffer = kmalloc (length, GFP_KERNEL);
unsigned char *buffer = kmemdup(data, length, GFP_KERNEL);
if (!buffer) {
err("emi62: kmalloc(%d) failed.", length);
return -ENOMEM;
}
memcpy (buffer, data, length);
/* Note: usb_control_msg returns negative value on error or length of the
* data that was written! */
result = usb_control_msg (dev, usb_sndctrlpipe(dev, 0), request, 0x40, address, 0, buffer, length, 300);

View file

@ -303,7 +303,7 @@ void ftdi_elan_gone_away(struct platform_device *pdev)
EXPORT_SYMBOL_GPL(ftdi_elan_gone_away);
void ftdi_release_platform_dev(struct device *dev)
static void ftdi_release_platform_dev(struct device *dev)
{
dev->parent = NULL;
}
@ -1426,14 +1426,6 @@ static int ftdi_elan_read_reg(struct usb_ftdi *ftdi, u32 *data)
}
}
int usb_ftdi_elan_read_reg(struct platform_device *pdev, u32 *data)
{
struct usb_ftdi *ftdi = platform_device_to_usb_ftdi(pdev);
return ftdi_elan_read_reg(ftdi, data);
}
EXPORT_SYMBOL_GPL(usb_ftdi_elan_read_reg);
static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset,
u8 width, u32 *data)
{
@ -2633,10 +2625,7 @@ static int ftdi_elan_probe(struct usb_interface *interface,
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
if (!ftdi->bulk_in_endpointAddr &&
((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
== USB_DIR_IN) && ((endpoint->bmAttributes &
USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK))
{
usb_endpoint_is_bulk_in(endpoint)) {
buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
ftdi->bulk_in_size = buffer_size;
ftdi->bulk_in_endpointAddr = endpoint->bEndpointAddress;
@ -2649,10 +2638,7 @@ static int ftdi_elan_probe(struct usb_interface *interface,
}
}
if (!ftdi->bulk_out_endpointAddr &&
((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
== USB_DIR_OUT) && ((endpoint->bmAttributes &
USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK))
{
usb_endpoint_is_bulk_out(endpoint)) {
ftdi->bulk_out_endpointAddr =
endpoint->bEndpointAddress;
}

View file

@ -125,12 +125,12 @@ static DEFINE_MUTEX(disconnect_mutex);
static int idmouse_create_image(struct usb_idmouse *dev)
{
int bytes_read = 0;
int bulk_read = 0;
int result = 0;
int bytes_read;
int bulk_read;
int result;
memcpy(dev->bulk_in_buffer, HEADER, sizeof(HEADER)-1);
bytes_read += sizeof(HEADER)-1;
bytes_read = sizeof(HEADER)-1;
/* reset the device and set a fast blink rate */
result = ftip_command(dev, FTIP_RELEASE, 0, 0);
@ -208,9 +208,9 @@ static inline void idmouse_delete(struct usb_idmouse *dev)
static int idmouse_open(struct inode *inode, struct file *file)
{
struct usb_idmouse *dev = NULL;
struct usb_idmouse *dev;
struct usb_interface *interface;
int result = 0;
int result;
/* prevent disconnects */
mutex_lock(&disconnect_mutex);
@ -305,7 +305,7 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count
loff_t * ppos)
{
struct usb_idmouse *dev;
int result = 0;
int result;
dev = (struct usb_idmouse *) file->private_data;
@ -329,7 +329,7 @@ static int idmouse_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
struct usb_idmouse *dev = NULL;
struct usb_idmouse *dev;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int result;
@ -350,11 +350,7 @@ static int idmouse_probe(struct usb_interface *interface,
/* set up the endpoint information - use only the first bulk-in endpoint */
endpoint = &iface_desc->endpoint[0].desc;
if (!dev->bulk_in_endpointAddr
&& (endpoint->bEndpointAddress & USB_DIR_IN)
&& ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_BULK)) {
if (!dev->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint)) {
/* we found a bulk in endpoint */
dev->orig_bi_size = le16_to_cpu(endpoint->wMaxPacketSize);
dev->bulk_in_size = 0x200; /* works _much_ faster */

View file

@ -317,12 +317,8 @@ static inline void tower_delete (struct lego_usb_tower *dev)
tower_abort_transfers (dev);
/* free data structures */
if (dev->interrupt_in_urb != NULL) {
usb_free_urb (dev->interrupt_in_urb);
}
if (dev->interrupt_out_urb != NULL) {
usb_free_urb (dev->interrupt_out_urb);
}
usb_free_urb(dev->interrupt_in_urb);
usb_free_urb(dev->interrupt_out_urb);
kfree (dev->read_buffer);
kfree (dev->interrupt_in_buffer);
kfree (dev->interrupt_out_buffer);
@ -502,15 +498,11 @@ static void tower_abort_transfers (struct lego_usb_tower *dev)
if (dev->interrupt_in_running) {
dev->interrupt_in_running = 0;
mb();
if (dev->interrupt_in_urb != NULL && dev->udev) {
if (dev->udev)
usb_kill_urb (dev->interrupt_in_urb);
}
}
if (dev->interrupt_out_busy) {
if (dev->interrupt_out_urb != NULL && dev->udev) {
usb_kill_urb (dev->interrupt_out_urb);
}
}
if (dev->interrupt_out_busy && dev->udev)
usb_kill_urb(dev->interrupt_out_urb);
exit:
dbg(2, "%s: leave", __FUNCTION__);
@ -898,14 +890,11 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
dev->interrupt_in_endpoint = endpoint;
}
if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
dev->interrupt_out_endpoint = endpoint;
if (usb_endpoint_xfer_int(endpoint)) {
if (usb_endpoint_dir_in(endpoint))
dev->interrupt_in_endpoint = endpoint;
else
dev->interrupt_out_endpoint = endpoint;
}
}
if(dev->interrupt_in_endpoint == NULL) {

View file

@ -551,7 +551,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
return -ENODEV;
endpoint = &interface->endpoint[0].desc;
if (!(endpoint->bEndpointAddress & 0x80))
if (!usb_endpoint_dir_in(endpoint))
return -ENODEV;
/*
* bmAttributes
@ -650,8 +650,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
device_remove_file(kit->dev, &dev_output_attrs[i]);
out:
if (kit) {
if (kit->irq)
usb_free_urb(kit->irq);
usb_free_urb(kit->irq);
if (kit->data)
usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma);
if (kit->dev)

View file

@ -323,7 +323,7 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic
return -ENODEV;
endpoint = &interface->endpoint[0].desc;
if (!(endpoint->bEndpointAddress & 0x80))
if (!usb_endpoint_dir_in(endpoint))
return -ENODEV;
/*
@ -392,8 +392,7 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic
device_remove_file(mc->dev, &dev_attrs[i]);
out:
if (mc) {
if (mc->irq)
usb_free_urb(mc->irq);
usb_free_urb(mc->irq);
if (mc->data)
usb_buffer_free(dev, URB_INT_SIZE, mc->data, mc->data_dma);
if (mc->dev)

View file

@ -95,3 +95,7 @@ int usb_ftdi_elan_edset_setup(struct platform_device *pdev, u8 ed_number,
int halted, int skipped, int actual, int non_null));
int usb_ftdi_elan_edset_flush(struct platform_device *pdev, u8 ed_number,
void *endp);
int usb_ftdi_elan_read_pcimem(struct platform_device *pdev, int mem_offset,
u8 width, u32 *data);
int usb_ftdi_elan_write_pcimem(struct platform_device *pdev, int mem_offset,
u8 width, u32 data);

View file

@ -138,7 +138,7 @@ get_endpoints (struct usbtest_dev *dev, struct usb_interface *intf)
default:
continue;
}
if (e->desc.bEndpointAddress & USB_DIR_IN) {
if (usb_endpoint_dir_in(&e->desc)) {
if (!in)
in = e;
} else {
@ -147,7 +147,7 @@ get_endpoints (struct usbtest_dev *dev, struct usb_interface *intf)
}
continue;
try_iso:
if (e->desc.bEndpointAddress & USB_DIR_IN) {
if (usb_endpoint_dir_in(&e->desc)) {
if (!iso_in)
iso_in = e;
} else {

View file

@ -249,9 +249,9 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
req->bRequest = cmd;
req->wValue = value;
req->wIndex = index;
req->wLength = size;
req->wValue = cpu_to_le16(value);
req->wIndex = cpu_to_le16(index);
req->wLength = cpu_to_le16(size);
usb_fill_control_urb(urb, dev->udev,
usb_sndctrlpipe(dev->udev, 0),

View file

@ -786,14 +786,10 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
if ((!catc->ctrl_urb) || (!catc->tx_urb) ||
(!catc->rx_urb) || (!catc->irq_urb)) {
err("No free urbs available.");
if (catc->ctrl_urb)
usb_free_urb(catc->ctrl_urb);
if (catc->tx_urb)
usb_free_urb(catc->tx_urb);
if (catc->rx_urb)
usb_free_urb(catc->rx_urb);
if (catc->irq_urb)
usb_free_urb(catc->irq_urb);
usb_free_urb(catc->ctrl_urb);
usb_free_urb(catc->tx_urb);
usb_free_urb(catc->rx_urb);
usb_free_urb(catc->irq_urb);
free_netdev(netdev);
return -ENOMEM;
}

View file

@ -200,8 +200,7 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
dev->status = &info->control->cur_altsetting->endpoint [0];
desc = &dev->status->desc;
if (desc->bmAttributes != USB_ENDPOINT_XFER_INT
|| !(desc->bEndpointAddress & USB_DIR_IN)
if (!usb_endpoint_is_int_in(desc)
|| (le16_to_cpu(desc->wMaxPacketSize)
< sizeof(struct usb_cdc_notification))
|| !desc->bInterval) {

View file

@ -237,12 +237,12 @@ static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl)
#define STATUS_CONN_OTHER (1 << 14)
#define STATUS_SUSPEND_OTHER (1 << 13)
#define STATUS_MAILBOX_OTHER (1 << 12)
#define STATUS_PACKETS_OTHER(n) (((n) >> 8) && 0x03)
#define STATUS_PACKETS_OTHER(n) (((n) >> 8) & 0x03)
#define STATUS_CONN_THIS (1 << 6)
#define STATUS_SUSPEND_THIS (1 << 5)
#define STATUS_MAILBOX_THIS (1 << 4)
#define STATUS_PACKETS_THIS(n) (((n) >> 0) && 0x03)
#define STATUS_PACKETS_THIS(n) (((n) >> 0) & 0x03)
#define STATUS_UNSPEC_MASK 0x0c8c
#define STATUS_NOISE_MASK ((u16)~(0x0303|STATUS_UNSPEC_MASK))

View file

@ -163,6 +163,7 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
/* using ATOMIC, we'd never wake up if we slept */
if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
set_current_state(TASK_RUNNING);
if (ret == -ENODEV)
netif_device_detach(pegasus->net);
if (netif_msg_drv(pegasus))

View file

@ -116,7 +116,7 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
e = alt->endpoint + ep;
switch (e->desc.bmAttributes) {
case USB_ENDPOINT_XFER_INT:
if (!(e->desc.bEndpointAddress & USB_DIR_IN))
if (!usb_endpoint_dir_in(&e->desc))
continue;
intr = 1;
/* FALLTHROUGH */
@ -125,7 +125,7 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
default:
continue;
}
if (e->desc.bEndpointAddress & USB_DIR_IN) {
if (usb_endpoint_dir_in(&e->desc)) {
if (!intr && !in)
in = e;
else if (intr && !status)

View file

@ -554,6 +554,17 @@ config USB_SERIAL_OMNINET
To compile this driver as a module, choose M here: the
module will be called omninet.
config USB_SERIAL_DEBUG
tristate "USB Debugging Device"
depends on USB_SERIAL
help
Say Y here if you have a USB debugging device used to recieve
debugging data from another machine. The most common of these
devices is the NetChip TurboCONNECT device.
To compile this driver as a module, choose M here: the
module will be called usb-debug.
config USB_EZUSB
bool
depends on USB_SERIAL_KEYSPAN_PDA || USB_SERIAL_XIRCOM || USB_SERIAL_KEYSPAN || USB_SERIAL_WHITEHEAT

View file

@ -18,6 +18,7 @@ obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o
obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o
obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o
obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o
obj-$(CONFIG_USB_SERIAL_DEBUG) += usb_debug.o
obj-$(CONFIG_USB_SERIAL_DIGI_ACCELEPORT) += digi_acceleport.o
obj-$(CONFIG_USB_SERIAL_EDGEPORT) += io_edgeport.o
obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += io_ti.o

View file

@ -270,8 +270,11 @@ static void aircable_read(void *params)
*/
tty = port->tty;
if (!tty)
if (!tty) {
schedule_work(&priv->rx_work);
err("%s - No tty available", __FUNCTION__);
return ;
}
count = min(64, serial_buf_data_avail(priv->rx_buf));
@ -305,9 +308,7 @@ static int aircable_probe(struct usb_serial *serial,
for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
endpoint = &iface_desc->endpoint[i].desc;
if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
((endpoint->bmAttributes & 3) == 0x02)) {
/* we found our bulk out endpoint */
if (usb_endpoint_is_bulk_out(endpoint)) {
dbg("found bulk out on endpoint %d", i);
++num_bulk_out;
}

View file

@ -19,6 +19,7 @@
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
{ USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */
{ USB_DEVICE(0x1410, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */
{ USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */
{ },
};

View file

@ -85,10 +85,9 @@ static int ark3116_attach(struct usb_serial *serial)
int i;
for (i = 0; i < serial->num_ports; ++i) {
priv = kmalloc(sizeof (struct ark3116_private), GFP_KERNEL);
priv = kzalloc(sizeof(struct ark3116_private), GFP_KERNEL);
if (!priv)
goto cleanup;
memset(priv, 0x00, sizeof (struct ark3116_private));
spin_lock_init(&priv->lock);
usb_set_serial_port_data(serial->port[i], priv);

View file

@ -166,19 +166,17 @@ static int usb_console_setup(struct console *co, char *options)
if (serial->type->set_termios) {
/* build up a fake tty structure so that the open call has something
* to look at to get the cflag value */
tty = kmalloc (sizeof (*tty), GFP_KERNEL);
tty = kzalloc(sizeof(*tty), GFP_KERNEL);
if (!tty) {
err ("no more memory");
return -ENOMEM;
}
termios = kmalloc (sizeof (*termios), GFP_KERNEL);
termios = kzalloc(sizeof(*termios), GFP_KERNEL);
if (!termios) {
err ("no more memory");
kfree (tty);
return -ENOMEM;
}
memset (tty, 0x00, sizeof(*tty));
memset (termios, 0x00, sizeof(*termios));
termios->c_cflag = cflag;
tty->termios = termios;
port->tty = tty;

View file

@ -1684,15 +1684,14 @@ static int __init cypress_init(void)
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
failed_usb_register:
usb_deregister(&cypress_driver);
failed_ca42v2_register:
usb_serial_deregister(&cypress_ca42v2_device);
failed_hidcom_register:
usb_serial_deregister(&cypress_hidcom_device);
failed_em_register:
usb_serial_deregister(&cypress_earthmate_device);
failed_usb_register:
usb_serial_deregister(&cypress_ca42v2_device);
failed_ca42v2_register:
usb_serial_deregister(&cypress_hidcom_device);
failed_hidcom_register:
usb_serial_deregister(&cypress_earthmate_device);
failed_em_register:
return retval;
}

View file

@ -31,12 +31,11 @@ int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *da
return -ENODEV;
}
transfer_buffer = kmalloc (length, GFP_KERNEL);
transfer_buffer = kmemdup(data, length, GFP_KERNEL);
if (!transfer_buffer) {
dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, length);
return -ENOMEM;
}
memcpy (transfer_buffer, data, length);
result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 3000);
kfree (transfer_buffer);
return result;

View file

@ -1388,8 +1388,7 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp)
flush_scheduled_work();
/* shutdown our bulk read */
if (port->read_urb)
usb_kill_urb(port->read_urb);
usb_kill_urb(port->read_urb);
} /* ftdi_close */

View file

@ -1523,12 +1523,11 @@ static int garmin_attach (struct usb_serial *serial)
dbg("%s", __FUNCTION__);
garmin_data_p = kmalloc (sizeof(struct garmin_data), GFP_KERNEL);
garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL);
if (garmin_data_p == NULL) {
dev_err(&port->dev, "%s - Out of memory\n", __FUNCTION__);
return -ENOMEM;
}
memset (garmin_data_p, 0, sizeof(struct garmin_data));
init_timer(&garmin_data_p->timer);
spin_lock_init(&garmin_data_p->lock);
INIT_LIST_HEAD(&garmin_data_p->pktlist);

View file

@ -1038,9 +1038,7 @@ static void edge_close (struct usb_serial_port *port, struct file * filp)
edge_port->open = FALSE;
edge_port->openPending = FALSE;
if (edge_port->write_urb) {
usb_kill_urb(edge_port->write_urb);
}
usb_kill_urb(edge_port->write_urb);
if (edge_port->write_urb) {
/* if this urb had a transfer buffer already (old transfer) free it */

View file

@ -206,10 +206,9 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
dbg("%s", __FUNCTION__);
buf_flow_init = kmalloc(16, GFP_KERNEL);
buf_flow_init = kmemdup(buf_flow_static, 16, GFP_KERNEL);
if (!buf_flow_init)
return -ENOMEM;
memcpy(buf_flow_init, buf_flow_static, 16);
if (port->tty)
port->tty->low_latency = 1;

View file

@ -2306,22 +2306,16 @@ static void keyspan_shutdown (struct usb_serial *serial)
}
/* Now free them */
if (s_priv->instat_urb)
usb_free_urb(s_priv->instat_urb);
if (s_priv->glocont_urb)
usb_free_urb(s_priv->glocont_urb);
usb_free_urb(s_priv->instat_urb);
usb_free_urb(s_priv->glocont_urb);
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
p_priv = usb_get_serial_port_data(port);
if (p_priv->inack_urb)
usb_free_urb(p_priv->inack_urb);
if (p_priv->outcont_urb)
usb_free_urb(p_priv->outcont_urb);
usb_free_urb(p_priv->inack_urb);
usb_free_urb(p_priv->outcont_urb);
for (j = 0; j < 2; j++) {
if (p_priv->in_urbs[j])
usb_free_urb(p_priv->in_urbs[j]);
if (p_priv->out_urbs[j])
usb_free_urb(p_priv->out_urbs[j]);
usb_free_urb(p_priv->in_urbs[j]);
usb_free_urb(p_priv->out_urbs[j]);
}
}

View file

@ -185,13 +185,11 @@ static int kobil_startup (struct usb_serial *serial)
for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
endpoint = &altsetting->endpoint[i];
if (((endpoint->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
((endpoint->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
if (usb_endpoint_is_int_out(&endpoint->desc)) {
dbg("%s Found interrupt out endpoint. Address: %d", __FUNCTION__, endpoint->desc.bEndpointAddress);
priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress;
}
if (((endpoint->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
((endpoint->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
if (usb_endpoint_is_int_in(&endpoint->desc)) {
dbg("%s Found interrupt in endpoint. Address: %d", __FUNCTION__, endpoint->desc.bEndpointAddress);
priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress;
}
@ -355,8 +353,7 @@ static void kobil_close (struct usb_serial_port *port, struct file *filp)
usb_free_urb( port->write_urb );
port->write_urb = NULL;
}
if (port->interrupt_in_urb)
usb_kill_urb(port->interrupt_in_urb);
usb_kill_urb(port->interrupt_in_urb);
}

View file

@ -358,10 +358,8 @@ static int mct_u232_startup (struct usb_serial *serial)
/* Puh, that's dirty */
port = serial->port[0];
rport = serial->port[1];
if (port->read_urb) {
/* No unlinking, it wasn't submitted yet. */
usb_free_urb(port->read_urb);
}
/* No unlinking, it wasn't submitted yet. */
usb_free_urb(port->read_urb);
port->read_urb = rport->interrupt_in_urb;
rport->interrupt_in_urb = NULL;
port->read_urb->context = port;

View file

@ -2596,12 +2596,11 @@ static int mos7840_startup(struct usb_serial *serial)
/* set up port private structures */
for (i = 0; i < serial->num_ports; ++i) {
mos7840_port = kmalloc(sizeof(struct moschip_port), GFP_KERNEL);
mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
if (mos7840_port == NULL) {
err("%s - Out of memory", __FUNCTION__);
return -ENOMEM;
}
memset(mos7840_port, 0, sizeof(struct moschip_port));
/* Initialize all port interrupt end point to port 0 int endpoint *
* Our device has only one interrupt end point comman to all port */

View file

@ -95,8 +95,7 @@ static void navman_close(struct usb_serial_port *port, struct file *filp)
{
dbg("%s - port %d", __FUNCTION__, port->number);
if (port->interrupt_in_urb)
usb_kill_urb(port->interrupt_in_urb);
usb_kill_urb(port->interrupt_in_urb);
}
static int navman_write(struct usb_serial_port *port,

View file

@ -228,6 +228,7 @@ static int product_5052_count;
/* null entry */
static struct usb_device_id ti_id_table_3410[1+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
};
static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
@ -239,6 +240,7 @@ static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
static struct usb_device_id ti_id_table_combined[] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
@ -459,13 +461,12 @@ static int ti_startup(struct usb_serial *serial)
/* set up port structures */
for (i = 0; i < serial->num_ports; ++i) {
tport = kmalloc(sizeof(struct ti_port), GFP_KERNEL);
tport = kzalloc(sizeof(struct ti_port), GFP_KERNEL);
if (tport == NULL) {
dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
status = -ENOMEM;
goto free_tports;
}
memset(tport, 0, sizeof(struct ti_port));
spin_lock_init(&tport->tp_lock);
tport->tp_uart_base_addr = (i == 0 ? TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;

View file

@ -28,6 +28,7 @@
/* Vendor and product ids */
#define TI_VENDOR_ID 0x0451
#define TI_3410_PRODUCT_ID 0x3410
#define TI_3410_EZ430_ID 0xF430 /* TI ez430 development tool */
#define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */
#define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */
#define TI_5052_EEPROM_PRODUCT_ID 0x505A /* EEPROM, no firmware */

View file

@ -952,32 +952,28 @@ int usb_serial_probe(struct usb_interface *interface,
port = serial->port[i];
if (!port)
continue;
if (port->read_urb)
usb_free_urb (port->read_urb);
usb_free_urb(port->read_urb);
kfree(port->bulk_in_buffer);
}
for (i = 0; i < num_bulk_out; ++i) {
port = serial->port[i];
if (!port)
continue;
if (port->write_urb)
usb_free_urb (port->write_urb);
usb_free_urb(port->write_urb);
kfree(port->bulk_out_buffer);
}
for (i = 0; i < num_interrupt_in; ++i) {
port = serial->port[i];
if (!port)
continue;
if (port->interrupt_in_urb)
usb_free_urb (port->interrupt_in_urb);
usb_free_urb(port->interrupt_in_urb);
kfree(port->interrupt_in_buffer);
}
for (i = 0; i < num_interrupt_out; ++i) {
port = serial->port[i];
if (!port)
continue;
if (port->interrupt_out_urb)
usb_free_urb (port->interrupt_out_urb);
usb_free_urb(port->interrupt_out_urb);
kfree(port->interrupt_out_buffer);
}

View file

@ -0,0 +1,65 @@
/*
* USB Debug cable driver
*
* Copyright (C) 2006 Greg Kroah-Hartman <greg@kroah.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x0525, 0x127a) },
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver debug_driver = {
.name = "debug",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
.no_dynamic_id = 1,
};
static struct usb_serial_driver debug_device = {
.driver = {
.owner = THIS_MODULE,
.name = "debug",
},
.id_table = id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
.num_bulk_out = NUM_DONT_CARE,
.num_ports = 1,
};
static int __init debug_init(void)
{
int retval;
retval = usb_serial_register(&debug_device);
if (retval)
return retval;
retval = usb_register(&debug_driver);
if (retval)
usb_serial_deregister(&debug_device);
return retval;
}
static void __exit debug_exit(void)
{
usb_deregister(&debug_driver);
usb_serial_deregister(&debug_device);
}
module_init(debug_init);
module_exit(debug_exit);
MODULE_LICENSE("GPL");

View file

@ -348,8 +348,7 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
/* shutdown our urbs */
usb_kill_urb(port->read_urb);
if (port->interrupt_in_urb)
usb_kill_urb(port->interrupt_in_urb);
usb_kill_urb(port->interrupt_in_urb);
/* Try to send shutdown message, if the device is gone, this will just fail. */
transfer_buffer = kmalloc (0x12, GFP_KERNEL);

View file

@ -142,10 +142,7 @@ int onetouch_connect_input(struct us_data *ss)
return -ENODEV;
endpoint = &interface->endpoint[2].desc;
if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -ENODEV;
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
!= USB_ENDPOINT_XFER_INT)
if (!usb_endpoint_is_int_in(endpoint))
return -ENODEV;
pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);

View file

@ -1318,6 +1318,16 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110,
US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
0 ),
/* Reported by Jaco Kroon <jaco@kroon.co.za>
* The usb-storage module found on the Digitech GNX4 (and supposedly other
* devices) misbehaves and causes a bunch of invalid I/O errors.
*/
UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100,
"Digitech HMG",
"DigiTech Mass Storage",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001,
"Minolta",

View file

@ -740,18 +740,16 @@ static int get_pipes(struct us_data *us)
ep = &altsetting->endpoint[i].desc;
/* Is it a BULK endpoint? */
if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
== USB_ENDPOINT_XFER_BULK) {
if (usb_endpoint_xfer_bulk(ep)) {
/* BULK in or out? */
if (ep->bEndpointAddress & USB_DIR_IN)
if (usb_endpoint_dir_in(ep))
ep_in = ep;
else
ep_out = ep;
}
/* Is it an interrupt endpoint? */
else if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
== USB_ENDPOINT_XFER_INT) {
else if (usb_endpoint_xfer_int(ep)) {
ep_int = ep;
}
}

View file

@ -313,8 +313,13 @@ struct usb_bus {
/* This is arbitrary.
* From USB 2.0 spec Table 11-13, offset 7, a hub can
* have up to 255 ports. The most yet reported is 10.
*
* Current Wireless USB host hardware (Intel i1480 for example) allows
* up to 22 devices to connect. Upcoming hardware might raise that
* limit. Because the arrays need to add a bit for hub status data, we
* do 31, so plus one evens out to four bytes.
*/
#define USB_MAXCHILDREN (16)
#define USB_MAXCHILDREN (31)
struct usb_tt;
@ -357,7 +362,8 @@ struct usb_device {
u8 portnum; /* Parent port number (origin 1) */
u8 level; /* Number of USB hub ancestors */
int have_langid; /* whether string_langid is valid */
unsigned discon_suspended:1; /* Disconnected while suspended */
unsigned have_langid:1; /* whether string_langid is valid */
int string_langid; /* language ID for strings */
/* static strings from the device */
@ -410,14 +416,37 @@ extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
/* USB autosuspend and autoresume */
#ifdef CONFIG_USB_SUSPEND
extern int usb_autopm_set_interface(struct usb_interface *intf);
extern int usb_autopm_get_interface(struct usb_interface *intf);
extern void usb_autopm_put_interface(struct usb_interface *intf);
#else
#define usb_autopm_get_interface(intf) 0
#define usb_autopm_put_interface(intf) do {} while (0)
#endif
static inline void usb_autopm_enable(struct usb_interface *intf)
{
intf->pm_usage_cnt = 0;
usb_autopm_set_interface(intf);
}
static inline void usb_autopm_disable(struct usb_interface *intf)
{
intf->pm_usage_cnt = 1;
usb_autopm_set_interface(intf);
}
#else
static inline int usb_autopm_set_interface(struct usb_interface *intf)
{ return 0; }
static inline int usb_autopm_get_interface(struct usb_interface *intf)
{ return 0; }
static inline void usb_autopm_put_interface(struct usb_interface *intf)
{ }
static inline void usb_autopm_enable(struct usb_interface *intf)
{ }
static inline void usb_autopm_disable(struct usb_interface *intf)
{ }
#endif
/*-------------------------------------------------------------------------*/
@ -490,17 +519,137 @@ static inline int usb_make_path (struct usb_device *dev, char *buf,
/*-------------------------------------------------------------------------*/
extern int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd);
extern int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd);
extern int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd);
extern int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd);
extern int usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd);
extern int usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd);
extern int usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd);
extern int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd);
extern int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd);
extern int usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd);
extern int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd);
/**
* usb_endpoint_dir_in - check if the endpoint has IN direction
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type IN, otherwise it returns false.
*/
static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
}
/**
* usb_endpoint_dir_out - check if the endpoint has OUT direction
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type OUT, otherwise it returns false.
*/
static inline int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
}
/**
* usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type bulk, otherwise it returns false.
*/
static inline int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_BULK);
}
/**
* usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type interrupt, otherwise it returns
* false.
*/
static inline int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_INT);
}
/**
* usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type isochronous, otherwise it returns
* false.
*/
static inline int usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_ISOC);
}
/**
* usb_endpoint_is_bulk_in - check if the endpoint is bulk IN
* @epd: endpoint to be checked
*
* Returns true if the endpoint has bulk transfer type and IN direction,
* otherwise it returns false.
*/
static inline int usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd));
}
/**
* usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT
* @epd: endpoint to be checked
*
* Returns true if the endpoint has bulk transfer type and OUT direction,
* otherwise it returns false.
*/
static inline int usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd));
}
/**
* usb_endpoint_is_int_in - check if the endpoint is interrupt IN
* @epd: endpoint to be checked
*
* Returns true if the endpoint has interrupt transfer type and IN direction,
* otherwise it returns false.
*/
static inline int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd));
}
/**
* usb_endpoint_is_int_out - check if the endpoint is interrupt OUT
* @epd: endpoint to be checked
*
* Returns true if the endpoint has interrupt transfer type and OUT direction,
* otherwise it returns false.
*/
static inline int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd));
}
/**
* usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN
* @epd: endpoint to be checked
*
* Returns true if the endpoint has isochronous transfer type and IN direction,
* otherwise it returns false.
*/
static inline int usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd));
}
/**
* usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT
* @epd: endpoint to be checked
*
* Returns true if the endpoint has isochronous transfer type and OUT direction,
* otherwise it returns false.
*/
static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd)
{
return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd));
}
/*-------------------------------------------------------------------------*/

View file

@ -981,7 +981,7 @@ void snd_usbmidi_disconnect(struct list_head* p)
if (umidi->usb_protocol_ops->finish_out_endpoint)
umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
}
if (ep->in && ep->in->urb)
if (ep->in)
usb_kill_urb(ep->in->urb);
}
}

View file

@ -1620,8 +1620,7 @@ static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
kfree(mixer->urb->transfer_buffer);
usb_free_urb(mixer->urb);
}
if (mixer->rc_urb)
usb_free_urb(mixer->rc_urb);
usb_free_urb(mixer->rc_urb);
kfree(mixer->rc_setup_packet);
kfree(mixer);
}
@ -2056,8 +2055,6 @@ void snd_usb_mixer_disconnect(struct list_head *p)
struct usb_mixer_interface *mixer;
mixer = list_entry(p, struct usb_mixer_interface, list);
if (mixer->urb)
usb_kill_urb(mixer->urb);
if (mixer->rc_urb)
usb_kill_urb(mixer->rc_urb);
usb_kill_urb(mixer->urb);
usb_kill_urb(mixer->rc_urb);
}