mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/usb/input/hid.h
This commit is contained in:
commit
bef986502f
4033 changed files with 156908 additions and 79616 deletions
|
|
@ -24,7 +24,7 @@ config USB_ARCH_HAS_OHCI
|
|||
default y if ARCH_S3C2410
|
||||
default y if PXA27x
|
||||
default y if ARCH_EP93XX
|
||||
default y if (ARCH_AT91RM9200 || ARCH_AT91SAM9261)
|
||||
default y if ARCH_AT91
|
||||
default y if ARCH_PNX4008
|
||||
# PPC:
|
||||
default y if STB03xxx
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ struct cxacru_data {
|
|||
const struct cxacru_modem_type *modem_type;
|
||||
|
||||
int line_status;
|
||||
struct work_struct poll_work;
|
||||
struct delayed_work poll_work;
|
||||
|
||||
/* contol handles */
|
||||
struct mutex cm_serialize;
|
||||
|
|
@ -347,7 +347,7 @@ static int cxacru_card_status(struct cxacru_data *instance)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void cxacru_poll_status(struct cxacru_data *instance);
|
||||
static void cxacru_poll_status(struct work_struct *work);
|
||||
|
||||
static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
|
||||
struct atm_dev *atm_dev)
|
||||
|
|
@ -376,12 +376,14 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
|
|||
}
|
||||
|
||||
/* Start status polling */
|
||||
cxacru_poll_status(instance);
|
||||
cxacru_poll_status(&instance->poll_work.work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cxacru_poll_status(struct cxacru_data *instance)
|
||||
static void cxacru_poll_status(struct work_struct *work)
|
||||
{
|
||||
struct cxacru_data *instance =
|
||||
container_of(work, struct cxacru_data, poll_work.work);
|
||||
u32 buf[CXINF_MAX] = {};
|
||||
struct usbatm_data *usbatm = instance->usbatm;
|
||||
struct atm_dev *atm_dev = usbatm->atm_dev;
|
||||
|
|
@ -720,7 +722,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
|
|||
|
||||
mutex_init(&instance->cm_serialize);
|
||||
|
||||
INIT_WORK(&instance->poll_work, (void *)cxacru_poll_status, instance);
|
||||
INIT_DELAYED_WORK(&instance->poll_work, cxacru_poll_status);
|
||||
|
||||
usbatm_instance->driver_data = instance;
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ struct speedtch_instance_data {
|
|||
|
||||
struct speedtch_params params; /* set in probe, constant afterwards */
|
||||
|
||||
struct work_struct status_checker;
|
||||
struct delayed_work status_checker;
|
||||
|
||||
unsigned char last_status;
|
||||
|
||||
|
|
@ -498,8 +498,11 @@ static int speedtch_start_synchro(struct speedtch_instance_data *instance)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void speedtch_check_status(struct speedtch_instance_data *instance)
|
||||
static void speedtch_check_status(struct work_struct *work)
|
||||
{
|
||||
struct speedtch_instance_data *instance =
|
||||
container_of(work, struct speedtch_instance_data,
|
||||
status_checker.work);
|
||||
struct usbatm_data *usbatm = instance->usbatm;
|
||||
struct atm_dev *atm_dev = usbatm->atm_dev;
|
||||
unsigned char *buf = instance->scratch_buffer;
|
||||
|
|
@ -576,7 +579,7 @@ static void speedtch_status_poll(unsigned long data)
|
|||
{
|
||||
struct speedtch_instance_data *instance = (void *)data;
|
||||
|
||||
schedule_work(&instance->status_checker);
|
||||
schedule_delayed_work(&instance->status_checker, 0);
|
||||
|
||||
/* The following check is racy, but the race is harmless */
|
||||
if (instance->poll_delay < MAX_POLL_DELAY)
|
||||
|
|
@ -596,7 +599,7 @@ static void speedtch_resubmit_int(unsigned long data)
|
|||
if (int_urb) {
|
||||
ret = usb_submit_urb(int_urb, GFP_ATOMIC);
|
||||
if (!ret)
|
||||
schedule_work(&instance->status_checker);
|
||||
schedule_delayed_work(&instance->status_checker, 0);
|
||||
else {
|
||||
atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret);
|
||||
mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY));
|
||||
|
|
@ -640,7 +643,7 @@ static void speedtch_handle_int(struct urb *int_urb)
|
|||
|
||||
if ((int_urb = instance->int_urb)) {
|
||||
ret = usb_submit_urb(int_urb, GFP_ATOMIC);
|
||||
schedule_work(&instance->status_checker);
|
||||
schedule_delayed_work(&instance->status_checker, 0);
|
||||
if (ret < 0) {
|
||||
atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret);
|
||||
goto fail;
|
||||
|
|
@ -834,8 +837,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -855,7 +858,7 @@ static int speedtch_bind(struct usbatm_data *usbatm,
|
|||
|
||||
usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0);
|
||||
|
||||
INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance);
|
||||
INIT_DELAYED_WORK(&instance->status_checker, speedtch_check_status);
|
||||
|
||||
instance->status_checker.timer.function = speedtch_status_poll;
|
||||
instance->status_checker.timer.data = (unsigned long)instance;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@
|
|||
#include <linux/kthread.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/freezer.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "usbatm.h"
|
||||
|
|
@ -401,9 +403,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 +596,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);
|
||||
|
|
@ -658,9 +657,9 @@ static int request_dsp(struct uea_softc *sc)
|
|||
/*
|
||||
* The uea_load_page() function must be called within a process context
|
||||
*/
|
||||
static void uea_load_page(void *xsc)
|
||||
static void uea_load_page(struct work_struct *work)
|
||||
{
|
||||
struct uea_softc *sc = xsc;
|
||||
struct uea_softc *sc = container_of(work, struct uea_softc, task);
|
||||
u16 pageno = sc->pageno;
|
||||
u16 ovl = sc->ovl;
|
||||
struct block_info bi;
|
||||
|
|
@ -765,12 +764,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,
|
||||
|
|
@ -1352,7 +1350,7 @@ static int uea_boot(struct uea_softc *sc)
|
|||
|
||||
uea_enters(INS_TO_USBDEV(sc));
|
||||
|
||||
INIT_WORK(&sc->task, uea_load_page, sc);
|
||||
INIT_WORK(&sc->task, uea_load_page);
|
||||
init_waitqueue_head(&sc->sync_q);
|
||||
init_waitqueue_head(&sc->cmv_ack_wait);
|
||||
|
||||
|
|
|
|||
|
|
@ -421,9 +421,9 @@ static void acm_write_bulk(struct urb *urb)
|
|||
schedule_work(&acm->work);
|
||||
}
|
||||
|
||||
static void acm_softint(void *private)
|
||||
static void acm_softint(struct work_struct *work)
|
||||
{
|
||||
struct acm *acm = private;
|
||||
struct acm *acm = container_of(work, struct acm, work);
|
||||
dbg("Entering acm_softint.");
|
||||
|
||||
if (!ACM_READY(acm))
|
||||
|
|
@ -892,7 +892,7 @@ skip_normal_probe:
|
|||
|
||||
|
||||
/* 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");
|
||||
|
|
@ -927,7 +927,7 @@ skip_normal_probe:
|
|||
acm->rx_buflimit = num_rx_buf;
|
||||
acm->urb_task.func = acm_rx_tasklet;
|
||||
acm->urb_task.data = (unsigned long) acm;
|
||||
INIT_WORK(&acm->work, acm_softint, acm);
|
||||
INIT_WORK(&acm->work, acm_softint);
|
||||
spin_lock_init(&acm->throttle_lock);
|
||||
spin_lock_init(&acm->write_lock);
|
||||
spin_lock_init(&acm->read_lock);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ void hcd_buffer_destroy (struct usb_hcd *hcd)
|
|||
}
|
||||
|
||||
|
||||
/* sometimes alloc/free could use kmalloc with SLAB_DMA, for
|
||||
/* sometimes alloc/free could use kmalloc with GFP_DMA, for
|
||||
* better sharing and to leverage mm/slab.c intelligence.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 @@ done:
|
|||
}
|
||||
|
||||
/* 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 @@ done:
|
|||
}
|
||||
|
||||
/* 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 @@ done:
|
|||
}
|
||||
|
||||
/* 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 @@ done:
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -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 @@ error_group:
|
|||
destroy_endpoint_class();
|
||||
return retval;
|
||||
|
||||
error_chrdev:
|
||||
endpoint_free_minor(ep_dev);
|
||||
|
||||
error_register:
|
||||
kfree(ep_dev);
|
||||
error_alloc:
|
||||
|
|
@ -271,14 +341,16 @@ exit:
|
|||
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/usbdevice_fs.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/freezer.h>
|
||||
|
||||
#include <asm/semaphore.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
|
@ -31,6 +32,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 delayed_work 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 +87,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);
|
||||
|
|
@ -167,9 +219,10 @@ static void set_port_led(
|
|||
|
||||
#define LED_CYCLE_PERIOD ((2*HZ)/3)
|
||||
|
||||
static void led_work (void *__hub)
|
||||
static void led_work (struct work_struct *work)
|
||||
{
|
||||
struct usb_hub *hub = __hub;
|
||||
struct usb_hub *hub =
|
||||
container_of(work, struct usb_hub, leds.work);
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
unsigned i;
|
||||
unsigned changed = 0;
|
||||
|
|
@ -276,6 +329,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);
|
||||
|
|
@ -351,9 +407,10 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
|
|||
* talking to TTs must queue control transfers (not just bulk and iso), so
|
||||
* both can talk to the same hub concurrently.
|
||||
*/
|
||||
static void hub_tt_kevent (void *arg)
|
||||
static void hub_tt_kevent (struct work_struct *work)
|
||||
{
|
||||
struct usb_hub *hub = arg;
|
||||
struct usb_hub *hub =
|
||||
container_of(work, struct usb_hub, tt.kevent);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave (&hub->tt.lock, flags);
|
||||
|
|
@ -404,7 +461,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
|
|||
* since each TT has "at least two" buffers that can need it (and
|
||||
* there can be many TTs per hub). even if they're uncommon.
|
||||
*/
|
||||
if ((clear = kmalloc (sizeof *clear, SLAB_ATOMIC)) == NULL) {
|
||||
if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) {
|
||||
dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
|
||||
/* FIXME recover somehow ... RESET_TT? */
|
||||
return;
|
||||
|
|
@ -457,7 +514,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 +529,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);
|
||||
|
|
@ -641,7 +697,7 @@ static int hub_configure(struct usb_hub *hub,
|
|||
|
||||
spin_lock_init (&hub->tt.lock);
|
||||
INIT_LIST_HEAD (&hub->tt.clear_list);
|
||||
INIT_WORK (&hub->tt.kevent, hub_tt_kevent, hub);
|
||||
INIT_WORK (&hub->tt.kevent, hub_tt_kevent);
|
||||
switch (hdev->descriptor.bDeviceProtocol) {
|
||||
case 0:
|
||||
break;
|
||||
|
|
@ -759,7 +815,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));
|
||||
|
||||
|
|
@ -880,9 +941,10 @@ descriptor_error:
|
|||
INIT_LIST_HEAD(&hub->event_list);
|
||||
hub->intfdev = &intf->dev;
|
||||
hub->hdev = hdev;
|
||||
INIT_WORK(&hub->leds, led_work, hub);
|
||||
INIT_DELAYED_WORK(&hub->leds, led_work);
|
||||
|
||||
usb_set_intfdata (intf, hub);
|
||||
intf->needs_remote_wakeup = 1;
|
||||
|
||||
if (hdev->speed == USB_SPEED_HIGH)
|
||||
highspeed_hubs++;
|
||||
|
|
@ -980,6 +1042,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 +1233,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 +1263,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 +1369,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 +1426,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 +1779,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 +1798,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 +1812,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 +1881,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 +1954,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 +1978,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 +2022,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);
|
||||
}
|
||||
|
||||
|
|
@ -2269,7 +2372,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
|
|||
struct usb_qualifier_descriptor *qual;
|
||||
int status;
|
||||
|
||||
qual = kmalloc (sizeof *qual, SLAB_KERNEL);
|
||||
qual = kmalloc (sizeof *qual, GFP_KERNEL);
|
||||
if (qual == NULL)
|
||||
return;
|
||||
|
||||
|
|
@ -2281,7 +2384,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
|
|||
/* hub LEDs are probably harder to miss than syslog */
|
||||
if (hub->has_indicators) {
|
||||
hub->indicator[port1-1] = INDICATOR_GREEN_BLINK;
|
||||
schedule_work (&hub->leds);
|
||||
schedule_delayed_work (&hub->leds, 0);
|
||||
}
|
||||
}
|
||||
kfree(qual);
|
||||
|
|
@ -2455,7 +2558,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
|||
if (hub->has_indicators) {
|
||||
hub->indicator[port1-1] =
|
||||
INDICATOR_AMBER_BLINK;
|
||||
schedule_work (&hub->leds);
|
||||
schedule_delayed_work (&hub->leds, 0);
|
||||
}
|
||||
status = -ENOTCONN; /* Don't retry */
|
||||
goto loop_disable;
|
||||
|
|
@ -2555,16 +2658,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 +2685,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 +2704,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 +2832,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 +2877,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)
|
||||
|
|
@ -2818,7 +2923,7 @@ static int config_descriptors_changed(struct usb_device *udev)
|
|||
if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
|
||||
len = le16_to_cpu(udev->config[index].desc.wTotalLength);
|
||||
}
|
||||
buf = kmalloc (len, SLAB_KERNEL);
|
||||
buf = kmalloc (len, GFP_KERNEL);
|
||||
if (buf == NULL) {
|
||||
dev_err(&udev->dev, "no mem to re-read configs after reset\n");
|
||||
/* assume the worst */
|
||||
|
|
@ -2997,7 +3102,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 +3145,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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ void usb_sg_wait (struct usb_sg_request *io)
|
|||
int retval;
|
||||
|
||||
io->urbs [i]->dev = io->dev;
|
||||
retval = usb_submit_urb (io->urbs [i], SLAB_ATOMIC);
|
||||
retval = usb_submit_urb (io->urbs [i], GFP_ATOMIC);
|
||||
|
||||
/* after we submit, let completions or cancelations fire;
|
||||
* we handshake using io->status.
|
||||
|
|
@ -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",
|
||||
|
|
@ -828,10 +828,7 @@ char *usb_cache_string(struct usb_device *udev, int index)
|
|||
* Context: !in_interrupt ()
|
||||
*
|
||||
* Updates the copy of the device descriptor stored in the device structure,
|
||||
* which dedicates space for this purpose. Note that several fields are
|
||||
* converted to the host CPU's byte order: the USB version (bcdUSB), and
|
||||
* vendors product and version fields (idVendor, idProduct, and bcdDevice).
|
||||
* That lets device drivers compare against non-byteswapped constants.
|
||||
* which dedicates space for this purpose.
|
||||
*
|
||||
* Not exported, only for use by the core. If drivers really want to read
|
||||
* the device descriptor directly, they can call usb_get_descriptor() with
|
||||
|
|
@ -1401,7 +1398,7 @@ free_interfaces:
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
|
|
@ -1424,7 +1421,7 @@ free_interfaces:
|
|||
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);
|
||||
|
|
@ -1493,7 +1490,7 @@ free_interfaces:
|
|||
usb_create_sysfs_intf_files (intf);
|
||||
}
|
||||
|
||||
usb_autosuspend_device(dev, 1);
|
||||
usb_autosuspend_device(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1504,9 +1501,10 @@ struct set_config_request {
|
|||
};
|
||||
|
||||
/* Worker routine for usb_driver_set_configuration() */
|
||||
static void driver_set_config_work(void *_req)
|
||||
static void driver_set_config_work(struct work_struct *work)
|
||||
{
|
||||
struct set_config_request *req = _req;
|
||||
struct set_config_request *req =
|
||||
container_of(work, struct set_config_request, work);
|
||||
|
||||
usb_lock_device(req->udev);
|
||||
usb_set_configuration(req->udev, req->config);
|
||||
|
|
@ -1544,7 +1542,7 @@ int usb_driver_set_configuration(struct usb_device *udev, int config)
|
|||
return -ENOMEM;
|
||||
req->udev = udev;
|
||||
req->config = config;
|
||||
INIT_WORK(&req->work, driver_set_config_work, req);
|
||||
INIT_WORK(&req->work, driver_set_config_work);
|
||||
|
||||
usb_get_dev(udev);
|
||||
if (!schedule_work(&req->work)) {
|
||||
|
|
|
|||
|
|
@ -200,19 +200,13 @@ 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 */
|
||||
static void usb_autosuspend_work(void *_udev)
|
||||
static void usb_autosuspend_work(struct work_struct *work)
|
||||
{
|
||||
struct usb_device *udev = _udev;
|
||||
struct usb_device *udev =
|
||||
container_of(work, struct usb_device, autosuspend.work);
|
||||
|
||||
usb_pm_lock(udev);
|
||||
udev->auto_pm = 1;
|
||||
|
|
@ -222,10 +216,17 @@ static void usb_autosuspend_work(void *_udev)
|
|||
|
||||
#else
|
||||
|
||||
static void usb_autosuspend_work(void *_udev)
|
||||
static void usb_autosuspend_work(struct work_struct *work)
|
||||
{}
|
||||
|
||||
#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)
|
||||
|
|
@ -304,7 +305,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
|
|||
|
||||
#ifdef CONFIG_PM
|
||||
mutex_init(&dev->pm_mutex);
|
||||
INIT_WORK(&dev->autosuspend, usb_autosuspend_work, dev);
|
||||
INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work);
|
||||
#endif
|
||||
return dev;
|
||||
}
|
||||
|
|
@ -537,138 +538,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 +971,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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ config USB_OTG
|
|||
|
||||
config USB_GADGET_AT91
|
||||
boolean "AT91 USB Device Port"
|
||||
depends on ARCH_AT91RM9200
|
||||
depends on ARCH_AT91
|
||||
select USB_GADGET_SELECTED
|
||||
help
|
||||
Many Atmel AT91 processors (such as the AT91RM2000) have a
|
||||
|
|
|
|||
|
|
@ -1833,9 +1833,9 @@ static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags)
|
|||
spin_unlock_irqrestore(&dev->req_lock, flags);
|
||||
}
|
||||
|
||||
static void eth_work (void *_dev)
|
||||
static void eth_work (struct work_struct *work)
|
||||
{
|
||||
struct eth_dev *dev = _dev;
|
||||
struct eth_dev *dev = container_of(work, struct eth_dev, work);
|
||||
|
||||
if (test_and_clear_bit (WORK_RX_MEMORY, &dev->todo)) {
|
||||
if (netif_running (dev->net))
|
||||
|
|
@ -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;
|
||||
|
|
@ -2398,7 +2398,7 @@ autoconf_fail:
|
|||
dev = netdev_priv(net);
|
||||
spin_lock_init (&dev->lock);
|
||||
spin_lock_init (&dev->req_lock);
|
||||
INIT_WORK (&dev->work, eth_work, dev);
|
||||
INIT_WORK (&dev->work, eth_work);
|
||||
INIT_LIST_HEAD (&dev->tx_reqs);
|
||||
INIT_LIST_HEAD (&dev->rx_reqs);
|
||||
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/utsname.h>
|
||||
|
||||
#include <linux/usb_ch9.h>
|
||||
|
|
|
|||
|
|
@ -1236,7 +1236,7 @@ autoconf_fail:
|
|||
|
||||
|
||||
/* ok, we made sense of the hardware ... */
|
||||
dev = kzalloc(sizeof(*dev), SLAB_KERNEL);
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1864,7 +1864,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
}
|
||||
|
||||
/* alloc, and start init */
|
||||
dev = kmalloc (sizeof *dev, SLAB_KERNEL);
|
||||
dev = kmalloc (sizeof *dev, GFP_KERNEL);
|
||||
if (dev == NULL){
|
||||
pr_debug("enomem %s\n", pci_name(pdev));
|
||||
retval = -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
|||
/* FIXME readahead for O_NONBLOCK and poll(); careful with ZLPs */
|
||||
|
||||
value = -ENOMEM;
|
||||
kbuf = kmalloc (len, SLAB_KERNEL);
|
||||
kbuf = kmalloc (len, GFP_KERNEL);
|
||||
if (unlikely (!kbuf))
|
||||
goto free1;
|
||||
|
||||
|
|
@ -456,7 +456,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
|||
/* FIXME writebehind for O_NONBLOCK and poll(), qlen = 1 */
|
||||
|
||||
value = -ENOMEM;
|
||||
kbuf = kmalloc (len, SLAB_KERNEL);
|
||||
kbuf = kmalloc (len, GFP_KERNEL);
|
||||
if (!kbuf)
|
||||
goto free1;
|
||||
if (copy_from_user (kbuf, buf, len)) {
|
||||
|
|
@ -1898,7 +1898,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
|||
buf += 4;
|
||||
length -= 4;
|
||||
|
||||
kbuf = kmalloc (length, SLAB_KERNEL);
|
||||
kbuf = kmalloc (length, GFP_KERNEL);
|
||||
if (!kbuf)
|
||||
return -ENOMEM;
|
||||
if (copy_from_user (kbuf, buf, length)) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 @@ delegate:
|
|||
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);
|
||||
|
|
@ -2857,7 +2861,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
}
|
||||
|
||||
/* alloc, and start init */
|
||||
dev = kzalloc (sizeof *dev, SLAB_KERNEL);
|
||||
dev = kzalloc (sizeof *dev, GFP_KERNEL);
|
||||
if (dev == NULL){
|
||||
retval = -ENOMEM;
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -2581,7 +2581,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
|
|||
/* UDC_PULLUP_EN gates the chip clock */
|
||||
// OTG_SYSCON_1_REG |= DEV_IDLE_EN;
|
||||
|
||||
udc = kzalloc(sizeof(*udc), SLAB_KERNEL);
|
||||
udc = kzalloc(sizeof(*udc), GFP_KERNEL);
|
||||
if (!udc)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1190,7 +1190,7 @@ autoconf_fail:
|
|||
|
||||
|
||||
/* ok, we made sense of the hardware ... */
|
||||
dev = kzalloc(sizeof(*dev), SLAB_KERNEL);
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
spin_lock_init (&dev->lock);
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ config USB_U132_HCD
|
|||
adapter will *NOT* work with PC cards that do not contain an OHCI
|
||||
controller.
|
||||
|
||||
For those PC cards that contain multiple OHCI controllers only ther
|
||||
For those PC cards that contain multiple OHCI controllers only the
|
||||
first one is used.
|
||||
|
||||
The driver consists of two modules, the "ftdi-elan" module is a
|
||||
|
|
|
|||
|
|
@ -492,7 +492,7 @@ show_periodic (struct class_device *class_dev, char *buf)
|
|||
unsigned i;
|
||||
__le32 tag;
|
||||
|
||||
if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC)))
|
||||
if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC)))
|
||||
return 0;
|
||||
seen_count = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ restart:
|
|||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ static DEFINE_TIMER(bulk_eot_timer, NULL, 0, 0);
|
|||
#define CHECK_ALIGN(x) if (((__u32)(x)) & 0x00000003) \
|
||||
{panic("Alignment check (DWORD) failed at %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);}
|
||||
|
||||
#define SLAB_FLAG (in_interrupt() ? SLAB_ATOMIC : SLAB_KERNEL)
|
||||
#define SLAB_FLAG (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
|
||||
#define KMALLOC_FLAG (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
|
||||
|
||||
/* Most helpful debugging aid */
|
||||
|
|
@ -275,13 +275,13 @@ static volatile USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4)));
|
|||
static int zout_buffer[4] __attribute__ ((aligned (4)));
|
||||
|
||||
/* Cache for allocating new EP and SB descriptors. */
|
||||
static kmem_cache_t *usb_desc_cache;
|
||||
static struct kmem_cache *usb_desc_cache;
|
||||
|
||||
/* Cache for the registers allocated in the top half. */
|
||||
static kmem_cache_t *top_half_reg_cache;
|
||||
static struct kmem_cache *top_half_reg_cache;
|
||||
|
||||
/* Cache for the data allocated in the isoc descr top half. */
|
||||
static kmem_cache_t *isoc_compl_cache;
|
||||
static struct kmem_cache *isoc_compl_cache;
|
||||
|
||||
static struct usb_bus *etrax_usb_bus;
|
||||
|
||||
|
|
@ -1743,7 +1743,7 @@ static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc)
|
|||
|
||||
*R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do);
|
||||
|
||||
comp_data = (usb_isoc_complete_data_t*)kmem_cache_alloc(isoc_compl_cache, SLAB_ATOMIC);
|
||||
comp_data = (usb_isoc_complete_data_t*)kmem_cache_alloc(isoc_compl_cache, GFP_ATOMIC);
|
||||
assert(comp_data != NULL);
|
||||
|
||||
INIT_WORK(&comp_data->usb_bh, etrax_usb_isoc_descr_interrupt_bottom_half, comp_data);
|
||||
|
|
@ -3010,7 +3010,7 @@ static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid)
|
|||
if (!urb->iso_frame_desc[i].length)
|
||||
continue;
|
||||
|
||||
next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_ATOMIC);
|
||||
next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_ATOMIC);
|
||||
assert(next_sb_desc != NULL);
|
||||
|
||||
if (urb->iso_frame_desc[i].length > 0) {
|
||||
|
|
@ -3063,7 +3063,7 @@ static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid)
|
|||
if (TxIsocEPList[epid].sub == 0) {
|
||||
dbg_isoc("Isoc traffic not already running, allocating SB");
|
||||
|
||||
next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_ATOMIC);
|
||||
next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_ATOMIC);
|
||||
assert(next_sb_desc != NULL);
|
||||
|
||||
next_sb_desc->command = (IO_STATE(USB_SB_command, tt, in) |
|
||||
|
|
@ -3317,7 +3317,7 @@ static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc)
|
|||
|
||||
restore_flags(flags);
|
||||
|
||||
reg = (usb_interrupt_registers_t *)kmem_cache_alloc(top_half_reg_cache, SLAB_ATOMIC);
|
||||
reg = (usb_interrupt_registers_t *)kmem_cache_alloc(top_half_reg_cache, GFP_ATOMIC);
|
||||
|
||||
assert(reg != NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -505,7 +505,7 @@ show_periodic (struct class_device *class_dev, char *buf)
|
|||
char *next;
|
||||
unsigned i;
|
||||
|
||||
if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC)))
|
||||
if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC)))
|
||||
return 0;
|
||||
seen_count = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -715,13 +715,6 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
|
|||
return IRQ_NOTMINE;
|
||||
}
|
||||
|
||||
if (ints & OHCI_INTR_RHSC) {
|
||||
ohci_vdbg (ohci, "rhsc\n");
|
||||
ohci->next_statechange = jiffies + STATECHANGE_DELAY;
|
||||
ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrstatus);
|
||||
usb_hcd_poll_rh_status(hcd);
|
||||
}
|
||||
|
||||
if (ints & OHCI_INTR_UE) {
|
||||
disable (ohci);
|
||||
ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
|
||||
|
|
@ -731,9 +724,31 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
|
|||
ohci_usb_reset (ohci);
|
||||
}
|
||||
|
||||
if (ints & OHCI_INTR_RD) {
|
||||
ohci_vdbg (ohci, "resume detect\n");
|
||||
ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus);
|
||||
if (ints & OHCI_INTR_RHSC) {
|
||||
ohci_vdbg(ohci, "rhsc\n");
|
||||
ohci->next_statechange = jiffies + STATECHANGE_DELAY;
|
||||
ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC,
|
||||
®s->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, ®s->intrdisable);
|
||||
usb_hcd_poll_rh_status(hcd);
|
||||
}
|
||||
|
||||
/* For connect and disconnect events, we expect the controller
|
||||
* to turn on RHSC along with RD. But for remote wakeup events
|
||||
* this might not happen.
|
||||
*/
|
||||
else if (ints & OHCI_INTR_RD) {
|
||||
ohci_vdbg(ohci, "resume detect\n");
|
||||
ohci_writel(ohci, OHCI_INTR_RD, ®s->intrstatus);
|
||||
hcd->poll_rh = 1;
|
||||
if (ohci->autostop) {
|
||||
spin_lock (&ohci->lock);
|
||||
|
|
@ -930,7 +945,7 @@ MODULE_LICENSE ("GPL");
|
|||
#include "ohci-ppc-soc.c"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_AT91RM9200) || defined(CONFIG_ARCH_AT91SAM9261)
|
||||
#ifdef CONFIG_ARCH_AT91
|
||||
#include "ohci-at91.c"
|
||||
#endif
|
||||
|
||||
|
|
@ -947,8 +962,7 @@ MODULE_LICENSE ("GPL");
|
|||
|| defined (CONFIG_ARCH_EP93XX) \
|
||||
|| defined (CONFIG_SOC_AU1X00) \
|
||||
|| defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
|
||||
|| defined (CONFIG_ARCH_AT91RM9200) \
|
||||
|| defined (CONFIG_ARCH_AT91SAM9261) \
|
||||
|| defined (CONFIG_ARCH_AT91) \
|
||||
|| defined (CONFIG_ARCH_PNX4008) \
|
||||
)
|
||||
#error "missing bus glue for ohci-hcd"
|
||||
|
|
|
|||
|
|
@ -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,8 @@ __acquires(ohci->lock)
|
|||
break;
|
||||
case OHCI_USB_RESUME:
|
||||
/* HCFS changes sometime after INTR_RD */
|
||||
ohci_info (ohci, "wakeup\n");
|
||||
ohci_dbg(ohci, "%swakeup root hub\n",
|
||||
autostopped ? "auto-" : "");
|
||||
break;
|
||||
case OHCI_USB_OPER:
|
||||
/* this can happen after resuming a swsusp snapshot */
|
||||
|
|
@ -180,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);
|
||||
|
|
@ -190,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);
|
||||
|
||||
|
|
@ -216,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;
|
||||
}
|
||||
|
||||
|
|
@ -295,8 +288,6 @@ skip_resume:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int ohci_bus_suspend (struct usb_hcd *hcd)
|
||||
{
|
||||
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||
|
|
@ -334,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 */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
|
@ -345,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);
|
||||
|
|
@ -386,66 +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 (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);
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ static int isp1301_attach(struct i2c_adapter *adap, int addr, int kind)
|
|||
{
|
||||
struct i2c_client *c;
|
||||
|
||||
c = (struct i2c_client *)kzalloc(sizeof(*c), SLAB_KERNEL);
|
||||
c = (struct i2c_client *)kzalloc(sizeof(*c), GFP_KERNEL);
|
||||
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -169,21 +169,14 @@ static int sl811_cs_config(struct pcmcia_device *link)
|
|||
|
||||
DBG(0, "sl811_cs_config(0x%p)\n", link);
|
||||
|
||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
|
||||
link->conf.ConfigBase = parse.config.base;
|
||||
link->conf.Present = parse.config.rmask[0];
|
||||
|
||||
/* Look up the current Vcc */
|
||||
CS_CHECK(GetConfigurationInfo,
|
||||
pcmcia_get_configuration_info(link, &conf));
|
||||
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
@ -163,7 +163,7 @@ struct u132_endp {
|
|||
u16 queue_next;
|
||||
struct urb *urb_list[ENDP_QUEUE_SIZE];
|
||||
struct list_head urb_more;
|
||||
struct work_struct scheduler;
|
||||
struct delayed_work scheduler;
|
||||
};
|
||||
struct u132_ring {
|
||||
unsigned in_use:1;
|
||||
|
|
@ -171,7 +171,7 @@ struct u132_ring {
|
|||
u8 number;
|
||||
struct u132 *u132;
|
||||
struct u132_endp *curr_endp;
|
||||
struct work_struct scheduler;
|
||||
struct delayed_work scheduler;
|
||||
};
|
||||
#define OHCI_QUIRK_AMD756 0x01
|
||||
#define OHCI_QUIRK_SUPERIO 0x02
|
||||
|
|
@ -198,20 +198,16 @@ struct u132 {
|
|||
u32 hc_roothub_portstatus[MAX_ROOT_PORTS];
|
||||
int flags;
|
||||
unsigned long next_statechange;
|
||||
struct work_struct monitor;
|
||||
struct delayed_work monitor;
|
||||
int num_endpoints;
|
||||
struct u132_addr addr[MAX_U132_ADDRS];
|
||||
struct u132_udev udev[MAX_U132_UDEVS];
|
||||
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 can not be inlines because we need the structure offset!!
|
||||
* these cannot be inlines because we need the structure offset!!
|
||||
* Does anyone have a better way?????
|
||||
*/
|
||||
#define u132_read_pcimem(u132, member, data) \
|
||||
|
|
@ -314,7 +310,7 @@ static void u132_ring_requeue_work(struct u132 *u132, struct u132_ring *ring,
|
|||
if (delta > 0) {
|
||||
if (queue_delayed_work(workqueue, &ring->scheduler, delta))
|
||||
return;
|
||||
} else if (queue_work(workqueue, &ring->scheduler))
|
||||
} else if (queue_delayed_work(workqueue, &ring->scheduler, 0))
|
||||
return;
|
||||
kref_put(&u132->kref, u132_hcd_delete);
|
||||
return;
|
||||
|
|
@ -393,12 +389,8 @@ static inline void u132_endp_init_kref(struct u132 *u132,
|
|||
static void u132_endp_queue_work(struct u132 *u132, struct u132_endp *endp,
|
||||
unsigned int delta)
|
||||
{
|
||||
if (delta > 0) {
|
||||
if (queue_delayed_work(workqueue, &endp->scheduler, delta))
|
||||
kref_get(&endp->kref);
|
||||
} else if (queue_work(workqueue, &endp->scheduler))
|
||||
kref_get(&endp->kref);
|
||||
return;
|
||||
if (queue_delayed_work(workqueue, &endp->scheduler, delta))
|
||||
kref_get(&endp->kref);
|
||||
}
|
||||
|
||||
static void u132_endp_cancel_work(struct u132 *u132, struct u132_endp *endp)
|
||||
|
|
@ -414,24 +406,14 @@ static inline void u132_monitor_put_kref(struct u132 *u132)
|
|||
|
||||
static void u132_monitor_queue_work(struct u132 *u132, unsigned int delta)
|
||||
{
|
||||
if (delta > 0) {
|
||||
if (queue_delayed_work(workqueue, &u132->monitor, delta)) {
|
||||
kref_get(&u132->kref);
|
||||
}
|
||||
} else if (queue_work(workqueue, &u132->monitor))
|
||||
kref_get(&u132->kref);
|
||||
return;
|
||||
if (queue_delayed_work(workqueue, &u132->monitor, delta))
|
||||
kref_get(&u132->kref);
|
||||
}
|
||||
|
||||
static void u132_monitor_requeue_work(struct u132 *u132, unsigned int delta)
|
||||
{
|
||||
if (delta > 0) {
|
||||
if (queue_delayed_work(workqueue, &u132->monitor, delta))
|
||||
return;
|
||||
} else if (queue_work(workqueue, &u132->monitor))
|
||||
return;
|
||||
kref_put(&u132->kref, u132_hcd_delete);
|
||||
return;
|
||||
if (!queue_delayed_work(workqueue, &u132->monitor, delta))
|
||||
kref_put(&u132->kref, u132_hcd_delete);
|
||||
}
|
||||
|
||||
static void u132_monitor_cancel_work(struct u132 *u132)
|
||||
|
|
@ -493,9 +475,9 @@ static int read_roothub_info(struct u132 *u132)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void u132_hcd_monitor_work(void *data)
|
||||
static void u132_hcd_monitor_work(struct work_struct *work)
|
||||
{
|
||||
struct u132 *u132 = data;
|
||||
struct u132 *u132 = container_of(work, struct u132, monitor.work);
|
||||
if (u132->going > 1) {
|
||||
dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
|
||||
, u132->going);
|
||||
|
|
@ -1319,15 +1301,14 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf,
|
|||
}
|
||||
}
|
||||
|
||||
static void u132_hcd_ring_work_scheduler(void *data);
|
||||
static void u132_hcd_endp_work_scheduler(void *data);
|
||||
/*
|
||||
* this work function is only executed from the work queue
|
||||
*
|
||||
*/
|
||||
static void u132_hcd_ring_work_scheduler(void *data)
|
||||
static void u132_hcd_ring_work_scheduler(struct work_struct *work)
|
||||
{
|
||||
struct u132_ring *ring = data;
|
||||
struct u132_ring *ring =
|
||||
container_of(work, struct u132_ring, scheduler.work);
|
||||
struct u132 *u132 = ring->u132;
|
||||
down(&u132->scheduler_lock);
|
||||
if (ring->in_use) {
|
||||
|
|
@ -1386,10 +1367,11 @@ static void u132_hcd_ring_work_scheduler(void *data)
|
|||
}
|
||||
}
|
||||
|
||||
static void u132_hcd_endp_work_scheduler(void *data)
|
||||
static void u132_hcd_endp_work_scheduler(struct work_struct *work)
|
||||
{
|
||||
struct u132_ring *ring;
|
||||
struct u132_endp *endp = data;
|
||||
struct u132_endp *endp =
|
||||
container_of(work, struct u132_endp, scheduler.work);
|
||||
struct u132 *u132 = endp->u132;
|
||||
down(&u132->scheduler_lock);
|
||||
ring = endp->ring;
|
||||
|
|
@ -1947,7 +1929,7 @@ static int create_endpoint_and_queue_int(struct u132 *u132,
|
|||
if (!endp) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp);
|
||||
INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler);
|
||||
spin_lock_init(&endp->queue_lock.slock);
|
||||
INIT_LIST_HEAD(&endp->urb_more);
|
||||
ring = endp->ring = &u132->ring[0];
|
||||
|
|
@ -2036,7 +2018,7 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132,
|
|||
if (!endp) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp);
|
||||
INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler);
|
||||
spin_lock_init(&endp->queue_lock.slock);
|
||||
INIT_LIST_HEAD(&endp->urb_more);
|
||||
endp->dequeueing = 0;
|
||||
|
|
@ -2121,7 +2103,7 @@ static int create_endpoint_and_queue_control(struct u132 *u132,
|
|||
if (!endp) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp);
|
||||
INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler);
|
||||
spin_lock_init(&endp->queue_lock.slock);
|
||||
INIT_LIST_HEAD(&endp->urb_more);
|
||||
ring = endp->ring = &u132->ring[0];
|
||||
|
|
@ -3045,7 +3027,7 @@ static struct hc_driver u132_hc_driver = {
|
|||
* This function may be called by the USB core whilst the "usb_all_devices_rwsem"
|
||||
* is held for writing, thus this module must not call usb_remove_hcd()
|
||||
* synchronously - but instead should immediately stop activity to the
|
||||
* device and ansynchronously call usb_remove_hcd()
|
||||
* device and asynchronously call usb_remove_hcd()
|
||||
*/
|
||||
static int __devexit u132_remove(struct platform_device *pdev)
|
||||
{
|
||||
|
|
@ -3100,10 +3082,10 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev)
|
|||
ring->number = rings + 1;
|
||||
ring->length = 0;
|
||||
ring->curr_endp = NULL;
|
||||
INIT_WORK(&ring->scheduler, u132_hcd_ring_work_scheduler,
|
||||
(void *)ring);
|
||||
INIT_DELAYED_WORK(&ring->scheduler,
|
||||
u132_hcd_ring_work_scheduler);
|
||||
} down(&u132->sw_lock);
|
||||
INIT_WORK(&u132->monitor, u132_hcd_monitor_work, (void *)u132);
|
||||
INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work);
|
||||
while (ports-- > 0) {
|
||||
struct u132_port *port = &u132->port[ports];
|
||||
port->u132 = u132;
|
||||
|
|
@ -3241,7 +3223,7 @@ static int u132_resume(struct platform_device *pdev)
|
|||
#define u132_resume NULL
|
||||
#endif
|
||||
/*
|
||||
* this driver is loaded explicitely by ftdi_u132
|
||||
* this driver is loaded explicitly by ftdi_u132
|
||||
*
|
||||
* the platform_driver struct is static because it is per type of module
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ MODULE_PARM_DESC(debug, "Debug level");
|
|||
static char *errbuf;
|
||||
#define ERRBUF_LEN (32 * 1024)
|
||||
|
||||
static kmem_cache_t *uhci_up_cachep; /* urb_priv */
|
||||
static struct kmem_cache *uhci_up_cachep; /* urb_priv */
|
||||
|
||||
static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state);
|
||||
static void wakeup_rh(struct uhci_hcd *uhci);
|
||||
|
|
|
|||
|
|
@ -498,7 +498,7 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
|
|||
{
|
||||
struct urb_priv *urbp;
|
||||
|
||||
urbp = kmem_cache_alloc(uhci_up_cachep, SLAB_ATOMIC);
|
||||
urbp = kmem_cache_alloc(uhci_up_cachep, GFP_ATOMIC);
|
||||
if (!urbp)
|
||||
return NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
|
|||
if (!acecad || !input_dev)
|
||||
goto fail1;
|
||||
|
||||
acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma);
|
||||
acecad->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &acecad->data_dma);
|
||||
if (!acecad->data)
|
||||
goto fail1;
|
||||
|
||||
|
|
|
|||
|
|
@ -1988,7 +1988,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
goto fail1;
|
||||
|
||||
aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
|
||||
SLAB_ATOMIC, &aiptek->data_dma);
|
||||
GFP_ATOMIC, &aiptek->data_dma);
|
||||
if (!aiptek->data)
|
||||
goto fail1;
|
||||
|
||||
|
|
|
|||
|
|
@ -592,7 +592,7 @@ static void ati_remote_irq_in(struct urb *urb)
|
|||
__FUNCTION__, urb->status);
|
||||
}
|
||||
|
||||
retval = usb_submit_urb(urb, SLAB_ATOMIC);
|
||||
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n",
|
||||
__FUNCTION__, retval);
|
||||
|
|
@ -604,12 +604,12 @@ static void ati_remote_irq_in(struct urb *urb)
|
|||
static int ati_remote_alloc_buffers(struct usb_device *udev,
|
||||
struct ati_remote *ati_remote)
|
||||
{
|
||||
ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
|
||||
ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC,
|
||||
&ati_remote->inbuf_dma);
|
||||
if (!ati_remote->inbuf)
|
||||
return -1;
|
||||
|
||||
ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
|
||||
ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC,
|
||||
&ati_remote->outbuf_dma);
|
||||
if (!ati_remote->outbuf)
|
||||
return -1;
|
||||
|
|
@ -630,19 +630,14 @@ 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);
|
||||
usb_free_urb(ati_remote->irq_urb);
|
||||
usb_free_urb(ati_remote->out_urb);
|
||||
|
||||
if (ati_remote->out_urb)
|
||||
usb_free_urb(ati_remote->out_urb);
|
||||
usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
|
||||
ati_remote->inbuf, ati_remote->inbuf_dma);
|
||||
|
||||
if (ati_remote->inbuf)
|
||||
usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
|
||||
ati_remote->inbuf, ati_remote->inbuf_dma);
|
||||
|
||||
if (ati_remote->outbuf)
|
||||
usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
|
||||
ati_remote->inbuf, ati_remote->outbuf_dma);
|
||||
usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
|
||||
ati_remote->outbuf, ati_remote->outbuf_dma);
|
||||
}
|
||||
|
||||
static void ati_remote_input_init(struct ati_remote *ati_remote)
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -968,20 +968,30 @@ static void hid_retry_timeout(unsigned long _hid)
|
|||
hid_io_error(hid);
|
||||
}
|
||||
|
||||
/* Workqueue routine to reset the device */
|
||||
static void hid_reset(void *_hid)
|
||||
/* Workqueue routine to reset the device or clear a halt */
|
||||
static void hid_reset(struct work_struct *work)
|
||||
{
|
||||
struct hid_device *hid = (struct hid_device *) _hid;
|
||||
int rc_lock, rc;
|
||||
struct hid_device *hid =
|
||||
container_of(work, struct hid_device, reset_work);
|
||||
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 +1033,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 +1058,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 */
|
||||
|
|
@ -1065,7 +1079,7 @@ static void hid_irq_in(struct urb *urb)
|
|||
warn("input irq status %d received", urb->status);
|
||||
}
|
||||
|
||||
status = usb_submit_urb(urb, SLAB_ATOMIC);
|
||||
status = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (status) {
|
||||
clear_bit(HID_IN_RUNNING, &hid->iofl);
|
||||
if (status != -EPERM) {
|
||||
|
|
@ -1627,6 +1641,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
|
||||
|
|
@ -1797,16 +1824,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 },
|
||||
{ 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 },
|
||||
{ USB_VENDOR_ID_APPLE, 0x0219, 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 },
|
||||
|
|
@ -1839,13 +1869,13 @@ static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *
|
|||
|
||||
static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
|
||||
{
|
||||
if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma)))
|
||||
if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->inbuf_dma)))
|
||||
return -1;
|
||||
if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma)))
|
||||
if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->outbuf_dma)))
|
||||
return -1;
|
||||
if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma)))
|
||||
if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), GFP_ATOMIC, &hid->cr_dma)))
|
||||
return -1;
|
||||
if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma)))
|
||||
if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->ctrlbuf_dma)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
|
@ -1989,7 +2019,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)))
|
||||
|
|
@ -2019,7 +2049,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
|
|||
|
||||
init_waitqueue_head(&hid->wait);
|
||||
|
||||
INIT_WORK(&hid->reset_work, hid_reset, hid);
|
||||
INIT_WORK(&hid->reset_work, hid_reset);
|
||||
setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid);
|
||||
|
||||
spin_lock_init(&hid->inlock);
|
||||
|
|
@ -2071,13 +2101,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);
|
||||
|
||||
|
|
@ -2108,8 +2134,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);
|
||||
|
|
|
|||
|
|
@ -121,6 +121,12 @@ static struct hidinput_key_translation powerbook_numlock_keys[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
static struct hidinput_key_translation powerbook_iso_keyboard[] = {
|
||||
{ KEY_GRAVE, KEY_102ND },
|
||||
{ KEY_102ND, KEY_GRAVE },
|
||||
{ }
|
||||
};
|
||||
|
||||
static int usbhid_pb_fnmode = 1;
|
||||
module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
|
||||
MODULE_PARM_DESC(pb_fnmode,
|
||||
|
|
@ -195,6 +201,14 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
|
|||
}
|
||||
}
|
||||
|
||||
if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) {
|
||||
trans = find_translation(powerbook_iso_keyboard, usage->code);
|
||||
if (trans) {
|
||||
input_event(input, usage->type, trans->to, value);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -210,6 +224,9 @@ static void hidinput_pb_setup(struct input_dev *input)
|
|||
|
||||
for (trans = powerbook_numlock_keys; trans->from; trans++)
|
||||
set_bit(trans->to, input->keybit);
|
||||
|
||||
for (trans = powerbook_iso_keyboard; trans->from; trans++)
|
||||
set_bit(trans->to, input->keybit);
|
||||
}
|
||||
#else
|
||||
static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
|
||||
|
|
|
|||
|
|
@ -260,7 +260,8 @@ struct hid_item {
|
|||
#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000
|
||||
#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000
|
||||
#define HID_QUIRK_INVERT_HWHEEL 0x00004000
|
||||
#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00008000
|
||||
#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000
|
||||
#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000
|
||||
|
||||
/*
|
||||
* This is the global environment of the parser. This information is
|
||||
|
|
@ -385,6 +386,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;
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
|
|||
remote->in_endpoint = endpoint;
|
||||
remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */
|
||||
|
||||
remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
|
||||
remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma);
|
||||
if (!remote->in_buffer) {
|
||||
retval = -ENOMEM;
|
||||
goto fail1;
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ static int mtouchusb_alloc_buffers(struct usb_device *udev, struct mtouch_usb *m
|
|||
dbg("%s - called", __FUNCTION__);
|
||||
|
||||
mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE,
|
||||
SLAB_ATOMIC, &mtouch->data_dma);
|
||||
GFP_ATOMIC, &mtouch->data_dma);
|
||||
|
||||
if (!mtouch->data)
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -277,12 +277,12 @@ static int powermate_input_event(struct input_dev *dev, unsigned int type, unsig
|
|||
static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm)
|
||||
{
|
||||
pm->data = usb_buffer_alloc(udev, POWERMATE_PAYLOAD_SIZE_MAX,
|
||||
SLAB_ATOMIC, &pm->data_dma);
|
||||
GFP_ATOMIC, &pm->data_dma);
|
||||
if (!pm->data)
|
||||
return -1;
|
||||
|
||||
pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)),
|
||||
SLAB_ATOMIC, &pm->configcr_dma);
|
||||
GFP_ATOMIC, &pm->configcr_dma);
|
||||
if (!pm->configcr)
|
||||
return -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ static int touchkit_alloc_buffers(struct usb_device *udev,
|
|||
struct touchkit_usb *touchkit)
|
||||
{
|
||||
touchkit->data = usb_buffer_alloc(udev, TOUCHKIT_REPORT_DATA_SIZE,
|
||||
SLAB_ATOMIC, &touchkit->data_dma);
|
||||
GFP_ATOMIC, &touchkit->data_dma);
|
||||
|
||||
if (!touchkit->data)
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ static void usb_kbd_irq(struct urb *urb)
|
|||
memcpy(kbd->old, kbd->new, 8);
|
||||
|
||||
resubmit:
|
||||
i = usb_submit_urb (urb, SLAB_ATOMIC);
|
||||
i = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (i)
|
||||
err ("can't resubmit intr, %s-%s/input0, status %d",
|
||||
kbd->usbdev->bus->bus_name,
|
||||
|
|
@ -196,11 +196,11 @@ static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
|
|||
return -1;
|
||||
if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL)))
|
||||
return -1;
|
||||
if (!(kbd->new = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kbd->new_dma)))
|
||||
if (!(kbd->new = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
|
||||
return -1;
|
||||
if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), SLAB_ATOMIC, &kbd->cr_dma)))
|
||||
if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), GFP_ATOMIC, &kbd->cr_dma)))
|
||||
return -1;
|
||||
if (!(kbd->leds = usb_buffer_alloc(dev, 1, SLAB_ATOMIC, &kbd->leds_dma)))
|
||||
if (!(kbd->leds = usb_buffer_alloc(dev, 1, GFP_ATOMIC, &kbd->leds_dma)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ static void usb_mouse_irq(struct urb *urb)
|
|||
|
||||
input_sync(dev);
|
||||
resubmit:
|
||||
status = usb_submit_urb (urb, SLAB_ATOMIC);
|
||||
status = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (status)
|
||||
err ("can't resubmit intr, %s-%s/input0, status %d",
|
||||
mouse->usbdev->bus->bus_name,
|
||||
|
|
@ -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);
|
||||
|
|
@ -139,7 +137,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
|
|||
if (!mouse || !input_dev)
|
||||
goto fail1;
|
||||
|
||||
mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma);
|
||||
mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma);
|
||||
if (!mouse->data)
|
||||
goto fail1;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <[email protected]>"
|
||||
#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
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -586,7 +680,7 @@ static int usbtouch_probe(struct usb_interface *intf,
|
|||
type->process_pkt = usbtouch_process_pkt;
|
||||
|
||||
usbtouch->data = usb_buffer_alloc(udev, type->rept_size,
|
||||
SLAB_KERNEL, &usbtouch->data_dma);
|
||||
GFP_KERNEL, &usbtouch->data_dma);
|
||||
if (!usbtouch->data)
|
||||
goto out_free;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
goto fail1;
|
||||
|
||||
xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
|
||||
SLAB_ATOMIC, &xpad->idata_dma);
|
||||
GFP_ATOMIC, &xpad->idata_dma);
|
||||
if (!xpad->idata)
|
||||
goto fail1;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -876,17 +874,17 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
|
||||
/* allocate usb buffers */
|
||||
yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
|
||||
SLAB_ATOMIC, &yld->irq_dma);
|
||||
GFP_ATOMIC, &yld->irq_dma);
|
||||
if (yld->irq_data == NULL)
|
||||
return usb_cleanup(yld, -ENOMEM);
|
||||
|
||||
yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
|
||||
SLAB_ATOMIC, &yld->ctl_dma);
|
||||
GFP_ATOMIC, &yld->ctl_dma);
|
||||
if (!yld->ctl_data)
|
||||
return usb_cleanup(yld, -ENOMEM);
|
||||
|
||||
yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)),
|
||||
SLAB_ATOMIC, &yld->ctl_req_dma);
|
||||
GFP_ATOMIC, &yld->ctl_req_dma);
|
||||
if (yld->ctl_req == NULL)
|
||||
return usb_cleanup(yld, -ENOMEM);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ struct appledisplay {
|
|||
char *urbdata; /* interrupt URB data buffer */
|
||||
char *msgdata; /* control message data buffer */
|
||||
|
||||
struct work_struct work;
|
||||
struct delayed_work work;
|
||||
int button_pressed;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
|
@ -117,7 +117,7 @@ static void appledisplay_complete(struct urb *urb)
|
|||
case ACD_BTN_BRIGHT_UP:
|
||||
case ACD_BTN_BRIGHT_DOWN:
|
||||
pdata->button_pressed = 1;
|
||||
queue_work(wq, &pdata->work);
|
||||
queue_delayed_work(wq, &pdata->work, 0);
|
||||
break;
|
||||
case ACD_BTN_NONE:
|
||||
default:
|
||||
|
|
@ -184,9 +184,10 @@ static struct backlight_properties appledisplay_bl_data = {
|
|||
.max_brightness = 0xFF
|
||||
};
|
||||
|
||||
static void appledisplay_work(void *private)
|
||||
static void appledisplay_work(struct work_struct *work)
|
||||
{
|
||||
struct appledisplay *pdata = private;
|
||||
struct appledisplay *pdata =
|
||||
container_of(work, struct appledisplay, work.work);
|
||||
int retval;
|
||||
|
||||
up(&pdata->bd->sem);
|
||||
|
|
@ -216,10 +217,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;
|
||||
|
|
@ -241,7 +239,7 @@ static int appledisplay_probe(struct usb_interface *iface,
|
|||
pdata->udev = udev;
|
||||
|
||||
spin_lock_init(&pdata->lock);
|
||||
INIT_WORK(&pdata->work, appledisplay_work, pdata);
|
||||
INIT_DELAYED_WORK(&pdata->work, appledisplay_work);
|
||||
|
||||
/* Allocate buffer for control messages */
|
||||
pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -780,7 +778,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned
|
|||
|
||||
bl_fail:/* not enough memory. Free allocated elements */
|
||||
dbg ("auerbuf_setup: no more memory");
|
||||
kfree(bep);
|
||||
auerbuf_free(bep);
|
||||
auerbuf_free_buffers (bcp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -156,9 +156,9 @@ struct usb_ftdi {
|
|||
struct usb_device *udev;
|
||||
struct usb_interface *interface;
|
||||
struct usb_class_driver *class;
|
||||
struct work_struct status_work;
|
||||
struct work_struct command_work;
|
||||
struct work_struct respond_work;
|
||||
struct delayed_work status_work;
|
||||
struct delayed_work command_work;
|
||||
struct delayed_work respond_work;
|
||||
struct u132_platform_data platform_data;
|
||||
struct resource resources[0];
|
||||
struct platform_device platform_dev;
|
||||
|
|
@ -210,23 +210,14 @@ static void ftdi_elan_init_kref(struct usb_ftdi *ftdi)
|
|||
|
||||
static void ftdi_status_requeue_work(struct usb_ftdi *ftdi, unsigned int delta)
|
||||
{
|
||||
if (delta > 0) {
|
||||
if (queue_delayed_work(status_queue, &ftdi->status_work, delta))
|
||||
return;
|
||||
} else if (queue_work(status_queue, &ftdi->status_work))
|
||||
return;
|
||||
kref_put(&ftdi->kref, ftdi_elan_delete);
|
||||
return;
|
||||
if (!queue_delayed_work(status_queue, &ftdi->status_work, delta))
|
||||
kref_put(&ftdi->kref, ftdi_elan_delete);
|
||||
}
|
||||
|
||||
static void ftdi_status_queue_work(struct usb_ftdi *ftdi, unsigned int delta)
|
||||
{
|
||||
if (delta > 0) {
|
||||
if (queue_delayed_work(status_queue, &ftdi->status_work, delta))
|
||||
kref_get(&ftdi->kref);
|
||||
} else if (queue_work(status_queue, &ftdi->status_work))
|
||||
kref_get(&ftdi->kref);
|
||||
return;
|
||||
if (queue_delayed_work(status_queue, &ftdi->status_work, delta))
|
||||
kref_get(&ftdi->kref);
|
||||
}
|
||||
|
||||
static void ftdi_status_cancel_work(struct usb_ftdi *ftdi)
|
||||
|
|
@ -237,25 +228,14 @@ static void ftdi_status_cancel_work(struct usb_ftdi *ftdi)
|
|||
|
||||
static void ftdi_command_requeue_work(struct usb_ftdi *ftdi, unsigned int delta)
|
||||
{
|
||||
if (delta > 0) {
|
||||
if (queue_delayed_work(command_queue, &ftdi->command_work,
|
||||
delta))
|
||||
return;
|
||||
} else if (queue_work(command_queue, &ftdi->command_work))
|
||||
return;
|
||||
kref_put(&ftdi->kref, ftdi_elan_delete);
|
||||
return;
|
||||
if (!queue_delayed_work(command_queue, &ftdi->command_work, delta))
|
||||
kref_put(&ftdi->kref, ftdi_elan_delete);
|
||||
}
|
||||
|
||||
static void ftdi_command_queue_work(struct usb_ftdi *ftdi, unsigned int delta)
|
||||
{
|
||||
if (delta > 0) {
|
||||
if (queue_delayed_work(command_queue, &ftdi->command_work,
|
||||
delta))
|
||||
kref_get(&ftdi->kref);
|
||||
} else if (queue_work(command_queue, &ftdi->command_work))
|
||||
kref_get(&ftdi->kref);
|
||||
return;
|
||||
if (queue_delayed_work(command_queue, &ftdi->command_work, delta))
|
||||
kref_get(&ftdi->kref);
|
||||
}
|
||||
|
||||
static void ftdi_command_cancel_work(struct usb_ftdi *ftdi)
|
||||
|
|
@ -267,25 +247,14 @@ static void ftdi_command_cancel_work(struct usb_ftdi *ftdi)
|
|||
static void ftdi_response_requeue_work(struct usb_ftdi *ftdi,
|
||||
unsigned int delta)
|
||||
{
|
||||
if (delta > 0) {
|
||||
if (queue_delayed_work(respond_queue, &ftdi->respond_work,
|
||||
delta))
|
||||
return;
|
||||
} else if (queue_work(respond_queue, &ftdi->respond_work))
|
||||
return;
|
||||
kref_put(&ftdi->kref, ftdi_elan_delete);
|
||||
return;
|
||||
if (!queue_delayed_work(respond_queue, &ftdi->respond_work, delta))
|
||||
kref_put(&ftdi->kref, ftdi_elan_delete);
|
||||
}
|
||||
|
||||
static void ftdi_respond_queue_work(struct usb_ftdi *ftdi, unsigned int delta)
|
||||
{
|
||||
if (delta > 0) {
|
||||
if (queue_delayed_work(respond_queue, &ftdi->respond_work,
|
||||
delta))
|
||||
kref_get(&ftdi->kref);
|
||||
} else if (queue_work(respond_queue, &ftdi->respond_work))
|
||||
kref_get(&ftdi->kref);
|
||||
return;
|
||||
if (queue_delayed_work(respond_queue, &ftdi->respond_work, delta))
|
||||
kref_get(&ftdi->kref);
|
||||
}
|
||||
|
||||
static void ftdi_response_cancel_work(struct usb_ftdi *ftdi)
|
||||
|
|
@ -303,7 +272,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;
|
||||
}
|
||||
|
|
@ -475,9 +444,11 @@ static void ftdi_elan_kick_command_queue(struct usb_ftdi *ftdi)
|
|||
return;
|
||||
}
|
||||
|
||||
static void ftdi_elan_command_work(void *data)
|
||||
static void ftdi_elan_command_work(struct work_struct *work)
|
||||
{
|
||||
struct usb_ftdi *ftdi = data;
|
||||
struct usb_ftdi *ftdi =
|
||||
container_of(work, struct usb_ftdi, command_work.work);
|
||||
|
||||
if (ftdi->disconnected > 0) {
|
||||
ftdi_elan_put_kref(ftdi);
|
||||
return;
|
||||
|
|
@ -500,9 +471,10 @@ static void ftdi_elan_kick_respond_queue(struct usb_ftdi *ftdi)
|
|||
return;
|
||||
}
|
||||
|
||||
static void ftdi_elan_respond_work(void *data)
|
||||
static void ftdi_elan_respond_work(struct work_struct *work)
|
||||
{
|
||||
struct usb_ftdi *ftdi = data;
|
||||
struct usb_ftdi *ftdi =
|
||||
container_of(work, struct usb_ftdi, respond_work.work);
|
||||
if (ftdi->disconnected > 0) {
|
||||
ftdi_elan_put_kref(ftdi);
|
||||
return;
|
||||
|
|
@ -534,9 +506,10 @@ static void ftdi_elan_respond_work(void *data)
|
|||
* after the FTDI has been synchronized
|
||||
*
|
||||
*/
|
||||
static void ftdi_elan_status_work(void *data)
|
||||
static void ftdi_elan_status_work(struct work_struct *work)
|
||||
{
|
||||
struct usb_ftdi *ftdi = data;
|
||||
struct usb_ftdi *ftdi =
|
||||
container_of(work, struct usb_ftdi, status_work.work);
|
||||
int work_delay_in_msec = 0;
|
||||
if (ftdi->disconnected > 0) {
|
||||
ftdi_elan_put_kref(ftdi);
|
||||
|
|
@ -1426,14 +1399,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 +2598,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 +2611,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;
|
||||
}
|
||||
|
|
@ -2691,12 +2650,9 @@ static int ftdi_elan_probe(struct usb_interface *interface,
|
|||
ftdi->class = NULL;
|
||||
dev_info(&ftdi->udev->dev, "USB FDTI=%p ELAN interface %d now a"
|
||||
"ctivated\n", ftdi, iface_desc->desc.bInterfaceNumber);
|
||||
INIT_WORK(&ftdi->status_work, ftdi_elan_status_work,
|
||||
(void *)ftdi);
|
||||
INIT_WORK(&ftdi->command_work, ftdi_elan_command_work,
|
||||
(void *)ftdi);
|
||||
INIT_WORK(&ftdi->respond_work, ftdi_elan_respond_work,
|
||||
(void *)ftdi);
|
||||
INIT_DELAYED_WORK(&ftdi->status_work, ftdi_elan_status_work);
|
||||
INIT_DELAYED_WORK(&ftdi->command_work, ftdi_elan_command_work);
|
||||
INIT_DELAYED_WORK(&ftdi->respond_work, ftdi_elan_respond_work);
|
||||
ftdi_status_queue_work(ftdi, msecs_to_jiffies(3 *1000));
|
||||
return 0;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ struct interfacekit {
|
|||
unsigned char *data;
|
||||
dma_addr_t data_dma;
|
||||
|
||||
struct work_struct do_notify;
|
||||
struct work_struct do_resubmit;
|
||||
struct delayed_work do_notify;
|
||||
struct delayed_work do_resubmit;
|
||||
unsigned long input_events;
|
||||
unsigned long sensor_events;
|
||||
};
|
||||
|
|
@ -374,19 +374,20 @@ static void interfacekit_irq(struct urb *urb)
|
|||
}
|
||||
|
||||
if (kit->input_events || kit->sensor_events)
|
||||
schedule_work(&kit->do_notify);
|
||||
schedule_delayed_work(&kit->do_notify, 0);
|
||||
|
||||
resubmit:
|
||||
status = usb_submit_urb(urb, SLAB_ATOMIC);
|
||||
status = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (status)
|
||||
err("can't resubmit intr, %s-%s/interfacekit0, status %d",
|
||||
kit->udev->bus->bus_name,
|
||||
kit->udev->devpath, status);
|
||||
}
|
||||
|
||||
static void do_notify(void *data)
|
||||
static void do_notify(struct work_struct *work)
|
||||
{
|
||||
struct interfacekit *kit = data;
|
||||
struct interfacekit *kit =
|
||||
container_of(work, struct interfacekit, do_notify.work);
|
||||
int i;
|
||||
char sysfs_file[8];
|
||||
|
||||
|
|
@ -405,9 +406,11 @@ static void do_notify(void *data)
|
|||
}
|
||||
}
|
||||
|
||||
static void do_resubmit(void *data)
|
||||
static void do_resubmit(struct work_struct *work)
|
||||
{
|
||||
set_outputs(data);
|
||||
struct interfacekit *kit =
|
||||
container_of(work, struct interfacekit, do_resubmit.work);
|
||||
set_outputs(kit);
|
||||
}
|
||||
|
||||
#define show_set_output(value) \
|
||||
|
|
@ -551,7 +554,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
|
||||
|
|
@ -565,7 +568,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
|
|||
|
||||
kit->dev_no = -1;
|
||||
kit->ifkit = ifkit;
|
||||
kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma);
|
||||
kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &kit->data_dma);
|
||||
if (!kit->data)
|
||||
goto out;
|
||||
|
||||
|
|
@ -575,8 +578,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
|
|||
|
||||
kit->udev = usb_get_dev(dev);
|
||||
kit->intf = intf;
|
||||
INIT_WORK(&kit->do_notify, do_notify, kit);
|
||||
INIT_WORK(&kit->do_resubmit, do_resubmit, kit);
|
||||
INIT_DELAYED_WORK(&kit->do_notify, do_notify);
|
||||
INIT_DELAYED_WORK(&kit->do_resubmit, do_resubmit);
|
||||
usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data,
|
||||
maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
|
||||
interfacekit_irq, kit, endpoint->bInterval);
|
||||
|
|
@ -650,8 +653,7 @@ out2:
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ struct motorcontrol {
|
|||
unsigned char *data;
|
||||
dma_addr_t data_dma;
|
||||
|
||||
struct work_struct do_notify;
|
||||
struct delayed_work do_notify;
|
||||
unsigned long input_events;
|
||||
unsigned long speed_events;
|
||||
unsigned long exceed_events;
|
||||
|
|
@ -148,10 +148,10 @@ static void motorcontrol_irq(struct urb *urb)
|
|||
set_bit(1, &mc->exceed_events);
|
||||
|
||||
if (mc->input_events || mc->exceed_events || mc->speed_events)
|
||||
schedule_work(&mc->do_notify);
|
||||
schedule_delayed_work(&mc->do_notify, 0);
|
||||
|
||||
resubmit:
|
||||
status = usb_submit_urb(urb, SLAB_ATOMIC);
|
||||
status = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (status)
|
||||
dev_err(&mc->intf->dev,
|
||||
"can't resubmit intr, %s-%s/motorcontrol0, status %d",
|
||||
|
|
@ -159,9 +159,10 @@ resubmit:
|
|||
mc->udev->devpath, status);
|
||||
}
|
||||
|
||||
static void do_notify(void *data)
|
||||
static void do_notify(struct work_struct *work)
|
||||
{
|
||||
struct motorcontrol *mc = data;
|
||||
struct motorcontrol *mc =
|
||||
container_of(work, struct motorcontrol, do_notify.work);
|
||||
int i;
|
||||
char sysfs_file[8];
|
||||
|
||||
|
|
@ -323,7 +324,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;
|
||||
|
||||
/*
|
||||
|
|
@ -337,7 +338,7 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic
|
|||
goto out;
|
||||
|
||||
mc->dev_no = -1;
|
||||
mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &mc->data_dma);
|
||||
mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &mc->data_dma);
|
||||
if (!mc->data)
|
||||
goto out;
|
||||
|
||||
|
|
@ -348,7 +349,7 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic
|
|||
mc->udev = usb_get_dev(dev);
|
||||
mc->intf = intf;
|
||||
mc->acceleration[0] = mc->acceleration[1] = 10;
|
||||
INIT_WORK(&mc->do_notify, do_notify, mc);
|
||||
INIT_DELAYED_WORK(&mc->do_notify, do_notify);
|
||||
usb_fill_int_urb(mc->irq, mc->udev, pipe, mc->data,
|
||||
maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
|
||||
motorcontrol_irq, mc, endpoint->bInterval);
|
||||
|
|
@ -392,8 +393,7 @@ out2:
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
* the kernel to load the "u132-hcd" module.
|
||||
*
|
||||
* The "ftdi-u132" module provides the interface to the inserted
|
||||
* PC card and the "u132-hcd" module uses the API to send and recieve
|
||||
* PC card and the "u132-hcd" module uses the API to send and receive
|
||||
* data. The API features call-backs, so that part of the "u132-hcd"
|
||||
* module code will run in the context of one of the kernel threads
|
||||
* of the "ftdi-u132" module.
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -213,7 +213,7 @@ static struct urb *simple_alloc_urb (
|
|||
|
||||
if (bytes < 0)
|
||||
return NULL;
|
||||
urb = usb_alloc_urb (0, SLAB_KERNEL);
|
||||
urb = usb_alloc_urb (0, GFP_KERNEL);
|
||||
if (!urb)
|
||||
return urb;
|
||||
usb_fill_bulk_urb (urb, udev, pipe, NULL, bytes, simple_callback, NULL);
|
||||
|
|
@ -223,7 +223,7 @@ static struct urb *simple_alloc_urb (
|
|||
urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
|
||||
if (usb_pipein (pipe))
|
||||
urb->transfer_flags |= URB_SHORT_NOT_OK;
|
||||
urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL,
|
||||
urb->transfer_buffer = usb_buffer_alloc (udev, bytes, GFP_KERNEL,
|
||||
&urb->transfer_dma);
|
||||
if (!urb->transfer_buffer) {
|
||||
usb_free_urb (urb);
|
||||
|
|
@ -315,7 +315,7 @@ static int simple_io (
|
|||
init_completion (&completion);
|
||||
if (usb_pipeout (urb->pipe))
|
||||
simple_fill_buf (urb);
|
||||
if ((retval = usb_submit_urb (urb, SLAB_KERNEL)) != 0)
|
||||
if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0)
|
||||
break;
|
||||
|
||||
/* NOTE: no timeouts; can't be broken out of by interrupt */
|
||||
|
|
@ -374,7 +374,7 @@ alloc_sglist (int nents, int max, int vary)
|
|||
unsigned i;
|
||||
unsigned size = max;
|
||||
|
||||
sg = kmalloc (nents * sizeof *sg, SLAB_KERNEL);
|
||||
sg = kmalloc (nents * sizeof *sg, GFP_KERNEL);
|
||||
if (!sg)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -382,7 +382,7 @@ alloc_sglist (int nents, int max, int vary)
|
|||
char *buf;
|
||||
unsigned j;
|
||||
|
||||
buf = kzalloc (size, SLAB_KERNEL);
|
||||
buf = kzalloc (size, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
free_sglist (sg, i);
|
||||
return NULL;
|
||||
|
|
@ -428,7 +428,7 @@ static int perform_sglist (
|
|||
(udev->speed == USB_SPEED_HIGH)
|
||||
? (INTERRUPT_RATE << 3)
|
||||
: INTERRUPT_RATE,
|
||||
sg, nents, 0, SLAB_KERNEL);
|
||||
sg, nents, 0, GFP_KERNEL);
|
||||
|
||||
if (retval)
|
||||
break;
|
||||
|
|
@ -819,7 +819,7 @@ error:
|
|||
|
||||
/* resubmit if we need to, else mark this as done */
|
||||
if ((status == 0) && (ctx->pending < ctx->count)) {
|
||||
if ((status = usb_submit_urb (urb, SLAB_ATOMIC)) != 0) {
|
||||
if ((status = usb_submit_urb (urb, GFP_ATOMIC)) != 0) {
|
||||
dbg ("can't resubmit ctrl %02x.%02x, err %d",
|
||||
reqp->bRequestType, reqp->bRequest, status);
|
||||
urb->dev = NULL;
|
||||
|
|
@ -855,7 +855,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
|
|||
* as with bulk/intr sglists, sglen is the queue depth; it also
|
||||
* controls which subtests run (more tests than sglen) or rerun.
|
||||
*/
|
||||
urb = kcalloc(param->sglen, sizeof(struct urb *), SLAB_KERNEL);
|
||||
urb = kcalloc(param->sglen, sizeof(struct urb *), GFP_KERNEL);
|
||||
if (!urb)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < param->sglen; i++) {
|
||||
|
|
@ -981,7 +981,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
|
|||
if (!u)
|
||||
goto cleanup;
|
||||
|
||||
reqp = usb_buffer_alloc (udev, sizeof *reqp, SLAB_KERNEL,
|
||||
reqp = usb_buffer_alloc (udev, sizeof *reqp, GFP_KERNEL,
|
||||
&u->setup_dma);
|
||||
if (!reqp)
|
||||
goto cleanup;
|
||||
|
|
@ -999,7 +999,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
|
|||
context.urb = urb;
|
||||
spin_lock_irq (&context.lock);
|
||||
for (i = 0; i < param->sglen; i++) {
|
||||
context.status = usb_submit_urb (urb [i], SLAB_ATOMIC);
|
||||
context.status = usb_submit_urb (urb [i], GFP_ATOMIC);
|
||||
if (context.status != 0) {
|
||||
dbg ("can't submit urb[%d], status %d",
|
||||
i, context.status);
|
||||
|
|
@ -1041,7 +1041,7 @@ static void unlink1_callback (struct urb *urb)
|
|||
|
||||
// we "know" -EPIPE (stall) never happens
|
||||
if (!status)
|
||||
status = usb_submit_urb (urb, SLAB_ATOMIC);
|
||||
status = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (status) {
|
||||
urb->status = status;
|
||||
complete ((struct completion *) urb->context);
|
||||
|
|
@ -1067,7 +1067,7 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async)
|
|||
* FIXME want additional tests for when endpoint is STALLing
|
||||
* due to errors, or is just NAKing requests.
|
||||
*/
|
||||
if ((retval = usb_submit_urb (urb, SLAB_KERNEL)) != 0) {
|
||||
if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0) {
|
||||
dev_dbg (&dev->intf->dev, "submit fail %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -1251,7 +1251,7 @@ static int ctrl_out (struct usbtest_dev *dev,
|
|||
if (length < 1 || length > 0xffff || vary >= length)
|
||||
return -EINVAL;
|
||||
|
||||
buf = kmalloc(length, SLAB_KERNEL);
|
||||
buf = kmalloc(length, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -1403,7 +1403,7 @@ static struct urb *iso_alloc_urb (
|
|||
maxp *= 1 + (0x3 & (le16_to_cpu(desc->wMaxPacketSize) >> 11));
|
||||
packets = (bytes + maxp - 1) / maxp;
|
||||
|
||||
urb = usb_alloc_urb (packets, SLAB_KERNEL);
|
||||
urb = usb_alloc_urb (packets, GFP_KERNEL);
|
||||
if (!urb)
|
||||
return urb;
|
||||
urb->dev = udev;
|
||||
|
|
@ -1411,7 +1411,7 @@ static struct urb *iso_alloc_urb (
|
|||
|
||||
urb->number_of_packets = packets;
|
||||
urb->transfer_buffer_length = bytes;
|
||||
urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL,
|
||||
urb->transfer_buffer = usb_buffer_alloc (udev, bytes, GFP_KERNEL,
|
||||
&urb->transfer_dma);
|
||||
if (!urb->transfer_buffer) {
|
||||
usb_free_urb (urb);
|
||||
|
|
@ -1481,7 +1481,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param,
|
|||
spin_lock_irq (&context.lock);
|
||||
for (i = 0; i < param->sglen; i++) {
|
||||
++context.pending;
|
||||
status = usb_submit_urb (urbs [i], SLAB_ATOMIC);
|
||||
status = usb_submit_urb (urbs [i], GFP_ATOMIC);
|
||||
if (status < 0) {
|
||||
ERROR (dev, "submit iso[%d], error %d\n", i, status);
|
||||
if (i == 0) {
|
||||
|
|
@ -1900,7 +1900,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id)
|
|||
}
|
||||
#endif
|
||||
|
||||
dev = kzalloc(sizeof(*dev), SLAB_KERNEL);
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
info = (struct usbtest_info *) id->driver_info;
|
||||
|
|
@ -1910,7 +1910,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id)
|
|||
dev->intf = intf;
|
||||
|
||||
/* cacheline-aligned scratch for i/o */
|
||||
if ((dev->buf = kmalloc (TBUF_SIZE, SLAB_KERNEL)) == NULL) {
|
||||
if ((dev->buf = kmalloc (TBUF_SIZE, GFP_KERNEL)) == NULL) {
|
||||
kfree (dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ struct mon_event_text {
|
|||
|
||||
#define SLAB_NAME_SZ 30
|
||||
struct mon_reader_text {
|
||||
kmem_cache_t *e_slab;
|
||||
struct kmem_cache *e_slab;
|
||||
int nevents;
|
||||
struct list_head e_list;
|
||||
struct mon_reader r; /* In C, parent class can be placed anywhere */
|
||||
|
|
@ -63,7 +63,7 @@ struct mon_reader_text {
|
|||
char slab_name[SLAB_NAME_SZ];
|
||||
};
|
||||
|
||||
static void mon_text_ctor(void *, kmem_cache_t *, unsigned long);
|
||||
static void mon_text_ctor(void *, struct kmem_cache *, unsigned long);
|
||||
|
||||
/*
|
||||
* mon_text_submit
|
||||
|
|
@ -147,7 +147,7 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
|
|||
stamp = mon_get_timestamp();
|
||||
|
||||
if (rp->nevents >= EVENT_MAX ||
|
||||
(ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) {
|
||||
(ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
|
||||
rp->r.m_bus->cnt_text_lost++;
|
||||
return;
|
||||
}
|
||||
|
|
@ -188,7 +188,7 @@ static void mon_text_error(void *data, struct urb *urb, int error)
|
|||
struct mon_event_text *ep;
|
||||
|
||||
if (rp->nevents >= EVENT_MAX ||
|
||||
(ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) {
|
||||
(ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
|
||||
rp->r.m_bus->cnt_text_lost++;
|
||||
return;
|
||||
}
|
||||
|
|
@ -450,7 +450,7 @@ const struct file_operations mon_fops_text = {
|
|||
/*
|
||||
* Slab interface: constructor.
|
||||
*/
|
||||
static void mon_text_ctor(void *mem, kmem_cache_t *slab, unsigned long sflags)
|
||||
static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sflags)
|
||||
{
|
||||
/*
|
||||
* Nothing to initialize. No, really!
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ static void catc_irq_done(struct urb *urb)
|
|||
}
|
||||
}
|
||||
resubmit:
|
||||
status = usb_submit_urb (urb, SLAB_ATOMIC);
|
||||
status = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (status)
|
||||
err ("can't resubmit intr, %s-%s, status %d",
|
||||
catc->usbdev->bus->bus_name,
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,8 +200,7 @@ next_desc:
|
|||
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ struct kaweth_device
|
|||
int suspend_lowmem_ctrl;
|
||||
int linkstate;
|
||||
int opened;
|
||||
struct work_struct lowmem_work;
|
||||
struct delayed_work lowmem_work;
|
||||
|
||||
struct usb_device *dev;
|
||||
struct net_device *net;
|
||||
|
|
@ -530,9 +530,10 @@ resubmit:
|
|||
kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
static void kaweth_resubmit_tl(void *d)
|
||||
static void kaweth_resubmit_tl(struct work_struct *work)
|
||||
{
|
||||
struct kaweth_device *kaweth = (struct kaweth_device *)d;
|
||||
struct kaweth_device *kaweth =
|
||||
container_of(work, struct kaweth_device, lowmem_work.work);
|
||||
|
||||
if (IS_BLOCKED(kaweth->status))
|
||||
return;
|
||||
|
|
@ -1126,7 +1127,7 @@ err_fw:
|
|||
|
||||
/* kaweth is zeroed as part of alloc_netdev */
|
||||
|
||||
INIT_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl, (void *)kaweth);
|
||||
INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl);
|
||||
|
||||
SET_MODULE_OWNER(netdev);
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
@ -383,7 +383,7 @@ static void nc_ensure_sync(struct usbnet *dev)
|
|||
int status;
|
||||
|
||||
/* Send a flush */
|
||||
urb = usb_alloc_urb(0, SLAB_ATOMIC);
|
||||
urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
if (!urb)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
@ -855,7 +856,7 @@ static void intr_callback(struct urb *urb)
|
|||
pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4];
|
||||
}
|
||||
|
||||
status = usb_submit_urb(urb, SLAB_ATOMIC);
|
||||
status = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (status == -ENODEV)
|
||||
netif_device_detach(pegasus->net);
|
||||
if (status && netif_msg_timer(pegasus))
|
||||
|
|
@ -1280,9 +1281,9 @@ static inline void setup_pegasus_II(pegasus_t * pegasus)
|
|||
static struct workqueue_struct *pegasus_workqueue = NULL;
|
||||
#define CARRIER_CHECK_DELAY (2 * HZ)
|
||||
|
||||
static void check_carrier(void *data)
|
||||
static void check_carrier(struct work_struct *work)
|
||||
{
|
||||
pegasus_t *pegasus = data;
|
||||
pegasus_t *pegasus = container_of(work, pegasus_t, carrier_check.work);
|
||||
set_carrier(pegasus->net);
|
||||
if (!(pegasus->flags & PEGASUS_UNPLUG)) {
|
||||
queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check,
|
||||
|
|
@ -1318,7 +1319,7 @@ static int pegasus_probe(struct usb_interface *intf,
|
|||
|
||||
tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus);
|
||||
|
||||
INIT_WORK(&pegasus->carrier_check, check_carrier, pegasus);
|
||||
INIT_DELAYED_WORK(&pegasus->carrier_check, check_carrier);
|
||||
|
||||
pegasus->intf = intf;
|
||||
pegasus->usb = dev;
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ typedef struct pegasus {
|
|||
int dev_index;
|
||||
int intr_interval;
|
||||
struct tasklet_struct rx_tl;
|
||||
struct work_struct carrier_check;
|
||||
struct delayed_work carrier_check;
|
||||
struct urb *ctrl_urb, *rx_urb, *tx_urb, *intr_urb;
|
||||
struct sk_buff *rx_pool[RX_SKBS];
|
||||
struct sk_buff *rx_skb;
|
||||
|
|
|
|||
|
|
@ -469,7 +469,7 @@ static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
|
|||
struct rndis_halt *halt;
|
||||
|
||||
/* try to clear any rndis state/activity (no i/o from stack!) */
|
||||
halt = kcalloc(1, sizeof *halt, SLAB_KERNEL);
|
||||
halt = kcalloc(1, sizeof *halt, GFP_KERNEL);
|
||||
if (halt) {
|
||||
halt->msg_type = RNDIS_MSG_HALT;
|
||||
halt->msg_len = ccpu2(sizeof *halt);
|
||||
|
|
|
|||
|
|
@ -587,7 +587,7 @@ static void intr_callback(struct urb *urb)
|
|||
}
|
||||
|
||||
resubmit:
|
||||
status = usb_submit_urb (urb, SLAB_ATOMIC);
|
||||
status = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (status == -ENODEV)
|
||||
netif_device_detach(dev->netdev);
|
||||
else if (status)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -179,9 +179,9 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
|
|||
period = max ((int) dev->status->desc.bInterval,
|
||||
(dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3);
|
||||
|
||||
buf = kmalloc (maxp, SLAB_KERNEL);
|
||||
buf = kmalloc (maxp, GFP_KERNEL);
|
||||
if (buf) {
|
||||
dev->interrupt = usb_alloc_urb (0, SLAB_KERNEL);
|
||||
dev->interrupt = usb_alloc_urb (0, GFP_KERNEL);
|
||||
if (!dev->interrupt) {
|
||||
kfree (buf);
|
||||
return -ENOMEM;
|
||||
|
|
@ -782,9 +782,10 @@ static struct ethtool_ops usbnet_ethtool_ops = {
|
|||
* especially now that control transfers can be queued.
|
||||
*/
|
||||
static void
|
||||
kevent (void *data)
|
||||
kevent (struct work_struct *work)
|
||||
{
|
||||
struct usbnet *dev = data;
|
||||
struct usbnet *dev =
|
||||
container_of(work, struct usbnet, kevent);
|
||||
int status;
|
||||
|
||||
/* usb_clear_halt() needs a thread context */
|
||||
|
|
@ -1146,7 +1147,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
|
|||
skb_queue_head_init (&dev->done);
|
||||
dev->bh.func = usbnet_bh;
|
||||
dev->bh.data = (unsigned long) dev;
|
||||
INIT_WORK (&dev->kevent, kevent, dev);
|
||||
INIT_WORK (&dev->kevent, kevent);
|
||||
dev->delay.function = usbnet_bh;
|
||||
dev->delay.data = (unsigned long) dev;
|
||||
init_timer (&dev->delay);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ struct aircable_private {
|
|||
struct circ_buf *rx_buf; /* read buffer */
|
||||
int rx_flags; /* for throttilng */
|
||||
struct work_struct rx_work; /* work cue for the receiving line */
|
||||
struct usb_serial_port *port; /* USB port with which associated */
|
||||
};
|
||||
|
||||
/* Private methods */
|
||||
|
|
@ -251,10 +252,11 @@ static void aircable_send(struct usb_serial_port *port)
|
|||
schedule_work(&port->work);
|
||||
}
|
||||
|
||||
static void aircable_read(void *params)
|
||||
static void aircable_read(struct work_struct *work)
|
||||
{
|
||||
struct usb_serial_port *port = params;
|
||||
struct aircable_private *priv = usb_get_serial_port_data(port);
|
||||
struct aircable_private *priv =
|
||||
container_of(work, struct aircable_private, rx_work);
|
||||
struct usb_serial_port *port = priv->port;
|
||||
struct tty_struct *tty;
|
||||
unsigned char *data;
|
||||
int count;
|
||||
|
|
@ -270,8 +272,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 +310,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;
|
||||
}
|
||||
|
|
@ -348,7 +351,8 @@ static int aircable_attach (struct usb_serial *serial)
|
|||
}
|
||||
|
||||
priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
|
||||
INIT_WORK(&priv->rx_work, aircable_read, port);
|
||||
priv->port = port;
|
||||
INIT_WORK(&priv->rx_work, aircable_read);
|
||||
|
||||
usb_set_serial_port_data(serial->port[0], priv);
|
||||
|
||||
|
|
@ -515,7 +519,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
|
|||
package_length - shift);
|
||||
}
|
||||
}
|
||||
aircable_read(port);
|
||||
aircable_read(&priv->rx_work);
|
||||
}
|
||||
|
||||
/* Schedule the next read _if_ we are still open */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
{ },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@
|
|||
* to TASK_RUNNING will be lost and write_chan's subsequent call to
|
||||
* schedule() will never return (unless it catches a signal).
|
||||
* This race condition occurs because write_bulk_callback() (and thus
|
||||
* the wakeup) are called asynchonously from an interrupt, rather than
|
||||
* the wakeup) are called asynchronously from an interrupt, rather than
|
||||
* from the scheduler. We can avoid the race by calling the wakeup
|
||||
* from the scheduler queue and that's our fix: Now, at the end of
|
||||
* write_bulk_callback() we queue up a wakeup call on the scheduler
|
||||
|
|
@ -430,13 +430,14 @@ struct digi_port {
|
|||
int dp_in_close; /* close in progress */
|
||||
wait_queue_head_t dp_close_wait; /* wait queue for close */
|
||||
struct work_struct dp_wakeup_work;
|
||||
struct usb_serial_port *dp_port;
|
||||
};
|
||||
|
||||
|
||||
/* Local Function Declarations */
|
||||
|
||||
static void digi_wakeup_write( struct usb_serial_port *port );
|
||||
static void digi_wakeup_write_lock(void *);
|
||||
static void digi_wakeup_write_lock(struct work_struct *work);
|
||||
static int digi_write_oob_command( struct usb_serial_port *port,
|
||||
unsigned char *buf, int count, int interruptible );
|
||||
static int digi_write_inb_command( struct usb_serial_port *port,
|
||||
|
|
@ -598,11 +599,12 @@ static inline long cond_wait_interruptible_timeout_irqrestore(
|
|||
* on writes.
|
||||
*/
|
||||
|
||||
static void digi_wakeup_write_lock(void *arg)
|
||||
static void digi_wakeup_write_lock(struct work_struct *work)
|
||||
{
|
||||
struct usb_serial_port *port = arg;
|
||||
struct digi_port *priv =
|
||||
container_of(work, struct digi_port, dp_wakeup_work);
|
||||
struct usb_serial_port *port = priv->dp_port;
|
||||
unsigned long flags;
|
||||
struct digi_port *priv = usb_get_serial_port_data(port);
|
||||
|
||||
|
||||
spin_lock_irqsave( &priv->dp_port_lock, flags );
|
||||
|
|
@ -1702,8 +1704,8 @@ dbg( "digi_startup: TOP" );
|
|||
init_waitqueue_head( &priv->dp_flush_wait );
|
||||
priv->dp_in_close = 0;
|
||||
init_waitqueue_head( &priv->dp_close_wait );
|
||||
INIT_WORK(&priv->dp_wakeup_work,
|
||||
digi_wakeup_write_lock, serial->port[i]);
|
||||
INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock);
|
||||
priv->dp_port = serial->port[i];
|
||||
|
||||
/* initialize write wait queue for this port */
|
||||
init_waitqueue_head( &serial->port[i]->write_wait );
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ static struct usb_device_id id_table_combined [] = {
|
|||
{ USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
|
||||
|
|
@ -511,6 +512,7 @@ static struct usb_device_id id_table_combined [] = {
|
|||
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
|
||||
{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
|
||||
{ }, /* Optional parameter entry */
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
|
@ -557,7 +559,8 @@ struct ftdi_private {
|
|||
char prev_status, diff_status; /* Used for TIOCMIWAIT */
|
||||
__u8 rx_flags; /* receive state flags (throttling) */
|
||||
spinlock_t rx_lock; /* spinlock for receive state */
|
||||
struct work_struct rx_work;
|
||||
struct delayed_work rx_work;
|
||||
struct usb_serial_port *port;
|
||||
int rx_processed;
|
||||
unsigned long rx_bytes;
|
||||
|
||||
|
|
@ -591,7 +594,7 @@ static int ftdi_write_room (struct usb_serial_port *port);
|
|||
static int ftdi_chars_in_buffer (struct usb_serial_port *port);
|
||||
static void ftdi_write_bulk_callback (struct urb *urb);
|
||||
static void ftdi_read_bulk_callback (struct urb *urb);
|
||||
static void ftdi_process_read (void *param);
|
||||
static void ftdi_process_read (struct work_struct *work);
|
||||
static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old);
|
||||
static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file);
|
||||
static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear);
|
||||
|
|
@ -1199,7 +1202,8 @@ static int ftdi_sio_attach (struct usb_serial *serial)
|
|||
port->read_urb->transfer_buffer_length = BUFSZ;
|
||||
}
|
||||
|
||||
INIT_WORK(&priv->rx_work, ftdi_process_read, port);
|
||||
INIT_DELAYED_WORK(&priv->rx_work, ftdi_process_read);
|
||||
priv->port = port;
|
||||
|
||||
/* Free port's existing write urb and transfer buffer. */
|
||||
if (port->write_urb) {
|
||||
|
|
@ -1386,8 +1390,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 */
|
||||
|
||||
|
||||
|
|
@ -1639,17 +1642,18 @@ static void ftdi_read_bulk_callback (struct urb *urb)
|
|||
priv->rx_bytes += countread;
|
||||
spin_unlock_irqrestore(&priv->rx_lock, flags);
|
||||
|
||||
ftdi_process_read(port);
|
||||
ftdi_process_read(&priv->rx_work.work);
|
||||
|
||||
} /* ftdi_read_bulk_callback */
|
||||
|
||||
|
||||
static void ftdi_process_read (void *param)
|
||||
static void ftdi_process_read (struct work_struct *work)
|
||||
{ /* ftdi_process_read */
|
||||
struct usb_serial_port *port = (struct usb_serial_port*)param;
|
||||
struct ftdi_private *priv =
|
||||
container_of(work, struct ftdi_private, rx_work.work);
|
||||
struct usb_serial_port *port = priv->port;
|
||||
struct urb *urb;
|
||||
struct tty_struct *tty;
|
||||
struct ftdi_private *priv;
|
||||
char error_flag;
|
||||
unsigned char *data;
|
||||
|
||||
|
|
@ -2178,7 +2182,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port)
|
|||
spin_unlock_irqrestore(&priv->rx_lock, flags);
|
||||
|
||||
if (actually_throttled)
|
||||
schedule_work(&priv->rx_work);
|
||||
schedule_delayed_work(&priv->rx_work, 0);
|
||||
}
|
||||
|
||||
static int __init ftdi_init (void)
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@
|
|||
/* iPlus device */
|
||||
#define FTDI_IPLUS_PID 0xD070 /* Product Id */
|
||||
|
||||
/* DMX4ALL DMX Interfaces */
|
||||
#define FTDI_DMX4ALL 0xC850
|
||||
|
||||
/* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */
|
||||
/* they use the ftdi chipset for the USB interface and the vendor id is the same */
|
||||
#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */
|
||||
|
|
@ -174,10 +177,16 @@
|
|||
*/
|
||||
#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */
|
||||
|
||||
/*
|
||||
* FTDI USB UART chips used in construction projects from the
|
||||
* Elektor Electronics magazine (http://elektor-electronics.co.uk)
|
||||
*/
|
||||
#define ELEKTOR_VID 0x0C7D
|
||||
#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */
|
||||
|
||||
/*
|
||||
* DSS-20 Sync Station for Sony Ericsson P800
|
||||
*/
|
||||
|
||||
#define FTDI_DSS20_PID 0xFC82
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue