kernel: USB update from stlinux24_217

This commit is contained in:
Jaroslav Kysela 2015-08-03 18:18:03 +02:00
parent 07aa6b0e5a
commit c48033761a
48 changed files with 621 additions and 269 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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) {

View File

@ -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))

View File

@ -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;

View File

@ -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);

View File

@ -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 },

View File

@ -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))

View File

@ -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) {

View File

@ -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)) {

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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 */
};

View File

@ -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:

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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*/

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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[] = {

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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);
}

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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) },

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -925,6 +925,7 @@ static void sierra_release(struct usb_serial *serial)
continue;
kfree(portdata);
}
kfree(serial->private);
}
#ifdef CONFIG_PM

View File

@ -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:

View File

@ -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:

View File

@ -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);
}

View File

@ -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;
}
}
}

View File

@ -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",

View File

@ -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)

View File

@ -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>

View File

@ -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 */