kernel: USB update from stlinux24_217
This commit is contained in:
parent
07aa6b0e5a
commit
c48033761a
@ -49,7 +49,8 @@ config USB_ARCH_HAS_OHCI
|
||||
default y if CPU_SUBTYPE_SH7721
|
||||
default y if CPU_SUBTYPE_SH7763
|
||||
default y if CPU_SUBTYPE_SH7786
|
||||
default y if CPU_SUBTYPE_FLI7510
|
||||
default y if CPU_SUBTYPE_FLI75XX
|
||||
default y if CPU_SUBTYPE_STXH205
|
||||
default y if CPU_SUBTYPE_STX5197
|
||||
default y if CPU_SUBTYPE_STX5206
|
||||
default y if CPU_SUBTYPE_STX7100
|
||||
@ -69,7 +70,8 @@ config USB_ARCH_HAS_EHCI
|
||||
default y if ARCH_IXP4XX
|
||||
default y if ARCH_W90X900
|
||||
default y if ARCH_AT91SAM9G45
|
||||
default y if CPU_SUBTYPE_FLI7510
|
||||
default y if CPU_SUBTYPE_FLI75XX
|
||||
default y if CPU_SUBTYPE_STXH205
|
||||
default y if CPU_SUBTYPE_STX5197
|
||||
default y if CPU_SUBTYPE_STX5206
|
||||
default y if CPU_SUBTYPE_STX7100
|
||||
|
@ -1120,7 +1120,8 @@ skip_normal_probe:
|
||||
}
|
||||
|
||||
|
||||
if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
|
||||
if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 ||
|
||||
control_interface->cur_altsetting->desc.bNumEndpoints == 0)
|
||||
return -EINVAL;
|
||||
|
||||
epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
|
||||
@ -1264,6 +1265,8 @@ made_compressed_probe:
|
||||
i = device_create_file(&intf->dev, &dev_attr_wCountryCodes);
|
||||
if (i < 0) {
|
||||
kfree(acm->country_codes);
|
||||
acm->country_codes = NULL;
|
||||
acm->country_code_size = 0;
|
||||
goto skip_countries;
|
||||
}
|
||||
|
||||
@ -1272,6 +1275,8 @@ made_compressed_probe:
|
||||
if (i < 0) {
|
||||
device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
|
||||
kfree(acm->country_codes);
|
||||
acm->country_codes = NULL;
|
||||
acm->country_code_size = 0;
|
||||
goto skip_countries;
|
||||
}
|
||||
}
|
||||
@ -1528,6 +1533,16 @@ static struct usb_device_id acm_ids[] = {
|
||||
},
|
||||
{ USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
|
||||
},
|
||||
/* Motorola H24 HSPA module: */
|
||||
{ USB_DEVICE(0x22b8, 0x2d91) }, /* modem */
|
||||
{ USB_DEVICE(0x22b8, 0x2d92) }, /* modem + diagnostics */
|
||||
{ USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port */
|
||||
{ USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics */
|
||||
{ USB_DEVICE(0x22b8, 0x2d96) }, /* modem + NMEA */
|
||||
{ USB_DEVICE(0x22b8, 0x2d97) }, /* modem + diagnostics + NMEA */
|
||||
{ USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port + NMEA */
|
||||
{ USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */
|
||||
|
||||
{ USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
|
||||
.driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on
|
||||
data interface instead of
|
||||
@ -1606,6 +1621,9 @@ static struct usb_device_id acm_ids[] = {
|
||||
{ NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */
|
||||
{ SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */
|
||||
|
||||
/* Support for Owen devices */
|
||||
{ USB_DEVICE(0x03eb, 0x0030), }, /* Owen SI30 */
|
||||
|
||||
/* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */
|
||||
|
||||
/* control interfaces without any protocol set */
|
||||
|
@ -52,6 +52,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
|
||||
#define WDM_READ 4
|
||||
#define WDM_INT_STALL 5
|
||||
#define WDM_POLL_RUNNING 6
|
||||
#define WDM_OVERFLOW 10
|
||||
|
||||
|
||||
#define WDM_MAX 16
|
||||
@ -115,6 +116,7 @@ static void wdm_in_callback(struct urb *urb)
|
||||
{
|
||||
struct wdm_device *desc = urb->context;
|
||||
int status = urb->status;
|
||||
int length = urb->actual_length;
|
||||
|
||||
spin_lock(&desc->iuspin);
|
||||
|
||||
@ -144,9 +146,17 @@ static void wdm_in_callback(struct urb *urb)
|
||||
}
|
||||
|
||||
desc->rerr = status;
|
||||
desc->reslength = urb->actual_length;
|
||||
memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength);
|
||||
desc->length += desc->reslength;
|
||||
if (length + desc->length > desc->wMaxCommand) {
|
||||
/* The buffer would overflow */
|
||||
set_bit(WDM_OVERFLOW, &desc->flags);
|
||||
} else {
|
||||
/* we may already be in overflow */
|
||||
if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
|
||||
memmove(desc->ubuf + desc->length, desc->inbuf, length);
|
||||
desc->length += length;
|
||||
desc->reslength = length;
|
||||
}
|
||||
}
|
||||
wake_up(&desc->wait);
|
||||
|
||||
set_bit(WDM_READ, &desc->flags);
|
||||
@ -277,7 +287,7 @@ static void cleanup(struct wdm_device *desc)
|
||||
desc->sbuf,
|
||||
desc->validity->transfer_dma);
|
||||
usb_buffer_free(interface_to_usbdev(desc->intf),
|
||||
desc->wMaxCommand,
|
||||
desc->bMaxPacketSize0,
|
||||
desc->inbuf,
|
||||
desc->response->transfer_dma);
|
||||
kfree(desc->orq);
|
||||
@ -314,7 +324,7 @@ static ssize_t wdm_write
|
||||
if (r < 0)
|
||||
goto outnp;
|
||||
|
||||
if (!file->f_flags && O_NONBLOCK)
|
||||
if (!(file->f_flags & O_NONBLOCK))
|
||||
r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
|
||||
&desc->flags));
|
||||
else
|
||||
@ -398,6 +408,11 @@ retry:
|
||||
rv = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
if (test_bit(WDM_OVERFLOW, &desc->flags)) {
|
||||
clear_bit(WDM_OVERFLOW, &desc->flags);
|
||||
rv = -ENOBUFS;
|
||||
goto err;
|
||||
}
|
||||
i++;
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
if (!test_bit(WDM_READ, &desc->flags)) {
|
||||
@ -440,7 +455,10 @@ retry:
|
||||
spin_unlock_irq(&desc->iuspin);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (!desc->reslength) { /* zero length read */
|
||||
dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__);
|
||||
clear_bit(WDM_READ, &desc->flags);
|
||||
spin_unlock_irq(&desc->iuspin);
|
||||
goto retry;
|
||||
}
|
||||
@ -458,7 +476,9 @@ retry:
|
||||
for (i = 0; i < desc->length - cntr; i++)
|
||||
desc->ubuf[i] = desc->ubuf[i + cntr];
|
||||
|
||||
spin_lock_irq(&desc->iuspin);
|
||||
desc->length -= cntr;
|
||||
spin_unlock_irq(&desc->iuspin);
|
||||
/* in case we had outstanding data */
|
||||
if (!desc->length)
|
||||
clear_bit(WDM_READ, &desc->flags);
|
||||
@ -840,6 +860,7 @@ static int wdm_post_reset(struct usb_interface *intf)
|
||||
struct wdm_device *desc = usb_get_intfdata(intf);
|
||||
int rv;
|
||||
|
||||
clear_bit(WDM_OVERFLOW, &desc->flags);
|
||||
rv = recover_from_urb_loss(desc);
|
||||
mutex_unlock(&desc->plock);
|
||||
return 0;
|
||||
|
@ -267,7 +267,7 @@ usbtmc_abort_bulk_in_status:
|
||||
dev_err(dev, "usb_bulk_msg returned %d\n", rv);
|
||||
goto exit;
|
||||
}
|
||||
} while ((actual = max_size) &&
|
||||
} while ((actual == max_size) &&
|
||||
(n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));
|
||||
|
||||
if (actual == max_size) {
|
||||
|
@ -403,7 +403,7 @@ static void async_completed(struct urb *urb)
|
||||
sinfo.si_errno = as->status;
|
||||
sinfo.si_code = SI_ASYNCIO;
|
||||
sinfo.si_addr = as->userurb;
|
||||
pid = as->pid;
|
||||
pid = get_pid(as->pid);
|
||||
uid = as->uid;
|
||||
euid = as->euid;
|
||||
secid = as->secid;
|
||||
@ -416,9 +416,11 @@ static void async_completed(struct urb *urb)
|
||||
cancel_bulk_urbs(ps, as->bulk_addr);
|
||||
spin_unlock(&ps->lock);
|
||||
|
||||
if (signr)
|
||||
if (signr) {
|
||||
kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid,
|
||||
euid, secid);
|
||||
put_pid(pid);
|
||||
}
|
||||
|
||||
wake_up(&ps->wait);
|
||||
}
|
||||
@ -1452,10 +1454,14 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
|
||||
void __user *addr = as->userurb;
|
||||
unsigned int i;
|
||||
|
||||
if (as->userbuffer && urb->actual_length)
|
||||
if (copy_to_user(as->userbuffer, urb->transfer_buffer,
|
||||
urb->actual_length))
|
||||
if (as->userbuffer && urb->actual_length) {
|
||||
if (urb->number_of_packets > 0) /* Isochronous */
|
||||
i = urb->transfer_buffer_length;
|
||||
else /* Non-Isoc */
|
||||
i = urb->actual_length;
|
||||
if (copy_to_user(as->userbuffer, urb->transfer_buffer, i))
|
||||
return -EFAULT;
|
||||
}
|
||||
if (put_user(as->status, &userurb->status))
|
||||
return -EFAULT;
|
||||
if (put_user(urb->actual_length, &userurb->actual_length))
|
||||
|
@ -1187,13 +1187,22 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
|
||||
for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
|
||||
intf = udev->actconfig->interface[i];
|
||||
status = usb_suspend_interface(udev, intf, msg);
|
||||
|
||||
/* Ignore errors during system sleep transitions */
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
status = 0;
|
||||
if (status != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status == 0)
|
||||
if (status == 0) {
|
||||
status = usb_suspend_device(udev, msg);
|
||||
|
||||
/* Again, ignore errors during system sleep transitions */
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
status = 0;
|
||||
}
|
||||
|
||||
/* If the suspend failed, resume interfaces that did get suspended */
|
||||
if (status != 0) {
|
||||
pm_message_t msg2;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/usb/quirks.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/byteorder.h>
|
||||
@ -458,10 +459,8 @@ 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_work(struct work_struct *work)
|
||||
void _hub_tt_work(struct usb_hub *hub)
|
||||
{
|
||||
struct usb_hub *hub =
|
||||
container_of(work, struct usb_hub, tt.clear_work);
|
||||
unsigned long flags;
|
||||
int limit = 100;
|
||||
|
||||
@ -496,6 +495,14 @@ static void hub_tt_work(struct work_struct *work)
|
||||
spin_unlock_irqrestore (&hub->tt.lock, flags);
|
||||
}
|
||||
|
||||
void hub_tt_work(struct work_struct *work)
|
||||
{
|
||||
struct usb_hub *hub =
|
||||
container_of(work, struct usb_hub, tt.clear_work);
|
||||
|
||||
_hub_tt_work(hub);
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
|
||||
* @urb: an URB associated with the failed or incomplete split transaction
|
||||
@ -543,7 +550,20 @@ int usb_hub_clear_tt_buffer(struct urb *urb)
|
||||
/* tell keventd to clear state for this TT */
|
||||
spin_lock_irqsave (&tt->lock, flags);
|
||||
list_add_tail (&clear->clear_list, &tt->clear_list);
|
||||
schedule_work(&tt->clear_work);
|
||||
/* don't schedule on kevent if we're running on keventd (e.g.,
|
||||
* in hid_reset we can get here on kevent) unless on >=2.6.36
|
||||
*/
|
||||
if (!current_is_keventd())
|
||||
/* put it on keventd */
|
||||
schedule_work(&tt->clear_work);
|
||||
else {
|
||||
/* let khubd do it */
|
||||
struct usb_hub *hub =
|
||||
container_of(&tt->clear_work, struct usb_hub,
|
||||
tt.clear_work);
|
||||
kick_khubd(hub);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore (&tt->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
@ -1812,6 +1832,16 @@ int usb_new_device(struct usb_device *udev)
|
||||
/* Tell the world! */
|
||||
announce_device(udev);
|
||||
|
||||
#if 0
|
||||
if (udev->serial)
|
||||
add_device_randomness(udev->serial, strlen(udev->serial));
|
||||
if (udev->product)
|
||||
add_device_randomness(udev->product, strlen(udev->product));
|
||||
if (udev->manufacturer)
|
||||
add_device_randomness(udev->manufacturer,
|
||||
strlen(udev->manufacturer));
|
||||
#endif
|
||||
|
||||
/* Register the device. The device driver is responsible
|
||||
* for configuring the device and invoking the add-device
|
||||
* notifier chain (used by usbfs and possibly others).
|
||||
@ -2188,6 +2218,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
||||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
|
||||
/* System sleep transitions should never fail */
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
status = 0;
|
||||
} else {
|
||||
/* device has up to 10 msec to fully suspend */
|
||||
dev_dbg(&udev->dev, "usb %ssuspend\n",
|
||||
@ -2427,16 +2461,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
unsigned port1;
|
||||
|
||||
/* fail if children aren't already suspended */
|
||||
/* Warn if children aren't already suspended */
|
||||
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
|
||||
struct usb_device *udev;
|
||||
|
||||
udev = hdev->children [port1-1];
|
||||
if (udev && udev->can_submit) {
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
dev_dbg(&intf->dev, "port %d nyet suspended\n",
|
||||
port1);
|
||||
return -EBUSY;
|
||||
dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
|
||||
if (msg.event & PM_EVENT_AUTO)
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3271,6 +3304,10 @@ static void hub_events(void)
|
||||
if (hub->quiescing)
|
||||
goto loop_autopm;
|
||||
|
||||
/* _hub_tt_work usually run on keventd */
|
||||
if (!list_empty(&hub->tt.clear_list))
|
||||
_hub_tt_work(hub);
|
||||
|
||||
if (hub->error) {
|
||||
dev_dbg (hub_dev, "resetting for error %d\n",
|
||||
hub->error);
|
||||
|
@ -38,6 +38,51 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
/* Creative SB Audigy 2 NX */
|
||||
{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C200 */
|
||||
{ USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C250 */
|
||||
{ USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam B/C500 */
|
||||
{ USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C600 */
|
||||
{ USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam Pro 9000 */
|
||||
{ USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C905 */
|
||||
{ USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C210 */
|
||||
{ USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C260 */
|
||||
{ USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C310 */
|
||||
{ USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C910 */
|
||||
{ USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C160 */
|
||||
{ USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C270 */
|
||||
{ USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Quickcam Pro 9000 */
|
||||
{ USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Quickcam E3500 */
|
||||
{ USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Quickcam Vision Pro */
|
||||
{ USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Harmony 700-series */
|
||||
{ USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
@ -69,6 +114,12 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x06a3, 0x0006), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
/* Guillemot Webcam Hercules Dualpix Exchange (2nd ID) */
|
||||
{ USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Guillemot Webcam Hercules Dualpix Exchange*/
|
||||
{ USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* M-Systems Flash Disk Pioneers */
|
||||
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
|
@ -449,7 +449,7 @@ static int dbgp_ehci_startup(void)
|
||||
writel(FLAG_CF, &ehci_regs->configured_flag);
|
||||
|
||||
/* Wait until the controller is no longer halted */
|
||||
loop = 10;
|
||||
loop = 1000;
|
||||
do {
|
||||
status = readl(&ehci_regs->status);
|
||||
if (!(status & STS_HALT))
|
||||
|
@ -1886,6 +1886,7 @@ static int dummy_hcd_probe(struct platform_device *pdev)
|
||||
if (!hcd)
|
||||
return -ENOMEM;
|
||||
the_controller = hcd_to_dummy (hcd);
|
||||
hcd->has_tt = 1;
|
||||
|
||||
retval = usb_add_hcd(hcd, 0, 0);
|
||||
if (retval != 0) {
|
||||
|
@ -373,7 +373,7 @@ int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume)
|
||||
|
||||
/* support autoresume for remote wakeup testing */
|
||||
if (autoresume)
|
||||
sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
|
||||
loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
|
||||
|
||||
/* support OTG systems */
|
||||
if (gadget_is_otg(cdev->gadget)) {
|
||||
|
@ -41,7 +41,7 @@
|
||||
* (host controller _Structural_ parameters)
|
||||
* see EHCI spec, Table 2-4 for each value
|
||||
*/
|
||||
static void dbg_hcs_params (struct ehci_hcd *ehci, char *label)
|
||||
static inline void dbg_hcs_params(struct ehci_hcd *ehci, char *label)
|
||||
{
|
||||
u32 params = ehci_readl(ehci, &ehci->caps->hcs_params);
|
||||
|
||||
@ -85,7 +85,7 @@ static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {}
|
||||
* (host controller _Capability_ parameters)
|
||||
* see EHCI Spec, Table 2-5 for each value
|
||||
* */
|
||||
static void dbg_hcc_params (struct ehci_hcd *ehci, char *label)
|
||||
static inline void dbg_hcc_params(struct ehci_hcd *ehci, char *label)
|
||||
{
|
||||
u32 params = ehci_readl(ehci, &ehci->caps->hcc_params);
|
||||
|
||||
|
@ -84,7 +84,8 @@ static const char hcd_name [] = "ehci_hcd";
|
||||
#define EHCI_IAA_MSECS 10 /* arbitrary */
|
||||
#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */
|
||||
#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */
|
||||
#define EHCI_SHRINK_FRAMES 5 /* async qh unlink delay */
|
||||
#define EHCI_SHRINK_JIFFIES (DIV_ROUND_UP(HZ, 200) + 1)
|
||||
/* 200-ms async qh unlink delay */
|
||||
|
||||
/* Initial IRQ latency: faster than hw default */
|
||||
static int log2_irq_thresh = 0; // 0 to 6
|
||||
@ -139,10 +140,7 @@ timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
|
||||
break;
|
||||
/* case TIMER_ASYNC_SHRINK: */
|
||||
default:
|
||||
/* add a jiffie since we synch against the
|
||||
* 8 KHz uframe counter.
|
||||
*/
|
||||
t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
|
||||
t = EHCI_SHRINK_JIFFIES;
|
||||
break;
|
||||
}
|
||||
mod_timer(&ehci->watchdog, t + jiffies);
|
||||
@ -432,7 +430,7 @@ static void ehci_shutdown(struct usb_hcd *hcd)
|
||||
spin_unlock_irq(&ehci->lock);
|
||||
}
|
||||
|
||||
static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
|
||||
static inline void ehci_port_power(struct ehci_hcd *ehci, int is_on)
|
||||
{
|
||||
unsigned port;
|
||||
|
||||
|
@ -264,7 +264,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
|
||||
u32 temp;
|
||||
u32 power_okay;
|
||||
int i;
|
||||
u8 resume_needed = 0;
|
||||
unsigned long resume_needed = 0;
|
||||
|
||||
if (time_before (jiffies, ehci->next_statechange))
|
||||
msleep(5);
|
||||
@ -328,7 +328,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
|
||||
if (test_bit(i, &ehci->bus_suspended) &&
|
||||
(temp & PORT_SUSPEND)) {
|
||||
temp |= PORT_RESUME;
|
||||
resume_needed = 1;
|
||||
set_bit(i, &resume_needed);
|
||||
}
|
||||
ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
|
||||
}
|
||||
@ -343,8 +343,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
|
||||
i = HCS_N_PORTS (ehci->hcs_params);
|
||||
while (i--) {
|
||||
temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
|
||||
if (test_bit(i, &ehci->bus_suspended) &&
|
||||
(temp & PORT_SUSPEND)) {
|
||||
if (test_bit(i, &resume_needed)) {
|
||||
temp &= ~(PORT_RWC_BITS | PORT_RESUME);
|
||||
ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
|
||||
ehci_vdbg (ehci, "resumed port %d\n", i + 1);
|
||||
@ -779,10 +778,11 @@ static int ehci_hub_control (
|
||||
* power switching; they're allowed to just limit the
|
||||
* current. khubd will turn the power back on.
|
||||
*/
|
||||
if (HCS_PPC (ehci->hcs_params)){
|
||||
if ((temp & PORT_OC) && HCS_PPC(ehci->hcs_params)) {
|
||||
ehci_writel(ehci,
|
||||
temp & ~(PORT_RWC_BITS | PORT_POWER),
|
||||
status_reg);
|
||||
temp = ehci_readl(ehci, status_reg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
|
||||
if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
|
||||
unsigned is_out, epnum;
|
||||
|
||||
is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
|
||||
is_out = qh->is_out;
|
||||
epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f;
|
||||
if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
|
||||
hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
|
||||
@ -936,6 +936,7 @@ done:
|
||||
hw = qh->hw;
|
||||
hw->hw_info1 = cpu_to_hc32(ehci, info1);
|
||||
hw->hw_info2 = cpu_to_hc32(ehci, info2);
|
||||
qh->is_out = !is_input;
|
||||
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
|
||||
qh_refresh (ehci, qh);
|
||||
return qh;
|
||||
@ -1216,6 +1217,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
||||
|
||||
prev->hw->hw_next = qh->hw->hw_next;
|
||||
prev->qh_next = qh->qh_next;
|
||||
if (ehci->qh_scan_next == qh)
|
||||
ehci->qh_scan_next = qh->qh_next.qh;
|
||||
wmb ();
|
||||
|
||||
/* If the controller isn't running, we don't have to wait for it */
|
||||
@ -1241,53 +1244,49 @@ static void scan_async (struct ehci_hcd *ehci)
|
||||
struct ehci_qh *qh;
|
||||
enum ehci_timer_action action = TIMER_IO_WATCHDOG;
|
||||
|
||||
ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index);
|
||||
timer_action_done (ehci, TIMER_ASYNC_SHRINK);
|
||||
rescan:
|
||||
stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state);
|
||||
qh = ehci->async->qh_next.qh;
|
||||
if (likely (qh != NULL)) {
|
||||
do {
|
||||
/* clean any finished work for this qh */
|
||||
if (!list_empty(&qh->qtd_list) && (stopped ||
|
||||
qh->stamp != ehci->stamp)) {
|
||||
int temp;
|
||||
|
||||
/* unlinks could happen here; completion
|
||||
* reporting drops the lock. rescan using
|
||||
* the latest schedule, but don't rescan
|
||||
* qhs we already finished (no looping)
|
||||
* unless the controller is stopped.
|
||||
*/
|
||||
qh = qh_get (qh);
|
||||
qh->stamp = ehci->stamp;
|
||||
temp = qh_completions (ehci, qh);
|
||||
if (qh->needs_rescan)
|
||||
unlink_async(ehci, qh);
|
||||
qh_put (qh);
|
||||
if (temp != 0) {
|
||||
goto rescan;
|
||||
}
|
||||
}
|
||||
ehci->qh_scan_next = ehci->async->qh_next.qh;
|
||||
while (ehci->qh_scan_next) {
|
||||
qh = ehci->qh_scan_next;
|
||||
ehci->qh_scan_next = qh->qh_next.qh;
|
||||
rescan:
|
||||
/* clean any finished work for this qh */
|
||||
if (!list_empty(&qh->qtd_list)) {
|
||||
int temp;
|
||||
|
||||
/* unlink idle entries, reducing DMA usage as well
|
||||
* as HCD schedule-scanning costs. delay for any qh
|
||||
* we just scanned, there's a not-unusual case that it
|
||||
* doesn't stay idle for long.
|
||||
* (plus, avoids some kind of re-activation race.)
|
||||
/*
|
||||
* Unlinks could happen here; completion reporting
|
||||
* drops the lock. That's why ehci->qh_scan_next
|
||||
* always holds the next qh to scan; if the next qh
|
||||
* gets unlinked then ehci->qh_scan_next is adjusted
|
||||
* in start_unlink_async().
|
||||
*/
|
||||
if (list_empty(&qh->qtd_list)
|
||||
&& qh->qh_state == QH_STATE_LINKED) {
|
||||
if (!ehci->reclaim && (stopped ||
|
||||
((ehci->stamp - qh->stamp) & 0x1fff)
|
||||
>= EHCI_SHRINK_FRAMES * 8))
|
||||
start_unlink_async(ehci, qh);
|
||||
else
|
||||
action = TIMER_ASYNC_SHRINK;
|
||||
}
|
||||
qh = qh_get(qh);
|
||||
temp = qh_completions(ehci, qh);
|
||||
if (qh->needs_rescan)
|
||||
unlink_async(ehci, qh);
|
||||
qh->unlink_time = jiffies + EHCI_SHRINK_JIFFIES;
|
||||
qh_put(qh);
|
||||
if (temp != 0)
|
||||
goto rescan;
|
||||
}
|
||||
|
||||
qh = qh->qh_next.qh;
|
||||
} while (qh);
|
||||
/* unlink idle entries, reducing DMA usage as well
|
||||
* as HCD schedule-scanning costs. delay for any qh
|
||||
* we just scanned, there's a not-unusual case that it
|
||||
* doesn't stay idle for long.
|
||||
* (plus, avoids some kind of re-activation race.)
|
||||
*/
|
||||
if (list_empty(&qh->qtd_list)
|
||||
&& qh->qh_state == QH_STATE_LINKED) {
|
||||
if (!ehci->reclaim && (stopped ||
|
||||
time_after_eq(jiffies, qh->unlink_time)))
|
||||
start_unlink_async(ehci, qh);
|
||||
else
|
||||
action = TIMER_ASYNC_SHRINK;
|
||||
}
|
||||
}
|
||||
if (action == TIMER_ASYNC_SHRINK)
|
||||
timer_action (ehci, TIMER_ASYNC_SHRINK);
|
||||
|
@ -62,7 +62,7 @@ stm_ehci_bus_resume(struct usb_hcd *hcd)
|
||||
|
||||
static const struct hc_driver ehci_stm_hc_driver = {
|
||||
.description = hcd_name,
|
||||
.product_desc = "st-ehci",
|
||||
.product_desc = "STMicroelectronics EHCI Host Controller",
|
||||
.hcd_priv_size = sizeof(struct ehci_hcd),
|
||||
|
||||
/*
|
||||
@ -199,6 +199,7 @@ static struct platform_driver ehci_hcd_stm_driver = {
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "stm-ehci",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
@ -216,7 +217,7 @@ int stm_ehci_hcd_unregister(struct platform_device *dev)
|
||||
ret = ehci_hcd_stm_remove(dev);
|
||||
mutex_unlock(&stm_ehci_usb_mutex);
|
||||
if (ret)
|
||||
dgb_print("[STM][USB] Error on %s 0x%x\n", __func__, dev);
|
||||
dgb_print("[STM][USB] Error on %s %p\n", __func__, dev);
|
||||
return ret;
|
||||
|
||||
}
|
||||
@ -230,7 +231,7 @@ int stm_ehci_hcd_register(struct platform_device *dev)
|
||||
ret = ehci_hcd_stm_probe(dev);
|
||||
mutex_unlock(&stm_ehci_usb_mutex);
|
||||
if (ret)
|
||||
dgb_print("[STM][USB] Error on %s 0x%x\n", __func__, dev);
|
||||
dgb_print("[STM][USB] Error on %s %p\n", __func__, dev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(stm_ehci_hcd_register);
|
||||
|
@ -74,6 +74,7 @@ struct ehci_hcd { /* one per controller */
|
||||
/* async schedule support */
|
||||
struct ehci_qh *async;
|
||||
struct ehci_qh *reclaim;
|
||||
struct ehci_qh *qh_scan_next;
|
||||
unsigned scanning : 1;
|
||||
|
||||
/* periodic schedule support */
|
||||
@ -116,7 +117,6 @@ struct ehci_hcd { /* one per controller */
|
||||
struct timer_list iaa_watchdog;
|
||||
struct timer_list watchdog;
|
||||
unsigned long actions;
|
||||
unsigned stamp;
|
||||
unsigned random_frame;
|
||||
unsigned long next_statechange;
|
||||
ktime_t last_periodic_enable;
|
||||
@ -336,6 +336,7 @@ struct ehci_qh {
|
||||
struct ehci_qh *reclaim; /* next to reclaim */
|
||||
|
||||
struct ehci_hcd *ehci;
|
||||
unsigned long unlink_time;
|
||||
|
||||
/*
|
||||
* Do NOT use atomic operations for QH refcounting. On some CPUs
|
||||
@ -367,6 +368,7 @@ struct ehci_qh {
|
||||
#define NO_FRAME ((unsigned short)~0) /* pick new start */
|
||||
|
||||
struct usb_device *dev; /* access to TT */
|
||||
unsigned is_out:1; /* bulk or intr OUT */
|
||||
unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Freescale QUICC Engine USB Host Controller Driver
|
||||
*
|
||||
* Copyright (c) Freescale Semicondutor, Inc. 2006.
|
||||
* Copyright (c) Freescale Semicondutor, Inc. 2006, 2011.
|
||||
* Shlomi Gridish <gridish@freescale.com>
|
||||
* Jerry Huang <Chang-Ming.Huang@freescale.com>
|
||||
* Copyright (c) Logic Product Development, Inc. 2007
|
||||
@ -810,9 +810,11 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
|
||||
ed->dev_addr = usb_pipedevice(urb->pipe);
|
||||
ed->max_pkt_size = usb_maxpacket(urb->dev, urb->pipe,
|
||||
usb_pipeout(urb->pipe));
|
||||
/* setup stage */
|
||||
td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, FHCI_TA_SETUP,
|
||||
USB_TD_TOGGLE_DATA0, urb->setup_packet, 8, 0, 0, true);
|
||||
|
||||
/* data stage */
|
||||
if (data_len > 0) {
|
||||
td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
|
||||
usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
|
||||
@ -820,9 +822,18 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
|
||||
USB_TD_TOGGLE_DATA1, data, data_len, 0, 0,
|
||||
true);
|
||||
}
|
||||
td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
|
||||
usb_pipeout(urb->pipe) ? FHCI_TA_IN : FHCI_TA_OUT,
|
||||
USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true);
|
||||
|
||||
/* status stage */
|
||||
if (data_len > 0)
|
||||
td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
|
||||
(usb_pipeout(urb->pipe) ? FHCI_TA_IN :
|
||||
FHCI_TA_OUT),
|
||||
USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true);
|
||||
else
|
||||
td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
|
||||
FHCI_TA_IN,
|
||||
USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true);
|
||||
|
||||
urb_state = US_CTRL_SETUP;
|
||||
break;
|
||||
case FHCI_TF_ISO:
|
||||
|
@ -71,20 +71,21 @@ static int stm_usb_boot(struct platform_device *pdev)
|
||||
void *wrapper_base = usb_data->ahb2stbus_wrapper_glue_base;
|
||||
void *protocol_base = usb_data->ahb2stbus_protocol_base;
|
||||
unsigned long reg, req_reg;
|
||||
unsigned long flags = pl_data->flags;
|
||||
|
||||
if (pl_data->flags &
|
||||
(STM_PLAT_USB_FLAGS_STRAP_8BIT |
|
||||
STM_PLAT_USB_FLAGS_STRAP_16BIT)) {
|
||||
|
||||
if (flags & (STM_PLAT_USB_FLAGS_STRAP_8BIT |
|
||||
STM_PLAT_USB_FLAGS_STRAP_16BIT)) {
|
||||
/* Set strap mode */
|
||||
reg = readl(wrapper_base + AHB2STBUS_STRAP_OFFSET);
|
||||
if (pl_data->flags & STM_PLAT_USB_FLAGS_STRAP_16BIT)
|
||||
if (flags & STM_PLAT_USB_FLAGS_STRAP_16BIT)
|
||||
reg |= AHB2STBUS_STRAP_16_BIT;
|
||||
else
|
||||
reg &= ~AHB2STBUS_STRAP_16_BIT;
|
||||
writel(reg, wrapper_base + AHB2STBUS_STRAP_OFFSET);
|
||||
}
|
||||
|
||||
if (pl_data->flags & STM_PLAT_USB_FLAGS_STRAP_PLL) {
|
||||
if (flags & STM_PLAT_USB_FLAGS_STRAP_PLL) {
|
||||
/* Start PLL */
|
||||
reg = readl(wrapper_base + AHB2STBUS_STRAP_OFFSET);
|
||||
writel(reg | AHB2STBUS_STRAP_PLL,
|
||||
@ -95,7 +96,7 @@ static int stm_usb_boot(struct platform_device *pdev)
|
||||
mdelay(30);
|
||||
}
|
||||
|
||||
if (pl_data->flags & STM_PLAT_USB_FLAGS_OPC_MSGSIZE_CHUNKSIZE) {
|
||||
if (flags & STM_PLAT_USB_FLAGS_OPC_MSGSIZE_CHUNKSIZE) {
|
||||
/* Set the STBus Opcode Config for load/store 32 */
|
||||
writel(AHB2STBUS_STBUS_OPC_32BIT,
|
||||
protocol_base + AHB2STBUS_STBUS_OPC_OFFSET);
|
||||
@ -109,7 +110,7 @@ static int stm_usb_boot(struct platform_device *pdev)
|
||||
protocol_base + AHB2STBUS_CHUNKSIZE_OFFSET);
|
||||
}
|
||||
|
||||
if (pl_data->flags &
|
||||
if (flags &
|
||||
(STM_PLAT_USB_FLAGS_STBUS_CONFIG_THRESHOLD128 |
|
||||
STM_PLAT_USB_FLAGS_STBUS_CONFIG_THRESHOLD256)) {
|
||||
|
||||
@ -134,24 +135,14 @@ static int stm_usb_boot(struct platform_device *pdev)
|
||||
|
||||
static int stm_usb_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct drv_usb_data *dr_data = platform_get_drvdata(pdev);
|
||||
|
||||
platform_device_unregister(dr_data->ehci_device);
|
||||
platform_device_unregister(dr_data->ohci_device);
|
||||
|
||||
stm_device_power(dr_data->device_state, stm_device_power_off);
|
||||
|
||||
stm_usb_clk_disable(dr_data);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wrapper");
|
||||
devm_release_mem_region(dev, res->start, resource_size(res));
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "protocol");
|
||||
devm_release_mem_region(dev, res->start, resource_size(res));
|
||||
|
||||
if (dr_data->ehci_device)
|
||||
platform_device_unregister(dr_data->ehci_device);
|
||||
if (dr_data->ohci_device)
|
||||
platform_device_unregister(dr_data->ohci_device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -191,7 +182,7 @@ static int __init stm_usb_probe(struct platform_device *pdev)
|
||||
struct drv_usb_data *dr_data;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
int ret = 0, i;
|
||||
int i;
|
||||
static char __initdata *usb_clks_n[USB_CLKS_NR] = {
|
||||
[USB_48_CLK] = "usb_48_clk",
|
||||
[USB_IC_CLK] = "usb_ic_clk",
|
||||
@ -200,7 +191,7 @@ static int __init stm_usb_probe(struct platform_device *pdev)
|
||||
resource_size_t len;
|
||||
|
||||
dgb_print("\n");
|
||||
dr_data = kzalloc(sizeof(struct drv_usb_data), GFP_KERNEL);
|
||||
dr_data = devm_kzalloc(dev, sizeof(*dr_data), GFP_KERNEL);
|
||||
if (!dr_data)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -215,57 +206,47 @@ static int __init stm_usb_probe(struct platform_device *pdev)
|
||||
|
||||
stm_usb_clk_enable(dr_data);
|
||||
|
||||
dr_data->device_state = devm_stm_device_init(&pdev->dev,
|
||||
plat_data->device_config);
|
||||
if (!dr_data->device_state) {
|
||||
ret = -EBUSY;
|
||||
goto err_0;
|
||||
}
|
||||
dr_data->device_state =
|
||||
devm_stm_device_init(&pdev->dev, plat_data->device_config);
|
||||
if (!dr_data->device_state)
|
||||
return -EBUSY;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wrapper");
|
||||
if (!res) {
|
||||
ret = -ENXIO;
|
||||
goto err_0;
|
||||
}
|
||||
if (!res)
|
||||
return -ENXIO;
|
||||
|
||||
len = resource_size(res);
|
||||
if (devm_request_mem_region(dev, res->start, len, pdev->name) < 0) {
|
||||
ret = -EBUSY;
|
||||
goto err_0;
|
||||
}
|
||||
if (devm_request_mem_region(dev, res->start, len, pdev->name) < 0)
|
||||
return -EBUSY;
|
||||
|
||||
dr_data->ahb2stbus_wrapper_glue_base =
|
||||
devm_ioremap_nocache(dev, res->start, len);
|
||||
|
||||
if (!dr_data->ahb2stbus_wrapper_glue_base) {
|
||||
ret = -EFAULT;
|
||||
goto err_1;
|
||||
}
|
||||
if (!dr_data->ahb2stbus_wrapper_glue_base)
|
||||
return -EFAULT;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "protocol");
|
||||
if (!res) {
|
||||
ret = -ENXIO;
|
||||
goto err_2;
|
||||
}
|
||||
if (!res)
|
||||
return -ENXIO;
|
||||
|
||||
len = resource_size(res);
|
||||
if (devm_request_mem_region(dev, res->start, len, pdev->name) < 0) {
|
||||
ret = -EBUSY;
|
||||
goto err_2;
|
||||
}
|
||||
if (devm_request_mem_region(dev, res->start, len, pdev->name) < 0)
|
||||
return -EBUSY;
|
||||
|
||||
dr_data->ahb2stbus_protocol_base =
|
||||
devm_ioremap_nocache(dev, res->start, len);
|
||||
|
||||
if (!dr_data->ahb2stbus_protocol_base) {
|
||||
ret = -EFAULT;
|
||||
goto err_3;
|
||||
}
|
||||
if (!dr_data->ahb2stbus_protocol_base)
|
||||
return -EFAULT;
|
||||
|
||||
stm_usb_boot(pdev);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci");
|
||||
if (res) {
|
||||
dr_data->ehci_device = stm_usb_device_create("stm-ehci",
|
||||
pdev->id, pdev);
|
||||
if (IS_ERR(dr_data->ehci_device)) {
|
||||
ret = (int)dr_data->ehci_device;
|
||||
goto err_4;
|
||||
}
|
||||
if (IS_ERR(dr_data->ehci_device))
|
||||
return PTR_ERR(dr_data->ehci_device);
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci");
|
||||
@ -273,10 +254,8 @@ static int __init stm_usb_probe(struct platform_device *pdev)
|
||||
dr_data->ohci_device =
|
||||
stm_usb_device_create("stm-ohci", pdev->id, pdev);
|
||||
if (IS_ERR(dr_data->ohci_device)) {
|
||||
if (dr_data->ehci_device)
|
||||
platform_device_del(dr_data->ehci_device);
|
||||
ret = (int)dr_data->ohci_device;
|
||||
goto err_4;
|
||||
platform_device_del(dr_data->ehci_device);
|
||||
return PTR_ERR(dr_data->ohci_device);
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,21 +264,7 @@ static int __init stm_usb_probe(struct platform_device *pdev)
|
||||
pm_suspend_ignore_children(&pdev->dev, 1);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
|
||||
err_4:
|
||||
devm_iounmap(dev, dr_data->ahb2stbus_protocol_base);
|
||||
err_3:
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "protocol");
|
||||
devm_release_mem_region(dev, res->start, resource_size(res));
|
||||
err_2:
|
||||
devm_iounmap(dev, dr_data->ahb2stbus_wrapper_glue_base);
|
||||
err_1:
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wrapper");
|
||||
devm_release_mem_region(dev, res->start, resource_size(res));
|
||||
err_0:
|
||||
kfree(dr_data);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stm_usb_shutdown(struct platform_device *pdev)
|
||||
|
@ -56,7 +56,7 @@ static int stm_ohci_bus_suspend(struct usb_hcd *hcd)
|
||||
|
||||
static const struct hc_driver ohci_st40_hc_driver = {
|
||||
.description = hcd_name,
|
||||
.product_desc = "stm-ohci",
|
||||
.product_desc = "STMicroelectronics OHCI Host Controller",
|
||||
.hcd_priv_size = sizeof(struct ohci_hcd),
|
||||
|
||||
/* generic hardware linkage */
|
||||
@ -165,6 +165,7 @@ static struct platform_driver ohci_hcd_stm_driver = {
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "stm-ohci",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
@ -183,7 +184,7 @@ int stm_ohci_hcd_unregister(struct platform_device *dev)
|
||||
ret = ohci_hcd_stm_remove(dev);
|
||||
mutex_unlock(&stm_ohci_usb_mutex);
|
||||
if (ret)
|
||||
dgb_print("[STM][USB] Error on %s 0x%x\n", __func__, dev);
|
||||
dgb_print("[STM][USB] Error on %s %p\n", __func__, dev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(stm_ohci_hcd_unregister);
|
||||
@ -196,7 +197,7 @@ int stm_ohci_hcd_register(struct platform_device *dev)
|
||||
ret = ohci_hcd_stm_probe(dev);
|
||||
mutex_unlock(&stm_ohci_usb_mutex);
|
||||
if (ret)
|
||||
dgb_print("[STM][USB] Error on %s 0x%x\n", __func__, dev);
|
||||
dgb_print("[STM][USB] Error on %s %p\n", __func__, dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -34,6 +34,8 @@
|
||||
#define OHCI_INTRSTATUS 0x0c
|
||||
#define OHCI_INTRENABLE 0x10
|
||||
#define OHCI_INTRDISABLE 0x14
|
||||
#define OHCI_FMINTERVAL 0x34
|
||||
#define OHCI_HCR (1 << 0) /* host controller reset */
|
||||
#define OHCI_OCR (1 << 3) /* ownership change request */
|
||||
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
|
||||
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
|
||||
@ -204,6 +206,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
|
||||
|
||||
/* reset controller, preserving RWC (and possibly IR) */
|
||||
writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
|
||||
readl(base + OHCI_CONTROL);
|
||||
|
||||
/* Some NVIDIA controllers stop working if kept in RESET for too long */
|
||||
if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) {
|
||||
u32 fminterval;
|
||||
int cnt;
|
||||
|
||||
/* drive reset for at least 50 ms (7.1.7.5) */
|
||||
msleep(50);
|
||||
|
||||
/* software reset of the controller, preserving HcFmInterval */
|
||||
fminterval = readl(base + OHCI_FMINTERVAL);
|
||||
writel(OHCI_HCR, base + OHCI_CMDSTATUS);
|
||||
|
||||
/* reset requires max 10 us delay */
|
||||
for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */
|
||||
if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
writel(fminterval, base + OHCI_FMINTERVAL);
|
||||
|
||||
/* Now we're in the SUSPEND state with all devices reset
|
||||
* and wakeups and interrupts disabled
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* disable interrupts
|
||||
@ -390,12 +418,12 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
|
||||
void __iomem *op_reg_base;
|
||||
u32 val;
|
||||
int timeout;
|
||||
int len = pci_resource_len(pdev, 0);
|
||||
|
||||
if (!mmio_resource_enabled(pdev, 0))
|
||||
return;
|
||||
|
||||
base = ioremap_nocache(pci_resource_start(pdev, 0),
|
||||
pci_resource_len(pdev, 0));
|
||||
base = ioremap_nocache(pci_resource_start(pdev, 0), len);
|
||||
if (base == NULL)
|
||||
return;
|
||||
|
||||
@ -405,9 +433,17 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
|
||||
*/
|
||||
ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET);
|
||||
do {
|
||||
if ((ext_cap_offset + sizeof(val)) > len) {
|
||||
/* We're reading garbage from the controller */
|
||||
dev_warn(&pdev->dev,
|
||||
"xHCI controller failing to respond");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ext_cap_offset)
|
||||
/* We've reached the end of the extended capabilities */
|
||||
goto hc_init;
|
||||
|
||||
val = readl(base + ext_cap_offset);
|
||||
if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY)
|
||||
break;
|
||||
@ -416,7 +452,7 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
|
||||
|
||||
/* If the BIOS owns the HC, signal that the OS wants it, and wait */
|
||||
if (val & XHCI_HC_BIOS_OWNED) {
|
||||
writel(val & XHCI_HC_OS_OWNED, base + ext_cap_offset);
|
||||
writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset);
|
||||
|
||||
/* Wait for 5 seconds with 10 microsecond polling interval */
|
||||
timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED,
|
||||
@ -430,9 +466,13 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable any BIOS SMIs */
|
||||
writel(XHCI_LEGACY_DISABLE_SMI,
|
||||
base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
|
||||
val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
|
||||
/* Mask off (turn off) any enabled SMIs */
|
||||
val &= XHCI_LEGACY_DISABLE_SMI;
|
||||
/* Mask all SMI events bits, RW1C */
|
||||
val |= XHCI_LEGACY_SMI_EVENTS;
|
||||
/* Disable any BIOS SMIs and clear all SMI events*/
|
||||
writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
|
||||
|
||||
hc_init:
|
||||
op_reg_base = base + XHCI_HC_LENGTH(readl(base));
|
||||
@ -470,6 +510,22 @@ hc_init:
|
||||
|
||||
static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
|
||||
{
|
||||
/* Skip Netlogic mips SoC's internal PCI USB controller.
|
||||
* This device does not need/support EHCI/OHCI handoff
|
||||
*/
|
||||
if (pdev->vendor == 0x184e) /* vendor Netlogic */
|
||||
return;
|
||||
if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI &&
|
||||
pdev->class != PCI_CLASS_SERIAL_USB_OHCI &&
|
||||
pdev->class != PCI_CLASS_SERIAL_USB_EHCI &&
|
||||
pdev->class != PCI_CLASS_SERIAL_USB_XHCI)
|
||||
return;
|
||||
|
||||
if (pci_enable_device(pdev) < 0) {
|
||||
dev_warn(&pdev->dev, "Can't enable PCI device, "
|
||||
"BIOS handoff failed.\n");
|
||||
return;
|
||||
}
|
||||
if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI)
|
||||
quirk_usb_handoff_uhci(pdev);
|
||||
else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI)
|
||||
@ -478,5 +534,6 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
|
||||
quirk_usb_disable_ehci(pdev);
|
||||
else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI)
|
||||
quirk_usb_handoff_xhci(pdev);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
|
||||
|
@ -104,7 +104,7 @@ void qset_clear(struct whc *whc, struct whc_qset *qset)
|
||||
{
|
||||
qset->td_start = qset->td_end = qset->ntds = 0;
|
||||
|
||||
qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T);
|
||||
qset->qh.link = cpu_to_le64(QH_LINK_NTDS(8) | QH_LINK_T);
|
||||
qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK;
|
||||
qset->qh.err_count = 0;
|
||||
qset->qh.scratch[0] = 0;
|
||||
|
@ -62,8 +62,9 @@
|
||||
/* USB Legacy Support Control and Status Register - section 7.1.2 */
|
||||
/* Add this offset, plus the value of xECP in HCCPARAMS to the base address */
|
||||
#define XHCI_LEGACY_CONTROL_OFFSET (0x04)
|
||||
/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */
|
||||
#define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17))
|
||||
/* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */
|
||||
#define XHCI_LEGACY_DISABLE_SMI ((0x7 << 1) + (0xff << 5) + (0x7 << 17))
|
||||
#define XHCI_LEGACY_SMI_EVENTS (0x7 << 29)
|
||||
|
||||
/* command register values to disable interrupts and halt the HC */
|
||||
/* start/stop HC execution - do not write unless HC is halted*/
|
||||
|
@ -150,7 +150,7 @@ int xhci_reset(struct xhci_hcd *xhci)
|
||||
xhci_to_hcd(xhci)->state = HC_STATE_HALT;
|
||||
|
||||
ret = handshake(xhci, &xhci->op_regs->command,
|
||||
CMD_RESET, 0, 250 * 1000);
|
||||
CMD_RESET, 0, 10 * 1000 * 1000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -979,6 +979,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
u32 added_ctxs;
|
||||
unsigned int last_ctx;
|
||||
u32 new_add_flags, new_drop_flags, new_slot_info;
|
||||
struct xhci_virt_device *virt_dev;
|
||||
int ret = 0;
|
||||
|
||||
ret = xhci_check_args(hcd, udev, ep, 1, __func__);
|
||||
@ -1007,11 +1008,25 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
in_ctx = xhci->devs[udev->slot_id]->in_ctx;
|
||||
out_ctx = xhci->devs[udev->slot_id]->out_ctx;
|
||||
virt_dev = xhci->devs[udev->slot_id];
|
||||
in_ctx = virt_dev->in_ctx;
|
||||
out_ctx = virt_dev->out_ctx;
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
|
||||
ep_index = xhci_get_endpoint_index(&ep->desc);
|
||||
ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
|
||||
|
||||
/* If this endpoint is already in use, and the upper layers are trying
|
||||
* to add it again without dropping it, reject the addition.
|
||||
*/
|
||||
if (virt_dev->eps[ep_index].ring &&
|
||||
!(le32_to_cpu(ctrl_ctx->drop_flags) &
|
||||
xhci_get_endpoint_flag(&ep->desc))) {
|
||||
xhci_warn(xhci, "Trying to add endpoint 0x%x "
|
||||
"without dropping it.\n",
|
||||
(unsigned int) ep->desc.bEndpointAddress);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If the HCD has already noted the endpoint is enabled,
|
||||
* ignore this request.
|
||||
*/
|
||||
@ -1026,8 +1041,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
* process context, not interrupt context (or so documenation
|
||||
* for usb_set_interface() and usb_set_configuration() claim).
|
||||
*/
|
||||
if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id],
|
||||
udev, ep, GFP_KERNEL) < 0) {
|
||||
if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_NOIO) < 0) {
|
||||
dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
|
||||
__func__, ep->desc.bEndpointAddress);
|
||||
return -ENOMEM;
|
||||
|
@ -110,18 +110,20 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring)
|
||||
struct xhci_segment *seg;
|
||||
struct xhci_segment *first_seg;
|
||||
|
||||
if (!ring || !ring->first_seg)
|
||||
if (!ring)
|
||||
return;
|
||||
first_seg = ring->first_seg;
|
||||
seg = first_seg->next;
|
||||
xhci_dbg(xhci, "Freeing ring at %p\n", ring);
|
||||
while (seg != first_seg) {
|
||||
struct xhci_segment *next = seg->next;
|
||||
xhci_segment_free(xhci, seg);
|
||||
seg = next;
|
||||
if (ring->first_seg) {
|
||||
first_seg = ring->first_seg;
|
||||
seg = first_seg->next;
|
||||
xhci_dbg(xhci, "Freeing ring at %p\n", ring);
|
||||
while (seg != first_seg) {
|
||||
struct xhci_segment *next = seg->next;
|
||||
xhci_segment_free(xhci, seg);
|
||||
seg = next;
|
||||
}
|
||||
xhci_segment_free(xhci, first_seg);
|
||||
ring->first_seg = NULL;
|
||||
}
|
||||
xhci_segment_free(xhci, first_seg);
|
||||
ring->first_seg = NULL;
|
||||
kfree(ring);
|
||||
}
|
||||
|
||||
@ -470,26 +472,42 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert bInterval expressed in frames (in 1-255 range) to exponent of
|
||||
* Convert bInterval expressed in microframes (in 1-255 range) to exponent of
|
||||
* microframes, rounded down to nearest power of 2.
|
||||
*/
|
||||
static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep)
|
||||
static unsigned int xhci_microframes_to_exponent(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep, unsigned int desc_interval,
|
||||
unsigned int min_exponent, unsigned int max_exponent)
|
||||
{
|
||||
unsigned int interval;
|
||||
|
||||
interval = fls(8 * ep->desc.bInterval) - 1;
|
||||
interval = clamp_val(interval, 3, 10);
|
||||
if ((1 << interval) != 8 * ep->desc.bInterval)
|
||||
interval = fls(desc_interval) - 1;
|
||||
interval = clamp_val(interval, min_exponent, max_exponent);
|
||||
if ((1 << interval) != desc_interval)
|
||||
dev_warn(&udev->dev,
|
||||
"ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n",
|
||||
ep->desc.bEndpointAddress,
|
||||
1 << interval,
|
||||
8 * ep->desc.bInterval);
|
||||
desc_interval);
|
||||
|
||||
return interval;
|
||||
}
|
||||
|
||||
static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
return xhci_microframes_to_exponent(udev, ep,
|
||||
ep->desc.bInterval, 0, 15);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
return xhci_microframes_to_exponent(udev, ep,
|
||||
ep->desc.bInterval * 8, 3, 10);
|
||||
}
|
||||
|
||||
/* Return the polling or NAK interval.
|
||||
*
|
||||
* The polling interval is expressed in "microframes". If xHCI's Interval field
|
||||
@ -508,7 +526,7 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
|
||||
/* Max NAK rate */
|
||||
if (usb_endpoint_xfer_control(&ep->desc) ||
|
||||
usb_endpoint_xfer_bulk(&ep->desc)) {
|
||||
interval = ep->desc.bInterval;
|
||||
interval = xhci_parse_microframe_interval(udev, ep);
|
||||
break;
|
||||
}
|
||||
/* Fall through - SS and HS isoc/int have same decoding */
|
||||
@ -916,11 +934,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
|
||||
int i;
|
||||
|
||||
/* Free the Event Ring Segment Table and the actual Event Ring */
|
||||
if (xhci->ir_set) {
|
||||
xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
|
||||
xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
|
||||
xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
|
||||
}
|
||||
size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
|
||||
if (xhci->erst.entries)
|
||||
pci_free_consistent(pdev, size,
|
||||
@ -932,7 +945,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
|
||||
xhci->event_ring = NULL;
|
||||
xhci_dbg(xhci, "Freed event ring\n");
|
||||
|
||||
xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
|
||||
xhci->cmd_ring_reserved_trbs = 0;
|
||||
if (xhci->cmd_ring)
|
||||
xhci_ring_free(xhci, xhci->cmd_ring);
|
||||
xhci->cmd_ring = NULL;
|
||||
@ -951,7 +964,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
|
||||
xhci->device_pool = NULL;
|
||||
xhci_dbg(xhci, "Freed device context pool\n");
|
||||
|
||||
xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr);
|
||||
if (xhci->dcbaa)
|
||||
pci_free_consistent(pdev, sizeof(*xhci->dcbaa),
|
||||
xhci->dcbaa, xhci->dcbaa->dma);
|
||||
@ -1128,6 +1140,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
||||
|
||||
fail:
|
||||
xhci_warn(xhci, "Couldn't initialize memory\n");
|
||||
xhci_halt(xhci);
|
||||
xhci_reset(xhci);
|
||||
xhci_mem_cleanup(xhci);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -54,8 +54,9 @@ static int isight_firmware_load(struct usb_interface *intf,
|
||||
|
||||
ptr = firmware->data;
|
||||
|
||||
buf[0] = 0x01;
|
||||
if (usb_control_msg
|
||||
(dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1,
|
||||
(dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,
|
||||
300) != 1) {
|
||||
printk(KERN_ERR
|
||||
"Failed to initialise isight firmware loader\n");
|
||||
@ -99,8 +100,9 @@ static int isight_firmware_load(struct usb_interface *intf,
|
||||
}
|
||||
}
|
||||
|
||||
buf[0] = 0x00;
|
||||
if (usb_control_msg
|
||||
(dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1,
|
||||
(dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,
|
||||
300) != 1) {
|
||||
printk(KERN_ERR "isight firmware loading completion failed\n");
|
||||
ret = -ENODEV;
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#define VENDOR_ID 0x0fc5
|
||||
#define PRODUCT_ID 0x1227
|
||||
#define MAXLEN 6
|
||||
#define MAXLEN 8
|
||||
|
||||
/* table of devices that work with this driver */
|
||||
static struct usb_device_id id_table[] = {
|
||||
|
@ -1041,7 +1041,7 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
|
||||
nevents = mon_bin_queued(rp);
|
||||
|
||||
sp = (struct mon_bin_stats __user *)arg;
|
||||
if (put_user(rp->cnt_lost, &sp->dropped))
|
||||
if (put_user(ndropped, &sp->dropped))
|
||||
return -EFAULT;
|
||||
if (put_user(nevents, &sp->queued))
|
||||
return -EFAULT;
|
||||
|
@ -94,6 +94,7 @@ static struct usb_device_id id_table [] = {
|
||||
{ USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */
|
||||
{ USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
|
||||
{ USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
|
||||
{ USB_DEVICE(0x10C4, 0x81A9) }, /* Multiplex RC Interface */
|
||||
{ USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
|
||||
{ USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */
|
||||
{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
|
||||
@ -135,10 +136,13 @@ static struct usb_device_id id_table [] = {
|
||||
{ USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */
|
||||
{ USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */
|
||||
{ USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
|
||||
{ USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */
|
||||
{ USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */
|
||||
{ USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
|
||||
{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
|
||||
{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
|
||||
{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
|
||||
{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
|
||||
{ USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
|
||||
{ } /* Terminating Entry */
|
||||
};
|
||||
@ -359,8 +363,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port,
|
||||
* Quantises the baud rate as per AN205 Table 1
|
||||
*/
|
||||
static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
|
||||
if (baud <= 56) baud = 0;
|
||||
else if (baud <= 300) baud = 300;
|
||||
if (baud <= 300)
|
||||
baud = 300;
|
||||
else if (baud <= 600) baud = 600;
|
||||
else if (baud <= 1200) baud = 1200;
|
||||
else if (baud <= 1800) baud = 1800;
|
||||
|
@ -105,6 +105,7 @@ static int ftdi_jtag_probe(struct usb_serial *serial);
|
||||
static int ftdi_mtxorb_hack_setup(struct usb_serial *serial);
|
||||
static int ftdi_NDI_device_setup(struct usb_serial *serial);
|
||||
static int ftdi_stmclite_probe(struct usb_serial *serial);
|
||||
static int ftdi_8u2232c_probe(struct usb_serial *serial);
|
||||
static void ftdi_USB_UIRT_setup(struct ftdi_private *priv);
|
||||
static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
|
||||
|
||||
@ -132,6 +133,10 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = {
|
||||
.probe = ftdi_stmclite_probe,
|
||||
};
|
||||
|
||||
static struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
|
||||
.probe = ftdi_8u2232c_probe,
|
||||
};
|
||||
|
||||
/*
|
||||
* The 8U232AM has the same API as the sio except for:
|
||||
* - it can support MUCH higher baudrates; up to:
|
||||
@ -155,6 +160,7 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = {
|
||||
* /sys/bus/usb/ftdi_sio/new_id, then send patch/report!
|
||||
*/
|
||||
static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) },
|
||||
@ -181,7 +187,8 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) ,
|
||||
.driver_info = (kernel_ulong_t)&ftdi_8u2232c_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
|
||||
@ -203,6 +210,8 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_XF_640_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_XF_642_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_URBAN_0_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_URBAN_1_PID) },
|
||||
{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) },
|
||||
@ -730,6 +739,7 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) },
|
||||
{ USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID),
|
||||
@ -740,6 +750,8 @@ static struct usb_device_id id_table_combined [] = {
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
|
||||
@ -786,6 +798,7 @@ static struct usb_device_id id_table_combined [] = {
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(HORNBY_VID, HORNBY_ELITE_PID) },
|
||||
{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
|
||||
{ USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
@ -794,6 +807,8 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, TI_XDS100V2_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) },
|
||||
@ -825,11 +840,13 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
|
||||
{ USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(ST_VID, ST_STMCLT1030_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
|
||||
{ }, /* Optional parameter entry */
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
@ -1339,8 +1356,7 @@ static int set_serial_info(struct tty_struct *tty,
|
||||
goto check_and_exit;
|
||||
}
|
||||
|
||||
if ((new_serial.baud_base != priv->baud_base) &&
|
||||
(new_serial.baud_base < 9600)) {
|
||||
if (new_serial.baud_base != priv->baud_base) {
|
||||
unlock_kernel();
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1762,6 +1778,19 @@ static int ftdi_jtag_probe(struct usb_serial *serial)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ftdi_8u2232c_probe(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_device *udev = serial->dev;
|
||||
|
||||
dbg("%s", __func__);
|
||||
|
||||
if ((udev->manufacturer) &&
|
||||
(strcmp(udev->manufacturer, "CALAO Systems") == 0))
|
||||
return ftdi_jtag_probe(serial);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* First and second port on STMCLiteadaptors is reserved for JTAG interface
|
||||
* and the forth port for pio
|
||||
@ -1841,6 +1870,7 @@ static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
|
||||
|
||||
static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
{ /* ftdi_open */
|
||||
struct ktermios dummy;
|
||||
struct usb_device *dev = port->serial->dev;
|
||||
struct ftdi_private *priv = usb_get_serial_port_data(port);
|
||||
unsigned long flags;
|
||||
@ -1868,8 +1898,10 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
This is same behaviour as serial.c/rs_open() - Kuba */
|
||||
|
||||
/* ftdi_set_termios will send usb control messages */
|
||||
if (tty)
|
||||
ftdi_set_termios(tty, port, tty->termios);
|
||||
if (tty) {
|
||||
memset(&dummy, 0, sizeof(dummy));
|
||||
ftdi_set_termios(tty, port, &dummy);
|
||||
}
|
||||
|
||||
/* Not throttled */
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
@ -2332,13 +2364,23 @@ static void ftdi_set_termios(struct tty_struct *tty,
|
||||
|
||||
cflag = termios->c_cflag;
|
||||
|
||||
/* FIXME -For this cut I don't care if the line is really changing or
|
||||
not - so just do the change regardless - should be able to
|
||||
compare old_termios and tty->termios */
|
||||
if (!old_termios)
|
||||
goto no_skip;
|
||||
|
||||
if (old_termios->c_cflag == termios->c_cflag
|
||||
&& old_termios->c_ispeed == termios->c_ispeed
|
||||
&& old_termios->c_ospeed == termios->c_ospeed)
|
||||
goto no_c_cflag_changes;
|
||||
|
||||
/* NOTE These routines can get interrupted by
|
||||
ftdi_sio_read_bulk_callback - need to examine what this means -
|
||||
don't see any problems yet */
|
||||
|
||||
if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) ==
|
||||
(termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)))
|
||||
goto no_data_parity_stop_changes;
|
||||
|
||||
no_skip:
|
||||
/* Set number of data bits, parity, stop bits */
|
||||
|
||||
termios->c_cflag &= ~CMSPAR;
|
||||
@ -2375,6 +2417,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
|
||||
}
|
||||
|
||||
/* Now do the baudrate */
|
||||
no_data_parity_stop_changes:
|
||||
if ((cflag & CBAUD) == B0) {
|
||||
/* Disable flow control */
|
||||
if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||
@ -2400,6 +2443,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
|
||||
|
||||
/* Set flow control */
|
||||
/* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */
|
||||
no_c_cflag_changes:
|
||||
if (cflag & CRTSCTS) {
|
||||
dbg("%s Setting to CRTSCTS flow control", __func__);
|
||||
if (usb_control_msg(dev,
|
||||
|
@ -38,6 +38,13 @@
|
||||
/* www.candapter.com Ewert Energy Systems CANdapter device */
|
||||
#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */
|
||||
|
||||
/*
|
||||
* Texas Instruments XDS100v2 JTAG / BeagleBone A3
|
||||
* http://processors.wiki.ti.com/index.php/XDS100
|
||||
* http://beagleboard.org/bone
|
||||
*/
|
||||
#define TI_XDS100V2_PID 0xa6d0
|
||||
|
||||
#define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */
|
||||
|
||||
/* US Interface Navigator (http://www.usinterface.com/) */
|
||||
@ -53,6 +60,7 @@
|
||||
/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */
|
||||
#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8
|
||||
#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9
|
||||
#define LMI_LM3S_ICDI_BOARD_PID 0xbcda
|
||||
|
||||
#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */
|
||||
|
||||
@ -110,6 +118,7 @@
|
||||
|
||||
/* Propox devices */
|
||||
#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
|
||||
#define FTDI_PROPOX_ISPCABLEIII_PID 0xD739
|
||||
|
||||
/* Lenz LI-USB Computer Interface. */
|
||||
#define FTDI_LENZ_LIUSB_PID 0xD780
|
||||
@ -419,9 +428,11 @@
|
||||
#define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */
|
||||
|
||||
/*
|
||||
* DSS-20 Sync Station for Sony Ericsson P800
|
||||
* Sony Ericsson product ids
|
||||
*/
|
||||
#define FTDI_DSS20_PID 0xFC82
|
||||
#define FTDI_DSS20_PID 0xFC82 /* DSS-20 Sync Station for Sony Ericsson P800 */
|
||||
#define FTDI_URBAN_0_PID 0xFC8A /* Sony Ericsson Urban, uart #0 */
|
||||
#define FTDI_URBAN_1_PID 0xFC8B /* Sony Ericsson Urban, uart #1 */
|
||||
|
||||
/* www.irtrans.de device */
|
||||
#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */
|
||||
@ -519,6 +530,12 @@
|
||||
#define ADI_GNICE_PID 0xF000
|
||||
#define ADI_GNICEPLUS_PID 0xF001
|
||||
|
||||
/*
|
||||
* Hornby Elite
|
||||
*/
|
||||
#define HORNBY_VID 0x04D8
|
||||
#define HORNBY_ELITE_PID 0x000A
|
||||
|
||||
/*
|
||||
* RATOC REX-USB60F
|
||||
*/
|
||||
@ -1164,4 +1181,21 @@
|
||||
/* USB-Nano-485*/
|
||||
#define FTDI_CTI_NANO_PID 0xF60B
|
||||
|
||||
/*
|
||||
* ZeitControl cardsystems GmbH rfid-readers http://zeitconrol.de
|
||||
*/
|
||||
/* TagTracer MIFARE*/
|
||||
#define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID 0xF7C0
|
||||
|
||||
/*
|
||||
* Rainforest Automation
|
||||
*/
|
||||
/* ZigBee controller */
|
||||
#define FTDI_RF_R106 0x8A28
|
||||
|
||||
/*
|
||||
* Product: HCP HIT GPRS modem
|
||||
* Manufacturer: HCP d.o.o.
|
||||
* ATI command output: Cinterion MC55i
|
||||
*/
|
||||
#define FTDI_CINTERION_MC55I_PID 0xA951
|
||||
|
@ -974,10 +974,7 @@ static void garmin_close(struct usb_serial_port *port)
|
||||
if (!serial)
|
||||
return;
|
||||
|
||||
mutex_lock(&port->serial->disc_mutex);
|
||||
|
||||
if (!port->serial->disconnected)
|
||||
garmin_clear(garmin_data_p);
|
||||
garmin_clear(garmin_data_p);
|
||||
|
||||
/* shutdown our urbs */
|
||||
usb_kill_urb(port->read_urb);
|
||||
@ -986,8 +983,6 @@ static void garmin_close(struct usb_serial_port *port)
|
||||
/* keep reset state so we know that we must start a new session */
|
||||
if (garmin_data_p->state != STATE_RESET)
|
||||
garmin_data_p->state = STATE_DISCONNECTED;
|
||||
|
||||
mutex_unlock(&port->serial->disc_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -574,6 +574,9 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
|
||||
wait_queue_t wait;
|
||||
unsigned long flags;
|
||||
|
||||
if (!tty)
|
||||
return;
|
||||
|
||||
if (!timeout)
|
||||
timeout = (HZ * EDGE_CLOSING_WAIT)/100;
|
||||
|
||||
@ -2664,15 +2667,7 @@ cleanup:
|
||||
|
||||
static void edge_disconnect(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
struct edgeport_port *edge_port;
|
||||
|
||||
dbg("%s", __func__);
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
edge_port = usb_get_serial_port_data(serial->port[i]);
|
||||
edge_remove_sysfs_attrs(edge_port->port);
|
||||
}
|
||||
}
|
||||
|
||||
static void edge_release(struct usb_serial *serial)
|
||||
@ -2927,6 +2922,7 @@ static struct usb_serial_driver edgeport_1port_device = {
|
||||
.disconnect = edge_disconnect,
|
||||
.release = edge_release,
|
||||
.port_probe = edge_create_sysfs_attrs,
|
||||
.port_remove = edge_remove_sysfs_attrs,
|
||||
.ioctl = edge_ioctl,
|
||||
.set_termios = edge_set_termios,
|
||||
.tiocmget = edge_tiocmget,
|
||||
@ -2957,6 +2953,7 @@ static struct usb_serial_driver edgeport_2port_device = {
|
||||
.disconnect = edge_disconnect,
|
||||
.release = edge_release,
|
||||
.port_probe = edge_create_sysfs_attrs,
|
||||
.port_remove = edge_remove_sysfs_attrs,
|
||||
.ioctl = edge_ioctl,
|
||||
.set_termios = edge_set_termios,
|
||||
.tiocmget = edge_tiocmget,
|
||||
|
@ -1181,9 +1181,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty)
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&mos7840_port->pool_lock, flags);
|
||||
for (i = 0; i < NUM_URBS; ++i)
|
||||
if (mos7840_port->busy[i])
|
||||
chars += URB_TRANSFER_BUFFER_SIZE;
|
||||
for (i = 0; i < NUM_URBS; ++i) {
|
||||
if (mos7840_port->busy[i]) {
|
||||
struct urb *urb = mos7840_port->write_urb_pool[i];
|
||||
chars += urb->transfer_buffer_length;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
|
||||
dbg("%s - returns %d", __func__, chars);
|
||||
return chars;
|
||||
@ -2566,7 +2569,6 @@ error:
|
||||
kfree(mos7840_port->ctrl_buf);
|
||||
usb_free_urb(mos7840_port->control_urb);
|
||||
kfree(mos7840_port);
|
||||
serial->port[i] = NULL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -2633,6 +2635,7 @@ static void mos7840_release(struct usb_serial *serial)
|
||||
mos7840_port = mos7840_get_port_private(serial->port[i]);
|
||||
dbg("mos7840_port %d = %p", i, mos7840_port);
|
||||
if (mos7840_port) {
|
||||
usb_free_urb(mos7840_port->control_urb);
|
||||
kfree(mos7840_port->ctrl_buf);
|
||||
kfree(mos7840_port->dr);
|
||||
kfree(mos7840_port);
|
||||
|
@ -317,7 +317,7 @@ static int omninet_write_room(struct tty_struct *tty)
|
||||
int room = 0; /* Default: no room */
|
||||
|
||||
/* FIXME: no consistent locking for write_urb_busy */
|
||||
if (wport->write_urb_busy)
|
||||
if (!wport->write_urb_busy)
|
||||
room = wport->bulk_out_size - OMNINET_HEADERLEN;
|
||||
|
||||
dbg("%s - returns %d", __func__, room);
|
||||
|
@ -618,6 +618,7 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
|
||||
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
|
||||
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
|
||||
|
@ -100,6 +100,8 @@ static struct usb_device_id id_table [] = {
|
||||
{ USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
|
||||
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
|
||||
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
|
||||
{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
|
||||
{ USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
@ -615,10 +617,28 @@ static void pl2303_set_termios(struct tty_struct *tty,
|
||||
baud = 6000000;
|
||||
}
|
||||
dbg("%s - baud set = %d", __func__, baud);
|
||||
buf[0] = baud & 0xff;
|
||||
buf[1] = (baud >> 8) & 0xff;
|
||||
buf[2] = (baud >> 16) & 0xff;
|
||||
buf[3] = (baud >> 24) & 0xff;
|
||||
if (baud <= 115200) {
|
||||
buf[0] = baud & 0xff;
|
||||
buf[1] = (baud >> 8) & 0xff;
|
||||
buf[2] = (baud >> 16) & 0xff;
|
||||
buf[3] = (baud >> 24) & 0xff;
|
||||
} else {
|
||||
/* apparently the formula for higher speeds is:
|
||||
* baudrate = 12M * 32 / (2^buf[1]) / buf[0]
|
||||
*/
|
||||
unsigned tmp = 12*1000*1000*32 / baud;
|
||||
buf[3] = 0x80;
|
||||
buf[2] = 0;
|
||||
buf[1] = (tmp >= 256);
|
||||
while (tmp >= 256) {
|
||||
tmp >>= 2;
|
||||
buf[1] <<= 1;
|
||||
}
|
||||
if (tmp > 256) {
|
||||
tmp %= 256;
|
||||
}
|
||||
buf[0] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* For reference buf[4]=0 is 1 stop bits */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#define BENQ_VENDOR_ID 0x04a5
|
||||
@ -140,3 +140,12 @@
|
||||
/* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */
|
||||
#define SANWA_VENDOR_ID 0x11ad
|
||||
#define SANWA_PRODUCT_ID 0x0001
|
||||
|
||||
/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
|
||||
#define ADLINK_VENDOR_ID 0x0b63
|
||||
#define ADLINK_ND6530_PRODUCT_ID 0x6530
|
||||
|
||||
/* SMART USB Serial Adapter */
|
||||
#define SMART_VENDOR_ID 0x0b8c
|
||||
#define SMART_PRODUCT_ID 0x2303
|
||||
|
||||
|
@ -28,6 +28,7 @@ static const struct usb_device_id id_table[] = {
|
||||
{USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
|
||||
{USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
|
||||
{USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */
|
||||
{USB_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */
|
||||
{USB_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */
|
||||
{USB_DEVICE(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */
|
||||
{USB_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */
|
||||
@ -45,6 +46,7 @@ static const struct usb_device_id id_table[] = {
|
||||
{USB_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */
|
||||
{USB_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */
|
||||
{USB_DEVICE(0x05c6, 0x9008)}, /* Generic Gobi QDL device */
|
||||
{USB_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */
|
||||
{USB_DEVICE(0x05c6, 0x9201)}, /* Generic Gobi QDL device */
|
||||
{USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */
|
||||
{USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */
|
||||
@ -78,6 +80,7 @@ static const struct usb_device_id id_table[] = {
|
||||
{USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
|
||||
{USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
|
||||
{USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
|
||||
{USB_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */
|
||||
{USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */
|
||||
{USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */
|
||||
{USB_DEVICE(0x05c6, 0x9204)}, /* Gobi 2000 QDL device */
|
||||
|
@ -925,6 +925,7 @@ static void sierra_release(struct usb_serial *serial)
|
||||
continue;
|
||||
kfree(portdata);
|
||||
}
|
||||
kfree(serial->private);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -1071,6 +1071,12 @@ int usb_serial_probe(struct usb_interface *interface,
|
||||
serial->attached = 1;
|
||||
}
|
||||
|
||||
/* Avoid race with tty_open and serial_install by setting the
|
||||
* disconnected flag and not clearing it until all ports have been
|
||||
* registered.
|
||||
*/
|
||||
serial->disconnected = 1;
|
||||
|
||||
if (get_free_serial(serial, num_ports, &minor) == NULL) {
|
||||
dev_err(&interface->dev, "No more free serial devices\n");
|
||||
goto probe_error;
|
||||
@ -1093,6 +1099,8 @@ int usb_serial_probe(struct usb_interface *interface,
|
||||
}
|
||||
}
|
||||
|
||||
serial->disconnected = 0;
|
||||
|
||||
usb_serial_console_init(debug, minor);
|
||||
|
||||
exit:
|
||||
|
@ -576,6 +576,7 @@ no_firmware:
|
||||
"%s: please contact support@connecttech.com\n",
|
||||
serial->type->description);
|
||||
kfree(result);
|
||||
kfree(command);
|
||||
return -ENODEV;
|
||||
|
||||
no_command_private:
|
||||
|
@ -58,7 +58,9 @@
|
||||
|
||||
void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
|
||||
{
|
||||
/* Pad the SCSI command with zeros out to 12 bytes
|
||||
/*
|
||||
* Pad the SCSI command with zeros out to 12 bytes. If the
|
||||
* command already is 12 bytes or longer, leave it alone.
|
||||
*
|
||||
* NOTE: This only works because a scsi_cmnd struct field contains
|
||||
* a unsigned char cmnd[16], so we know we have storage available
|
||||
@ -66,9 +68,6 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
|
||||
for (; srb->cmd_len<12; srb->cmd_len++)
|
||||
srb->cmnd[srb->cmd_len] = 0;
|
||||
|
||||
/* set command length to 12 bytes */
|
||||
srb->cmd_len = 12;
|
||||
|
||||
/* send the command to the transport layer */
|
||||
usb_stor_invoke_transport(srb, us);
|
||||
}
|
||||
|
@ -693,6 +693,9 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
|
||||
int temp_result;
|
||||
struct scsi_eh_save ses;
|
||||
int sense_size = US_SENSE_SIZE;
|
||||
struct scsi_sense_hdr sshdr;
|
||||
const u8 *scdd;
|
||||
u8 fm_ili;
|
||||
|
||||
/* device supports and needs bigger sense buffer */
|
||||
if (us->fflags & US_FL_SANE_SENSE)
|
||||
@ -776,32 +779,30 @@ Retry_Sense:
|
||||
srb->sense_buffer[7] = (US_SENSE_SIZE - 8);
|
||||
}
|
||||
|
||||
scsi_normalize_sense(srb->sense_buffer, SCSI_SENSE_BUFFERSIZE,
|
||||
&sshdr);
|
||||
|
||||
US_DEBUGP("-- Result from auto-sense is %d\n", temp_result);
|
||||
US_DEBUGP("-- code: 0x%x, key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n",
|
||||
srb->sense_buffer[0],
|
||||
srb->sense_buffer[2] & 0xf,
|
||||
srb->sense_buffer[12],
|
||||
srb->sense_buffer[13]);
|
||||
sshdr.response_code, sshdr.sense_key,
|
||||
sshdr.asc, sshdr.ascq);
|
||||
#ifdef CONFIG_USB_STORAGE_DEBUG
|
||||
usb_stor_show_sense(
|
||||
srb->sense_buffer[2] & 0xf,
|
||||
srb->sense_buffer[12],
|
||||
srb->sense_buffer[13]);
|
||||
usb_stor_show_sense(sshdr.sense_key, sshdr.asc, sshdr.ascq);
|
||||
#endif
|
||||
|
||||
/* set the result so the higher layers expect this data */
|
||||
srb->result = SAM_STAT_CHECK_CONDITION;
|
||||
|
||||
scdd = scsi_sense_desc_find(srb->sense_buffer,
|
||||
SCSI_SENSE_BUFFERSIZE, 4);
|
||||
fm_ili = (scdd ? scdd[3] : srb->sense_buffer[2]) & 0xA0;
|
||||
|
||||
/* We often get empty sense data. This could indicate that
|
||||
* everything worked or that there was an unspecified
|
||||
* problem. We have to decide which.
|
||||
*/
|
||||
if ( /* Filemark 0, ignore EOM, ILI 0, no sense */
|
||||
(srb->sense_buffer[2] & 0xaf) == 0 &&
|
||||
/* No ASC or ASCQ */
|
||||
srb->sense_buffer[12] == 0 &&
|
||||
srb->sense_buffer[13] == 0) {
|
||||
|
||||
if (sshdr.sense_key == 0 && sshdr.asc == 0 && sshdr.ascq == 0 &&
|
||||
fm_ili == 0) {
|
||||
/* If things are really okay, then let's show that.
|
||||
* Zero out the sense buffer so the higher layers
|
||||
* won't realize we did an unsolicited auto-sense.
|
||||
@ -816,7 +817,10 @@ Retry_Sense:
|
||||
*/
|
||||
} else {
|
||||
srb->result = DID_ERROR << 16;
|
||||
srb->sense_buffer[2] = HARDWARE_ERROR;
|
||||
if ((sshdr.response_code & 0x72) == 0x72)
|
||||
srb->sense_buffer[1] = HARDWARE_ERROR;
|
||||
else
|
||||
srb->sense_buffer[2] = HARDWARE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1857,6 +1857,13 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110,
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_IGNORE_RESIDUE ),
|
||||
|
||||
/* Reported by Qinglin Ye <yestyle@gmail.com> */
|
||||
UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100,
|
||||
"Kingston",
|
||||
"DT 101 G2",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_BULK_IGNORE_TAG ),
|
||||
|
||||
/* Reported by Francesco Foresti <frafore@tiscali.it> */
|
||||
UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201,
|
||||
"Super Top",
|
||||
@ -1977,6 +1984,16 @@ UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100,
|
||||
"Micro Mini 1GB",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
|
||||
|
||||
/*
|
||||
* Nick Bowler <nbowler@elliptictech.com>
|
||||
* SCSI stack spams (otherwise harmless) error messages.
|
||||
*/
|
||||
UNUSUAL_DEV( 0xc251, 0x4003, 0x0100, 0x0100,
|
||||
"Keil Software, Inc.",
|
||||
"V2M MotherBoard",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_NOT_LOCKABLE),
|
||||
|
||||
/* Reported by Andrew Simmons <andrew.simmons@gmail.com> */
|
||||
UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001,
|
||||
"DataStor",
|
||||
|
@ -1025,6 +1025,7 @@ static struct usb_driver usb_storage_driver = {
|
||||
.post_reset = usb_stor_post_reset,
|
||||
.id_table = usb_storage_usb_ids,
|
||||
.soft_unbind = 1,
|
||||
.no_dynamic_id = 1,
|
||||
};
|
||||
|
||||
static int __init usb_stor_init(void)
|
||||
|
@ -46,7 +46,7 @@ struct ehci_caps {
|
||||
#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/
|
||||
#define HCC_64BIT_ADDR(p) ((p)&(1)) /* true: can use 64-bit addr */
|
||||
u8 portroute [8]; /* nibbles for routing - offset 0xC */
|
||||
} __attribute__ ((packed));
|
||||
};
|
||||
|
||||
|
||||
/* Section 2.3 Host Controller Operational Registers */
|
||||
@ -125,7 +125,7 @@ struct ehci_regs {
|
||||
#define PORT_CSC (1<<1) /* connect status change */
|
||||
#define PORT_CONNECT (1<<0) /* device connected */
|
||||
#define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
|
||||
} __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#define USBMODE 0x68 /* USB Device mode */
|
||||
#define USBMODE_SDIS (1<<3) /* Stream disable */
|
||||
@ -169,7 +169,7 @@ struct ehci_dbg_port {
|
||||
u32 data47;
|
||||
u32 address;
|
||||
#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep))
|
||||
} __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EARLY_PRINTK_DBGP
|
||||
#include <linux/init.h>
|
||||
|
@ -171,7 +171,8 @@ extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *);
|
||||
enum skb_state {
|
||||
illegal = 0,
|
||||
tx_start, tx_done,
|
||||
rx_start, rx_done, rx_cleanup
|
||||
rx_start, rx_done, rx_cleanup,
|
||||
unlink_start
|
||||
};
|
||||
|
||||
struct skb_data { /* skb->cb is one of these */
|
||||
|
Loading…
Reference in New Issue
Block a user