mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-19 07:27:50 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (48 commits) USB: otg: fix module reinsert issue USB: handle zero-length usbfs submissions correctly USB: EHCI: report actual_length for iso transfers USB: option: remove unnecessary and erroneous code USB: cypress_m8: remove invalid Clear-Halt USB: musb_host: undo incorrect change in musb_advance_schedule() USB: fix LANGID=0 regression USB: serial: sierra driver id_table additions USB serial: Add ID for Turtelizer, an FT2232L-based JTAG/RS-232 adapter. USB: fix race leading to a write after kfree in usbfs USB: Sierra: fix oops upon device close USB: option.c: add A-Link 3GU device id USB: Serial: Add support for Arkham Technology adapters USB: Fix option_ms regression in 2.6.31-rc2 USB: gadget audio: select SND_PCM USB: ftdi: support NDI devices Revert USB: usbfs: deprecate and hide option for !embedded USB: usb.h: fix kernel-doc notation USB: RNDIS gadget, fix issues talking from PXA USB: serial: FTDI with product code FB80 and vendor id 0403 ...
This commit is contained in:
commit
51feb98d25
@ -387,6 +387,7 @@ static void acm_rx_tasklet(unsigned long _acm)
|
||||
struct acm_ru *rcv;
|
||||
unsigned long flags;
|
||||
unsigned char throttled;
|
||||
struct usb_host_endpoint *ep;
|
||||
|
||||
dbg("Entering acm_rx_tasklet");
|
||||
|
||||
@ -462,11 +463,20 @@ urbs:
|
||||
|
||||
rcv->buffer = buf;
|
||||
|
||||
usb_fill_bulk_urb(rcv->urb, acm->dev,
|
||||
acm->rx_endpoint,
|
||||
buf->base,
|
||||
acm->readsize,
|
||||
acm_read_bulk, rcv);
|
||||
ep = (usb_pipein(acm->rx_endpoint) ? acm->dev->ep_in : acm->dev->ep_out)
|
||||
[usb_pipeendpoint(acm->rx_endpoint)];
|
||||
if (usb_endpoint_xfer_int(&ep->desc))
|
||||
usb_fill_int_urb(rcv->urb, acm->dev,
|
||||
acm->rx_endpoint,
|
||||
buf->base,
|
||||
acm->readsize,
|
||||
acm_read_bulk, rcv, ep->desc.bInterval);
|
||||
else
|
||||
usb_fill_bulk_urb(rcv->urb, acm->dev,
|
||||
acm->rx_endpoint,
|
||||
buf->base,
|
||||
acm->readsize,
|
||||
acm_read_bulk, rcv);
|
||||
rcv->urb->transfer_dma = buf->dma;
|
||||
rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
|
||||
@ -1227,9 +1237,14 @@ made_compressed_probe:
|
||||
goto alloc_fail7;
|
||||
}
|
||||
|
||||
usb_fill_bulk_urb(snd->urb, usb_dev,
|
||||
usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
|
||||
NULL, acm->writesize, acm_write_bulk, snd);
|
||||
if (usb_endpoint_xfer_int(epwrite))
|
||||
usb_fill_int_urb(snd->urb, usb_dev,
|
||||
usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
|
||||
NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval);
|
||||
else
|
||||
usb_fill_bulk_urb(snd->urb, usb_dev,
|
||||
usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
|
||||
NULL, acm->writesize, acm_write_bulk, snd);
|
||||
snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
snd->instance = acm;
|
||||
}
|
||||
|
@ -751,7 +751,7 @@ static int get_capabilities(struct usbtmc_device_data *data)
|
||||
{
|
||||
struct device *dev = &data->usb_dev->dev;
|
||||
char *buffer;
|
||||
int rv;
|
||||
int rv = 0;
|
||||
|
||||
buffer = kmalloc(0x18, GFP_KERNEL);
|
||||
if (!buffer)
|
||||
@ -763,7 +763,7 @@ static int get_capabilities(struct usbtmc_device_data *data)
|
||||
0, 0, buffer, 0x18, USBTMC_TIMEOUT);
|
||||
if (rv < 0) {
|
||||
dev_err(dev, "usb_control_msg returned %d\n", rv);
|
||||
return rv;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
|
||||
@ -773,7 +773,8 @@ static int get_capabilities(struct usbtmc_device_data *data)
|
||||
dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]);
|
||||
if (buffer[0] != USBTMC_STATUS_SUCCESS) {
|
||||
dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
|
||||
return -EPERM;
|
||||
rv = -EPERM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
data->capabilities.interface_capabilities = buffer[4];
|
||||
@ -781,8 +782,9 @@ static int get_capabilities(struct usbtmc_device_data *data)
|
||||
data->capabilities.usb488_interface_capabilities = buffer[14];
|
||||
data->capabilities.usb488_device_capabilities = buffer[15];
|
||||
|
||||
err_out:
|
||||
kfree(buffer);
|
||||
return 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
#define capability_attribute(name) \
|
||||
|
@ -28,7 +28,7 @@ comment "Miscellaneous USB options"
|
||||
depends on USB
|
||||
|
||||
config USB_DEVICEFS
|
||||
bool "USB device filesystem (DEPRECATED)" if EMBEDDED
|
||||
bool "USB device filesystem (DEPRECATED)"
|
||||
depends on USB
|
||||
---help---
|
||||
If you say Y here (and to "/proc file system support" in the "File
|
||||
|
@ -136,17 +136,19 @@ static const struct class_info clas_info[] =
|
||||
{USB_CLASS_AUDIO, "audio"},
|
||||
{USB_CLASS_COMM, "comm."},
|
||||
{USB_CLASS_HID, "HID"},
|
||||
{USB_CLASS_HUB, "hub"},
|
||||
{USB_CLASS_PHYSICAL, "PID"},
|
||||
{USB_CLASS_STILL_IMAGE, "still"},
|
||||
{USB_CLASS_PRINTER, "print"},
|
||||
{USB_CLASS_MASS_STORAGE, "stor."},
|
||||
{USB_CLASS_HUB, "hub"},
|
||||
{USB_CLASS_CDC_DATA, "data"},
|
||||
{USB_CLASS_APP_SPEC, "app."},
|
||||
{USB_CLASS_VENDOR_SPEC, "vend."},
|
||||
{USB_CLASS_STILL_IMAGE, "still"},
|
||||
{USB_CLASS_CSCID, "scard"},
|
||||
{USB_CLASS_CONTENT_SEC, "c-sec"},
|
||||
{USB_CLASS_VIDEO, "video"},
|
||||
{USB_CLASS_WIRELESS_CONTROLLER, "wlcon"},
|
||||
{USB_CLASS_MISC, "misc"},
|
||||
{USB_CLASS_APP_SPEC, "app."},
|
||||
{USB_CLASS_VENDOR_SPEC, "vend."},
|
||||
{-1, "unk."} /* leave as last */
|
||||
};
|
||||
|
||||
|
@ -325,21 +325,34 @@ static void async_completed(struct urb *urb)
|
||||
struct async *as = urb->context;
|
||||
struct dev_state *ps = as->ps;
|
||||
struct siginfo sinfo;
|
||||
struct pid *pid = NULL;
|
||||
uid_t uid = 0;
|
||||
uid_t euid = 0;
|
||||
u32 secid = 0;
|
||||
int signr;
|
||||
|
||||
spin_lock(&ps->lock);
|
||||
list_move_tail(&as->asynclist, &ps->async_completed);
|
||||
spin_unlock(&ps->lock);
|
||||
as->status = urb->status;
|
||||
if (as->signr) {
|
||||
signr = as->signr;
|
||||
if (signr) {
|
||||
sinfo.si_signo = as->signr;
|
||||
sinfo.si_errno = as->status;
|
||||
sinfo.si_code = SI_ASYNCIO;
|
||||
sinfo.si_addr = as->userurb;
|
||||
kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid,
|
||||
as->euid, as->secid);
|
||||
pid = as->pid;
|
||||
uid = as->uid;
|
||||
euid = as->euid;
|
||||
secid = as->secid;
|
||||
}
|
||||
snoop(&urb->dev->dev, "urb complete\n");
|
||||
snoop_urb(urb, as->userurb);
|
||||
spin_unlock(&ps->lock);
|
||||
|
||||
if (signr)
|
||||
kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid,
|
||||
euid, secid);
|
||||
|
||||
wake_up(&ps->wait);
|
||||
}
|
||||
|
||||
@ -982,7 +995,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
||||
USBDEVFS_URB_ZERO_PACKET |
|
||||
USBDEVFS_URB_NO_INTERRUPT))
|
||||
return -EINVAL;
|
||||
if (!uurb->buffer)
|
||||
if (uurb->buffer_length > 0 && !uurb->buffer)
|
||||
return -EINVAL;
|
||||
if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL &&
|
||||
(uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) {
|
||||
@ -1038,11 +1051,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
||||
is_in = 0;
|
||||
uurb->endpoint &= ~USB_DIR_IN;
|
||||
}
|
||||
if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
|
||||
uurb->buffer, uurb->buffer_length)) {
|
||||
kfree(dr);
|
||||
return -EFAULT;
|
||||
}
|
||||
snoop(&ps->dev->dev, "control urb: bRequest=%02x "
|
||||
"bRrequestType=%02x wValue=%04x "
|
||||
"wIndex=%04x wLength=%04x\n",
|
||||
@ -1062,9 +1070,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
||||
uurb->number_of_packets = 0;
|
||||
if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
|
||||
return -EINVAL;
|
||||
if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
|
||||
uurb->buffer, uurb->buffer_length))
|
||||
return -EFAULT;
|
||||
snoop(&ps->dev->dev, "bulk urb\n");
|
||||
break;
|
||||
|
||||
@ -1106,27 +1111,34 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
||||
return -EINVAL;
|
||||
if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
|
||||
return -EINVAL;
|
||||
if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
|
||||
uurb->buffer, uurb->buffer_length))
|
||||
return -EFAULT;
|
||||
snoop(&ps->dev->dev, "interrupt urb\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
if (uurb->buffer_length > 0 &&
|
||||
!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
|
||||
uurb->buffer, uurb->buffer_length)) {
|
||||
kfree(isopkt);
|
||||
kfree(dr);
|
||||
return -EFAULT;
|
||||
}
|
||||
as = alloc_async(uurb->number_of_packets);
|
||||
if (!as) {
|
||||
kfree(isopkt);
|
||||
kfree(dr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL);
|
||||
if (!as->urb->transfer_buffer) {
|
||||
kfree(isopkt);
|
||||
kfree(dr);
|
||||
free_async(as);
|
||||
return -ENOMEM;
|
||||
if (uurb->buffer_length > 0) {
|
||||
as->urb->transfer_buffer = kmalloc(uurb->buffer_length,
|
||||
GFP_KERNEL);
|
||||
if (!as->urb->transfer_buffer) {
|
||||
kfree(isopkt);
|
||||
kfree(dr);
|
||||
free_async(as);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
as->urb->dev = ps->dev;
|
||||
as->urb->pipe = (uurb->type << 30) |
|
||||
@ -1169,7 +1181,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
||||
kfree(isopkt);
|
||||
as->ps = ps;
|
||||
as->userurb = arg;
|
||||
if (uurb->endpoint & USB_DIR_IN)
|
||||
if (is_in && uurb->buffer_length > 0)
|
||||
as->userbuffer = uurb->buffer;
|
||||
else
|
||||
as->userbuffer = NULL;
|
||||
@ -1179,9 +1191,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
||||
as->uid = cred->uid;
|
||||
as->euid = cred->euid;
|
||||
security_task_getsecid(current, &as->secid);
|
||||
if (!is_in) {
|
||||
if (!is_in && uurb->buffer_length > 0) {
|
||||
if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,
|
||||
as->urb->transfer_buffer_length)) {
|
||||
uurb->buffer_length)) {
|
||||
free_async(as);
|
||||
return -EFAULT;
|
||||
}
|
||||
@ -1231,22 +1243,22 @@ static int processcompl(struct async *as, void __user * __user *arg)
|
||||
if (as->userbuffer)
|
||||
if (copy_to_user(as->userbuffer, urb->transfer_buffer,
|
||||
urb->transfer_buffer_length))
|
||||
return -EFAULT;
|
||||
goto err_out;
|
||||
if (put_user(as->status, &userurb->status))
|
||||
return -EFAULT;
|
||||
goto err_out;
|
||||
if (put_user(urb->actual_length, &userurb->actual_length))
|
||||
return -EFAULT;
|
||||
goto err_out;
|
||||
if (put_user(urb->error_count, &userurb->error_count))
|
||||
return -EFAULT;
|
||||
goto err_out;
|
||||
|
||||
if (usb_endpoint_xfer_isoc(&urb->ep->desc)) {
|
||||
for (i = 0; i < urb->number_of_packets; i++) {
|
||||
if (put_user(urb->iso_frame_desc[i].actual_length,
|
||||
&userurb->iso_frame_desc[i].actual_length))
|
||||
return -EFAULT;
|
||||
goto err_out;
|
||||
if (put_user(urb->iso_frame_desc[i].status,
|
||||
&userurb->iso_frame_desc[i].status))
|
||||
return -EFAULT;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1255,6 +1267,10 @@ static int processcompl(struct async *as, void __user * __user *arg)
|
||||
if (put_user(addr, (void __user * __user *)arg))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
free_async(as);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static struct async *reap_as(struct dev_state *ps)
|
||||
|
@ -227,6 +227,10 @@ struct hc_driver {
|
||||
/* has a port been handed over to a companion? */
|
||||
int (*port_handed_over)(struct usb_hcd *, int);
|
||||
|
||||
/* CLEAR_TT_BUFFER completion callback */
|
||||
void (*clear_tt_buffer_complete)(struct usb_hcd *,
|
||||
struct usb_host_endpoint *);
|
||||
|
||||
/* xHCI specific functions */
|
||||
/* Called by usb_alloc_dev to alloc HC device structures */
|
||||
int (*alloc_dev)(struct usb_hcd *, struct usb_device *);
|
||||
|
@ -450,10 +450,10 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
|
||||
* talking to TTs must queue control transfers (not just bulk and iso), so
|
||||
* both can talk to the same hub concurrently.
|
||||
*/
|
||||
static void hub_tt_kevent (struct work_struct *work)
|
||||
static void hub_tt_work(struct work_struct *work)
|
||||
{
|
||||
struct usb_hub *hub =
|
||||
container_of(work, struct usb_hub, tt.kevent);
|
||||
container_of(work, struct usb_hub, tt.clear_work);
|
||||
unsigned long flags;
|
||||
int limit = 100;
|
||||
|
||||
@ -462,6 +462,7 @@ static void hub_tt_kevent (struct work_struct *work)
|
||||
struct list_head *next;
|
||||
struct usb_tt_clear *clear;
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
const struct hc_driver *drv;
|
||||
int status;
|
||||
|
||||
next = hub->tt.clear_list.next;
|
||||
@ -471,21 +472,25 @@ static void hub_tt_kevent (struct work_struct *work)
|
||||
/* drop lock so HCD can concurrently report other TT errors */
|
||||
spin_unlock_irqrestore (&hub->tt.lock, flags);
|
||||
status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt);
|
||||
spin_lock_irqsave (&hub->tt.lock, flags);
|
||||
|
||||
if (status)
|
||||
dev_err (&hdev->dev,
|
||||
"clear tt %d (%04x) error %d\n",
|
||||
clear->tt, clear->devinfo, status);
|
||||
|
||||
/* Tell the HCD, even if the operation failed */
|
||||
drv = clear->hcd->driver;
|
||||
if (drv->clear_tt_buffer_complete)
|
||||
(drv->clear_tt_buffer_complete)(clear->hcd, clear->ep);
|
||||
|
||||
kfree(clear);
|
||||
spin_lock_irqsave(&hub->tt.lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore (&hub->tt.lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_hub_tt_clear_buffer - clear control/bulk TT state in high speed hub
|
||||
* @udev: the device whose split transaction failed
|
||||
* @pipe: identifies the endpoint of the failed transaction
|
||||
* 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
|
||||
*
|
||||
* High speed HCDs use this to tell the hub driver that some split control or
|
||||
* bulk transaction failed in a way that requires clearing internal state of
|
||||
@ -495,8 +500,10 @@ static void hub_tt_kevent (struct work_struct *work)
|
||||
* It may not be possible for that hub to handle additional full (or low)
|
||||
* speed transactions until that state is fully cleared out.
|
||||
*/
|
||||
void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
|
||||
int usb_hub_clear_tt_buffer(struct urb *urb)
|
||||
{
|
||||
struct usb_device *udev = urb->dev;
|
||||
int pipe = urb->pipe;
|
||||
struct usb_tt *tt = udev->tt;
|
||||
unsigned long flags;
|
||||
struct usb_tt_clear *clear;
|
||||
@ -508,7 +515,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
|
||||
if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) {
|
||||
dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
|
||||
/* FIXME recover somehow ... RESET_TT? */
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* info that CLEAR_TT_BUFFER needs */
|
||||
@ -520,14 +527,19 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
|
||||
: (USB_ENDPOINT_XFER_BULK << 11);
|
||||
if (usb_pipein (pipe))
|
||||
clear->devinfo |= 1 << 15;
|
||||
|
||||
|
||||
/* info for completion callback */
|
||||
clear->hcd = bus_to_hcd(udev->bus);
|
||||
clear->ep = urb->ep;
|
||||
|
||||
/* 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->kevent);
|
||||
schedule_work(&tt->clear_work);
|
||||
spin_unlock_irqrestore (&tt->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer);
|
||||
EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer);
|
||||
|
||||
/* If do_delay is false, return the number of milliseconds the caller
|
||||
* needs to delay.
|
||||
@ -818,7 +830,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
|
||||
if (hub->has_indicators)
|
||||
cancel_delayed_work_sync(&hub->leds);
|
||||
if (hub->tt.hub)
|
||||
cancel_work_sync(&hub->tt.kevent);
|
||||
cancel_work_sync(&hub->tt.clear_work);
|
||||
}
|
||||
|
||||
/* caller has locked the hub device */
|
||||
@ -935,7 +947,7 @@ static int hub_configure(struct usb_hub *hub,
|
||||
|
||||
spin_lock_init (&hub->tt.lock);
|
||||
INIT_LIST_HEAD (&hub->tt.clear_list);
|
||||
INIT_WORK (&hub->tt.kevent, hub_tt_kevent);
|
||||
INIT_WORK(&hub->tt.clear_work, hub_tt_work);
|
||||
switch (hdev->descriptor.bDeviceProtocol) {
|
||||
case 0:
|
||||
break;
|
||||
|
@ -188,16 +188,18 @@ struct usb_tt {
|
||||
/* for control/bulk error recovery (CLEAR_TT_BUFFER) */
|
||||
spinlock_t lock;
|
||||
struct list_head clear_list; /* of usb_tt_clear */
|
||||
struct work_struct kevent;
|
||||
struct work_struct clear_work;
|
||||
};
|
||||
|
||||
struct usb_tt_clear {
|
||||
struct list_head clear_list;
|
||||
unsigned tt;
|
||||
u16 devinfo;
|
||||
struct usb_hcd *hcd;
|
||||
struct usb_host_endpoint *ep;
|
||||
};
|
||||
|
||||
extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe);
|
||||
extern int usb_hub_clear_tt_buffer(struct urb *urb);
|
||||
extern void usb_ep0_reinit(struct usb_device *);
|
||||
|
||||
#endif /* __LINUX_HUB_H */
|
||||
|
@ -806,6 +806,48 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (dev->have_langid)
|
||||
return 0;
|
||||
|
||||
if (dev->string_langid < 0)
|
||||
return -EPIPE;
|
||||
|
||||
err = usb_string_sub(dev, 0, 0, tbuf);
|
||||
|
||||
/* If the string was reported but is malformed, default to english
|
||||
* (0x0409) */
|
||||
if (err == -ENODATA || (err > 0 && err < 4)) {
|
||||
dev->string_langid = 0x0409;
|
||||
dev->have_langid = 1;
|
||||
dev_err(&dev->dev,
|
||||
"string descriptor 0 malformed (err = %d), "
|
||||
"defaulting to 0x%04x\n",
|
||||
err, dev->string_langid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* In case of all other errors, we assume the device is not able to
|
||||
* deal with strings at all. Set string_langid to -1 in order to
|
||||
* prevent any string to be retrieved from the device */
|
||||
if (err < 0) {
|
||||
dev_err(&dev->dev, "string descriptor 0 read error: %d\n",
|
||||
err);
|
||||
dev->string_langid = -1;
|
||||
return -EPIPE;
|
||||
}
|
||||
|
||||
/* always use the first langid listed */
|
||||
dev->string_langid = tbuf[2] | (tbuf[3] << 8);
|
||||
dev->have_langid = 1;
|
||||
dev_dbg(&dev->dev, "default language 0x%04x\n",
|
||||
dev->string_langid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_string - returns UTF-8 version of a string descriptor
|
||||
* @dev: the device whose string descriptor is being retrieved
|
||||
@ -837,24 +879,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
|
||||
if (!tbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* get langid for strings if it's not yet known */
|
||||
if (!dev->have_langid) {
|
||||
err = usb_string_sub(dev, 0, 0, tbuf);
|
||||
if (err < 0) {
|
||||
dev_err(&dev->dev,
|
||||
"string descriptor 0 read error: %d\n",
|
||||
err);
|
||||
} else if (err < 4) {
|
||||
dev_err(&dev->dev, "string descriptor 0 too short\n");
|
||||
} else {
|
||||
dev->string_langid = tbuf[2] | (tbuf[3] << 8);
|
||||
/* always use the first langid listed */
|
||||
dev_dbg(&dev->dev, "default language 0x%04x\n",
|
||||
dev->string_langid);
|
||||
}
|
||||
|
||||
dev->have_langid = 1;
|
||||
}
|
||||
err = usb_get_langid(dev, tbuf);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
err = usb_string_sub(dev, dev->string_langid, index, tbuf);
|
||||
if (err < 0)
|
||||
|
@ -286,6 +286,27 @@ config USB_S3C_HSOTG
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_GADGET_IMX
|
||||
boolean "Freescale IMX USB Peripheral Controller"
|
||||
depends on ARCH_MX1
|
||||
help
|
||||
Freescale's IMX series include an integrated full speed
|
||||
USB 1.1 device controller. The controller in the IMX series
|
||||
is register-compatible.
|
||||
|
||||
It has Six fixed-function endpoints, as well as endpoint
|
||||
zero (for control transfers).
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "imx_udc" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_IMX
|
||||
tristate
|
||||
depends on USB_GADGET_IMX
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_GADGET_S3C2410
|
||||
boolean "S3C2410 USB Device Controller"
|
||||
depends on ARCH_S3C2410
|
||||
@ -321,27 +342,6 @@ config USB_GADGET_MUSB_HDRC
|
||||
This OTG-capable silicon IP is used in dual designs including
|
||||
the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin
|
||||
|
||||
config USB_GADGET_IMX
|
||||
boolean "Freescale IMX USB Peripheral Controller"
|
||||
depends on ARCH_MX1
|
||||
help
|
||||
Freescale's IMX series include an integrated full speed
|
||||
USB 1.1 device controller. The controller in the IMX series
|
||||
is register-compatible.
|
||||
|
||||
It has Six fixed-function endpoints, as well as endpoint
|
||||
zero (for control transfers).
|
||||
|
||||
Say "y" to link the driver statically, or "m" to build a
|
||||
dynamically linked module called "imx_udc" and force all
|
||||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_IMX
|
||||
tristate
|
||||
depends on USB_GADGET_IMX
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
config USB_GADGET_M66592
|
||||
boolean "Renesas M66592 USB Peripheral Controller"
|
||||
select USB_GADGET_DUALSPEED
|
||||
@ -604,6 +604,7 @@ config USB_ZERO_HNPTEST
|
||||
config USB_AUDIO
|
||||
tristate "Audio Gadget (EXPERIMENTAL)"
|
||||
depends on SND
|
||||
select SND_PCM
|
||||
help
|
||||
Gadget Audio is compatible with USB Audio Class specification 1.0.
|
||||
It will include at least one AudioControl interface, zero or more
|
||||
|
@ -42,9 +42,9 @@
|
||||
* Instead: allocate your own, using normal USB-IF procedures.
|
||||
*/
|
||||
|
||||
/* Thanks to NetChip Technologies for donating this product ID. */
|
||||
#define AUDIO_VENDOR_NUM 0x0525 /* NetChip */
|
||||
#define AUDIO_PRODUCT_NUM 0xa4a1 /* Linux-USB Audio Gadget */
|
||||
/* Thanks to Linux Foundation for donating this product ID. */
|
||||
#define AUDIO_VENDOR_NUM 0x1d6b /* Linux Foundation */
|
||||
#define AUDIO_PRODUCT_NUM 0x0101 /* Linux-USB Audio Gadget */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -293,15 +293,16 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
|
||||
/* CDC Subset */
|
||||
eth_config_driver.label = "CDC Subset/SAFE";
|
||||
|
||||
device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM),
|
||||
device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM),
|
||||
device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
|
||||
device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM);
|
||||
device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM);
|
||||
if (!has_rndis())
|
||||
device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
|
||||
}
|
||||
|
||||
if (has_rndis()) {
|
||||
/* RNDIS plus ECM-or-Subset */
|
||||
device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM),
|
||||
device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM),
|
||||
device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM);
|
||||
device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM);
|
||||
device_desc.bNumConfigurations = 2;
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ static int is_vbus_present(void)
|
||||
{
|
||||
struct pxa2xx_udc_mach_info *mach = the_controller->mach;
|
||||
|
||||
if (mach->gpio_vbus) {
|
||||
if (gpio_is_valid(mach->gpio_vbus)) {
|
||||
int value = gpio_get_value(mach->gpio_vbus);
|
||||
|
||||
if (mach->gpio_vbus_inverted)
|
||||
@ -158,7 +158,7 @@ static void pullup_off(void)
|
||||
struct pxa2xx_udc_mach_info *mach = the_controller->mach;
|
||||
int off_level = mach->gpio_pullup_inverted;
|
||||
|
||||
if (mach->gpio_pullup)
|
||||
if (gpio_is_valid(mach->gpio_pullup))
|
||||
gpio_set_value(mach->gpio_pullup, off_level);
|
||||
else if (mach->udc_command)
|
||||
mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
|
||||
@ -169,7 +169,7 @@ static void pullup_on(void)
|
||||
struct pxa2xx_udc_mach_info *mach = the_controller->mach;
|
||||
int on_level = !mach->gpio_pullup_inverted;
|
||||
|
||||
if (mach->gpio_pullup)
|
||||
if (gpio_is_valid(mach->gpio_pullup))
|
||||
gpio_set_value(mach->gpio_pullup, on_level);
|
||||
else if (mach->udc_command)
|
||||
mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
|
||||
@ -1000,7 +1000,7 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active)
|
||||
udc = container_of(_gadget, struct pxa25x_udc, gadget);
|
||||
|
||||
/* not all boards support pullup control */
|
||||
if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
|
||||
if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
udc->pullup = (is_active != 0);
|
||||
@ -1802,11 +1802,13 @@ pxa25x_udc_irq(int irq, void *_dev)
|
||||
USIR0 |= tmp;
|
||||
handled = 1;
|
||||
}
|
||||
#ifndef CONFIG_USB_PXA25X_SMALL
|
||||
if (usir1 & tmp) {
|
||||
handle_ep(&dev->ep[i+8]);
|
||||
USIR1 |= tmp;
|
||||
handled = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -2160,7 +2162,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
|
||||
dev->dev = &pdev->dev;
|
||||
dev->mach = pdev->dev.platform_data;
|
||||
|
||||
if (dev->mach->gpio_vbus) {
|
||||
if (gpio_is_valid(dev->mach->gpio_vbus)) {
|
||||
if ((retval = gpio_request(dev->mach->gpio_vbus,
|
||||
"pxa25x_udc GPIO VBUS"))) {
|
||||
dev_dbg(&pdev->dev,
|
||||
@ -2173,7 +2175,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
|
||||
} else
|
||||
vbus_irq = 0;
|
||||
|
||||
if (dev->mach->gpio_pullup) {
|
||||
if (gpio_is_valid(dev->mach->gpio_pullup)) {
|
||||
if ((retval = gpio_request(dev->mach->gpio_pullup,
|
||||
"pca25x_udc GPIO PULLUP"))) {
|
||||
dev_dbg(&pdev->dev,
|
||||
@ -2256,10 +2258,10 @@ lubbock_fail0:
|
||||
#endif
|
||||
free_irq(irq, dev);
|
||||
err_irq1:
|
||||
if (dev->mach->gpio_pullup)
|
||||
if (gpio_is_valid(dev->mach->gpio_pullup))
|
||||
gpio_free(dev->mach->gpio_pullup);
|
||||
err_gpio_pullup:
|
||||
if (dev->mach->gpio_vbus)
|
||||
if (gpio_is_valid(dev->mach->gpio_vbus))
|
||||
gpio_free(dev->mach->gpio_vbus);
|
||||
err_gpio_vbus:
|
||||
clk_put(dev->clk);
|
||||
@ -2294,11 +2296,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
|
||||
free_irq(LUBBOCK_USB_IRQ, dev);
|
||||
}
|
||||
#endif
|
||||
if (dev->mach->gpio_vbus) {
|
||||
if (gpio_is_valid(dev->mach->gpio_vbus)) {
|
||||
free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev);
|
||||
gpio_free(dev->mach->gpio_vbus);
|
||||
}
|
||||
if (dev->mach->gpio_pullup)
|
||||
if (gpio_is_valid(dev->mach->gpio_pullup))
|
||||
gpio_free(dev->mach->gpio_pullup);
|
||||
|
||||
clk_put(dev->clk);
|
||||
@ -2329,7 +2331,7 @@ static int pxa25x_udc_suspend(struct platform_device *dev, pm_message_t state)
|
||||
struct pxa25x_udc *udc = platform_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
|
||||
if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
|
||||
if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
|
||||
WARNING("USB host won't detect disconnect!\n");
|
||||
udc->suspended = 1;
|
||||
|
||||
|
@ -442,6 +442,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
|
||||
case OID_802_3_MAC_OPTIONS:
|
||||
pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__);
|
||||
*outbuf = cpu_to_le32(0);
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
/* ieee802.3 statistics OIDs (table 4-4) */
|
||||
|
@ -181,26 +181,27 @@ config USB_OHCI_HCD_PPC_SOC
|
||||
Enables support for the USB controller on the MPC52xx or
|
||||
STB03xxx processor chip. If unsure, say Y.
|
||||
|
||||
config USB_OHCI_HCD_PPC_OF
|
||||
bool "OHCI support for PPC USB controller on OF platform bus"
|
||||
depends on USB_OHCI_HCD && PPC_OF
|
||||
default y
|
||||
---help---
|
||||
Enables support for the USB controller PowerPC present on the
|
||||
OpenFirmware platform bus.
|
||||
|
||||
config USB_OHCI_HCD_PPC_OF_BE
|
||||
bool "Support big endian HC"
|
||||
depends on USB_OHCI_HCD_PPC_OF
|
||||
default y
|
||||
bool "OHCI support for OF platform bus (big endian)"
|
||||
depends on USB_OHCI_HCD && PPC_OF
|
||||
select USB_OHCI_BIG_ENDIAN_DESC
|
||||
select USB_OHCI_BIG_ENDIAN_MMIO
|
||||
---help---
|
||||
Enables support for big-endian USB controllers present on the
|
||||
OpenFirmware platform bus.
|
||||
|
||||
config USB_OHCI_HCD_PPC_OF_LE
|
||||
bool "Support little endian HC"
|
||||
depends on USB_OHCI_HCD_PPC_OF
|
||||
default n
|
||||
bool "OHCI support for OF platform bus (little endian)"
|
||||
depends on USB_OHCI_HCD && PPC_OF
|
||||
select USB_OHCI_LITTLE_ENDIAN
|
||||
---help---
|
||||
Enables support for little-endian USB controllers present on the
|
||||
OpenFirmware platform bus.
|
||||
|
||||
config USB_OHCI_HCD_PPC_OF
|
||||
bool
|
||||
depends on USB_OHCI_HCD && PPC_OF
|
||||
default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE
|
||||
|
||||
config USB_OHCI_HCD_PCI
|
||||
bool "OHCI support for PCI-bus USB controllers"
|
||||
|
@ -113,6 +113,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
|
||||
.bus_resume = ehci_bus_resume,
|
||||
.relinquish_port = ehci_relinquish_port,
|
||||
.port_handed_over = ehci_port_handed_over,
|
||||
|
||||
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
|
||||
};
|
||||
|
||||
static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
|
||||
|
@ -325,6 +325,8 @@ static const struct hc_driver ehci_fsl_hc_driver = {
|
||||
.bus_resume = ehci_bus_resume,
|
||||
.relinquish_port = ehci_relinquish_port,
|
||||
.port_handed_over = ehci_port_handed_over,
|
||||
|
||||
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
|
||||
};
|
||||
|
||||
static int ehci_fsl_drv_probe(struct platform_device *pdev)
|
||||
|
@ -1003,6 +1003,8 @@ idle_timeout:
|
||||
schedule_timeout_uninterruptible(1);
|
||||
goto rescan;
|
||||
case QH_STATE_IDLE: /* fully unlinked */
|
||||
if (qh->clearing_tt)
|
||||
goto idle_timeout;
|
||||
if (list_empty (&qh->qtd_list)) {
|
||||
qh_put (qh);
|
||||
break;
|
||||
@ -1030,12 +1032,14 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
|
||||
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
||||
struct ehci_qh *qh;
|
||||
int eptype = usb_endpoint_type(&ep->desc);
|
||||
int epnum = usb_endpoint_num(&ep->desc);
|
||||
int is_out = usb_endpoint_dir_out(&ep->desc);
|
||||
unsigned long flags;
|
||||
|
||||
if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
|
||||
return;
|
||||
|
||||
rescan:
|
||||
spin_lock_irq(&ehci->lock);
|
||||
spin_lock_irqsave(&ehci->lock, flags);
|
||||
qh = ep->hcpriv;
|
||||
|
||||
/* For Bulk and Interrupt endpoints we maintain the toggle state
|
||||
@ -1044,29 +1048,24 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
|
||||
* the toggle bit in the QH.
|
||||
*/
|
||||
if (qh) {
|
||||
usb_settoggle(qh->dev, epnum, is_out, 0);
|
||||
if (!list_empty(&qh->qtd_list)) {
|
||||
WARN_ONCE(1, "clear_halt for a busy endpoint\n");
|
||||
} else if (qh->qh_state == QH_STATE_IDLE) {
|
||||
qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
|
||||
} else {
|
||||
/* It's not safe to write into the overlay area
|
||||
* while the QH is active. Unlink it first and
|
||||
* wait for the unlink to complete.
|
||||
} else if (qh->qh_state == QH_STATE_LINKED) {
|
||||
|
||||
/* The toggle value in the QH can't be updated
|
||||
* while the QH is active. Unlink it now;
|
||||
* re-linking will call qh_refresh().
|
||||
*/
|
||||
if (qh->qh_state == QH_STATE_LINKED) {
|
||||
if (eptype == USB_ENDPOINT_XFER_BULK) {
|
||||
unlink_async(ehci, qh);
|
||||
} else {
|
||||
intr_deschedule(ehci, qh);
|
||||
(void) qh_schedule(ehci, qh);
|
||||
}
|
||||
if (eptype == USB_ENDPOINT_XFER_BULK) {
|
||||
unlink_async(ehci, qh);
|
||||
} else {
|
||||
intr_deschedule(ehci, qh);
|
||||
(void) qh_schedule(ehci, qh);
|
||||
}
|
||||
spin_unlock_irq(&ehci->lock);
|
||||
schedule_timeout_uninterruptible(1);
|
||||
goto rescan;
|
||||
}
|
||||
}
|
||||
spin_unlock_irq(&ehci->lock);
|
||||
spin_unlock_irqrestore(&ehci->lock, flags);
|
||||
}
|
||||
|
||||
static int ehci_get_frame (struct usb_hcd *hcd)
|
||||
|
@ -61,6 +61,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = {
|
||||
#endif
|
||||
.relinquish_port = ehci_relinquish_port,
|
||||
.port_handed_over = ehci_port_handed_over,
|
||||
|
||||
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
|
||||
};
|
||||
|
||||
static int ixp4xx_ehci_probe(struct platform_device *pdev)
|
||||
|
@ -165,6 +165,8 @@ static const struct hc_driver ehci_orion_hc_driver = {
|
||||
.bus_resume = ehci_bus_resume,
|
||||
.relinquish_port = ehci_relinquish_port,
|
||||
.port_handed_over = ehci_port_handed_over,
|
||||
|
||||
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
|
||||
};
|
||||
|
||||
static void __init
|
||||
|
@ -404,6 +404,8 @@ static const struct hc_driver ehci_pci_hc_driver = {
|
||||
.bus_resume = ehci_bus_resume,
|
||||
.relinquish_port = ehci_relinquish_port,
|
||||
.port_handed_over = ehci_port_handed_over,
|
||||
|
||||
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -79,6 +79,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
|
||||
#endif
|
||||
.relinquish_port = ehci_relinquish_port,
|
||||
.port_handed_over = ehci_port_handed_over,
|
||||
|
||||
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
|
||||
};
|
||||
|
||||
|
||||
|
@ -75,6 +75,8 @@ static const struct hc_driver ps3_ehci_hc_driver = {
|
||||
#endif
|
||||
.relinquish_port = ehci_relinquish_port,
|
||||
.port_handed_over = ehci_port_handed_over,
|
||||
|
||||
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
|
||||
};
|
||||
|
||||
static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev)
|
||||
|
@ -93,6 +93,22 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
|
||||
qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
|
||||
qh->hw_alt_next = EHCI_LIST_END(ehci);
|
||||
|
||||
/* Except for control endpoints, we make hardware maintain data
|
||||
* toggle (like OHCI) ... here (re)initialize the toggle in the QH,
|
||||
* and set the pseudo-toggle in udev. Only usb_clear_halt() will
|
||||
* ever clear it.
|
||||
*/
|
||||
if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
|
||||
unsigned is_out, epnum;
|
||||
|
||||
is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
|
||||
epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f;
|
||||
if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
|
||||
qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
|
||||
usb_settoggle (qh->dev, epnum, is_out, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
|
||||
wmb ();
|
||||
qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING);
|
||||
@ -123,6 +139,55 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static void qh_link_async(struct ehci_hcd *ehci, struct ehci_qh *qh);
|
||||
|
||||
static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd,
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
||||
struct ehci_qh *qh = ep->hcpriv;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ehci->lock, flags);
|
||||
qh->clearing_tt = 0;
|
||||
if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
|
||||
&& HC_IS_RUNNING(hcd->state))
|
||||
qh_link_async(ehci, qh);
|
||||
spin_unlock_irqrestore(&ehci->lock, flags);
|
||||
}
|
||||
|
||||
static void ehci_clear_tt_buffer(struct ehci_hcd *ehci, struct ehci_qh *qh,
|
||||
struct urb *urb, u32 token)
|
||||
{
|
||||
|
||||
/* If an async split transaction gets an error or is unlinked,
|
||||
* the TT buffer may be left in an indeterminate state. We
|
||||
* have to clear the TT buffer.
|
||||
*
|
||||
* Note: this routine is never called for Isochronous transfers.
|
||||
*/
|
||||
if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
|
||||
#ifdef DEBUG
|
||||
struct usb_device *tt = urb->dev->tt->hub;
|
||||
dev_dbg(&tt->dev,
|
||||
"clear tt buffer port %d, a%d ep%d t%08x\n",
|
||||
urb->dev->ttport, urb->dev->devnum,
|
||||
usb_pipeendpoint(urb->pipe), token);
|
||||
#endif /* DEBUG */
|
||||
if (!ehci_is_TDI(ehci)
|
||||
|| urb->dev->tt->hub !=
|
||||
ehci_to_hcd(ehci)->self.root_hub) {
|
||||
if (usb_hub_clear_tt_buffer(urb) == 0)
|
||||
qh->clearing_tt = 1;
|
||||
} else {
|
||||
|
||||
/* REVISIT ARC-derived cores don't clear the root
|
||||
* hub TT buffer in this way...
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int qtd_copy_status (
|
||||
struct ehci_hcd *ehci,
|
||||
struct urb *urb,
|
||||
@ -149,6 +214,14 @@ static int qtd_copy_status (
|
||||
if (token & QTD_STS_BABBLE) {
|
||||
/* FIXME "must" disable babbling device's port too */
|
||||
status = -EOVERFLOW;
|
||||
/* CERR nonzero + halt --> stall */
|
||||
} else if (QTD_CERR(token)) {
|
||||
status = -EPIPE;
|
||||
|
||||
/* In theory, more than one of the following bits can be set
|
||||
* since they are sticky and the transaction is retried.
|
||||
* Which to test first is rather arbitrary.
|
||||
*/
|
||||
} else if (token & QTD_STS_MMF) {
|
||||
/* fs/ls interrupt xfer missed the complete-split */
|
||||
status = -EPROTO;
|
||||
@ -157,21 +230,15 @@ static int qtd_copy_status (
|
||||
? -ENOSR /* hc couldn't read data */
|
||||
: -ECOMM; /* hc couldn't write data */
|
||||
} else if (token & QTD_STS_XACT) {
|
||||
/* timeout, bad crc, wrong PID, etc; retried */
|
||||
if (QTD_CERR (token))
|
||||
status = -EPIPE;
|
||||
else {
|
||||
ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n",
|
||||
urb->dev->devpath,
|
||||
usb_pipeendpoint (urb->pipe),
|
||||
usb_pipein (urb->pipe) ? "in" : "out");
|
||||
status = -EPROTO;
|
||||
}
|
||||
/* CERR nonzero + no errors + halt --> stall */
|
||||
} else if (QTD_CERR (token))
|
||||
status = -EPIPE;
|
||||
else /* unknown */
|
||||
/* timeout, bad CRC, wrong PID, etc */
|
||||
ehci_dbg(ehci, "devpath %s ep%d%s 3strikes\n",
|
||||
urb->dev->devpath,
|
||||
usb_pipeendpoint(urb->pipe),
|
||||
usb_pipein(urb->pipe) ? "in" : "out");
|
||||
status = -EPROTO;
|
||||
} else { /* unknown */
|
||||
status = -EPROTO;
|
||||
}
|
||||
|
||||
ehci_vdbg (ehci,
|
||||
"dev%d ep%d%s qtd token %08x --> status %d\n",
|
||||
@ -179,28 +246,6 @@ static int qtd_copy_status (
|
||||
usb_pipeendpoint (urb->pipe),
|
||||
usb_pipein (urb->pipe) ? "in" : "out",
|
||||
token, status);
|
||||
|
||||
/* if async CSPLIT failed, try cleaning out the TT buffer */
|
||||
if (status != -EPIPE
|
||||
&& urb->dev->tt
|
||||
&& !usb_pipeint(urb->pipe)
|
||||
&& ((token & QTD_STS_MMF) != 0
|
||||
|| QTD_CERR(token) == 0)
|
||||
&& (!ehci_is_TDI(ehci)
|
||||
|| urb->dev->tt->hub !=
|
||||
ehci_to_hcd(ehci)->self.root_hub)) {
|
||||
#ifdef DEBUG
|
||||
struct usb_device *tt = urb->dev->tt->hub;
|
||||
dev_dbg (&tt->dev,
|
||||
"clear tt buffer port %d, a%d ep%d t%08x\n",
|
||||
urb->dev->ttport, urb->dev->devnum,
|
||||
usb_pipeendpoint (urb->pipe), token);
|
||||
#endif /* DEBUG */
|
||||
/* REVISIT ARC-derived cores don't clear the root
|
||||
* hub TT buffer in this way...
|
||||
*/
|
||||
usb_hub_tt_clear_buffer (urb->dev, urb->pipe);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -391,9 +436,16 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
||||
/* qh unlinked; token in overlay may be most current */
|
||||
if (state == QH_STATE_IDLE
|
||||
&& cpu_to_hc32(ehci, qtd->qtd_dma)
|
||||
== qh->hw_current)
|
||||
== qh->hw_current) {
|
||||
token = hc32_to_cpu(ehci, qh->hw_token);
|
||||
|
||||
/* An unlink may leave an incomplete
|
||||
* async transaction in the TT buffer.
|
||||
* We have to clear it.
|
||||
*/
|
||||
ehci_clear_tt_buffer(ehci, qh, urb, token);
|
||||
}
|
||||
|
||||
/* force halt for unlinked or blocked qh, so we'll
|
||||
* patch the qh later and so that completions can't
|
||||
* activate it while we "know" it's stopped.
|
||||
@ -419,6 +471,13 @@ halt:
|
||||
&& (qtd->hw_alt_next
|
||||
& EHCI_LIST_END(ehci)))
|
||||
last_status = -EINPROGRESS;
|
||||
|
||||
/* As part of low/full-speed endpoint-halt processing
|
||||
* we must clear the TT buffer (11.17.5).
|
||||
*/
|
||||
if (unlikely(last_status != -EINPROGRESS &&
|
||||
last_status != -EREMOTEIO))
|
||||
ehci_clear_tt_buffer(ehci, qh, urb, token);
|
||||
}
|
||||
|
||||
/* if we're removing something not at the queue head,
|
||||
@ -834,6 +893,7 @@ done:
|
||||
qh->qh_state = QH_STATE_IDLE;
|
||||
qh->hw_info1 = cpu_to_hc32(ehci, info1);
|
||||
qh->hw_info2 = cpu_to_hc32(ehci, info2);
|
||||
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
|
||||
qh_refresh (ehci, qh);
|
||||
return qh;
|
||||
}
|
||||
@ -847,6 +907,10 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
||||
__hc32 dma = QH_NEXT(ehci, qh->qh_dma);
|
||||
struct ehci_qh *head;
|
||||
|
||||
/* Don't link a QH if there's a Clear-TT-Buffer pending */
|
||||
if (unlikely(qh->clearing_tt))
|
||||
return;
|
||||
|
||||
/* (re)start the async schedule? */
|
||||
head = ehci->async;
|
||||
timer_action_done (ehci, TIMER_ASYNC_OFF);
|
||||
@ -864,7 +928,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
||||
}
|
||||
}
|
||||
|
||||
/* clear halt and maybe recover from silicon quirk */
|
||||
/* clear halt and/or toggle; and maybe recover from silicon quirk */
|
||||
if (qh->qh_state == QH_STATE_IDLE)
|
||||
qh_refresh (ehci, qh);
|
||||
|
||||
|
@ -1619,11 +1619,14 @@ itd_complete (
|
||||
desc->status = -EPROTO;
|
||||
|
||||
/* HC need not update length with this error */
|
||||
if (!(t & EHCI_ISOC_BABBLE))
|
||||
desc->actual_length = EHCI_ITD_LENGTH (t);
|
||||
if (!(t & EHCI_ISOC_BABBLE)) {
|
||||
desc->actual_length = EHCI_ITD_LENGTH(t);
|
||||
urb->actual_length += desc->actual_length;
|
||||
}
|
||||
} else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
|
||||
desc->status = 0;
|
||||
desc->actual_length = EHCI_ITD_LENGTH (t);
|
||||
desc->actual_length = EHCI_ITD_LENGTH(t);
|
||||
urb->actual_length += desc->actual_length;
|
||||
} else {
|
||||
/* URB was too late */
|
||||
desc->status = -EXDEV;
|
||||
@ -2014,7 +2017,8 @@ sitd_complete (
|
||||
desc->status = -EPROTO;
|
||||
} else {
|
||||
desc->status = 0;
|
||||
desc->actual_length = desc->length - SITD_LENGTH (t);
|
||||
desc->actual_length = desc->length - SITD_LENGTH(t);
|
||||
urb->actual_length += desc->actual_length;
|
||||
}
|
||||
stream->depth -= stream->interval << 3;
|
||||
|
||||
|
@ -354,7 +354,9 @@ struct ehci_qh {
|
||||
unsigned short period; /* polling interval */
|
||||
unsigned short start; /* where polling starts */
|
||||
#define NO_FRAME ((unsigned short)~0) /* pick new start */
|
||||
|
||||
struct usb_device *dev; /* access to TT */
|
||||
unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
|
||||
} __attribute__ ((aligned (32)));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -576,9 +576,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
|
||||
out_be16(&usb->fhci->regs->usb_event,
|
||||
usb->saved_msk);
|
||||
} else if (usb->port_status == FHCI_PORT_DISABLED) {
|
||||
if (fhci_ioports_check_bus_state(fhci) == 1 &&
|
||||
usb->port_status != FHCI_PORT_LOW &&
|
||||
usb->port_status != FHCI_PORT_FULL)
|
||||
if (fhci_ioports_check_bus_state(fhci) == 1)
|
||||
fhci_device_connected_interrupt(fhci);
|
||||
}
|
||||
usb_er &= ~USB_E_RESET_MASK;
|
||||
@ -605,9 +603,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
|
||||
}
|
||||
|
||||
if (usb_er & USB_E_IDLE_MASK) {
|
||||
if (usb->port_status == FHCI_PORT_DISABLED &&
|
||||
usb->port_status != FHCI_PORT_LOW &&
|
||||
usb->port_status != FHCI_PORT_FULL) {
|
||||
if (usb->port_status == FHCI_PORT_DISABLED) {
|
||||
usb_er &= ~USB_E_RESET_MASK;
|
||||
fhci_device_connected_interrupt(fhci);
|
||||
} else if (usb->port_status ==
|
||||
|
@ -361,7 +361,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver isp1760_plat_driver = {
|
||||
.probe = isp1760_plat_probe,
|
||||
.remove = isp1760_plat_remove,
|
||||
.remove = __devexit_p(isp1760_plat_remove),
|
||||
.driver = {
|
||||
.name = "isp1760",
|
||||
},
|
||||
|
@ -35,13 +35,14 @@
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/memory.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/cputype.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "musb_core.h"
|
||||
|
||||
#ifdef CONFIG_MACH_DAVINCI_EVM
|
||||
#define GPIO_nVBUS_DRV 87
|
||||
#define GPIO_nVBUS_DRV 144
|
||||
#endif
|
||||
|
||||
#include "davinci.h"
|
||||
@ -329,7 +330,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
|
||||
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
|
||||
WARNING("VBUS error workaround (delay coming)\n");
|
||||
} else if (is_host_enabled(musb) && drvvbus) {
|
||||
musb->is_active = 1;
|
||||
MUSB_HST_MODE(musb);
|
||||
musb->xceiv->default_a = 1;
|
||||
musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
|
||||
@ -343,7 +343,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
|
||||
portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
|
||||
}
|
||||
|
||||
/* NOTE: this must complete poweron within 100 msec */
|
||||
/* NOTE: this must complete poweron within 100 msec
|
||||
* (OTG_TIME_A_WAIT_VRISE) but we don't check for that.
|
||||
*/
|
||||
davinci_source_power(musb, drvvbus, 0);
|
||||
DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
|
||||
drvvbus ? "on" : "off",
|
||||
@ -411,6 +413,21 @@ int __init musb_platform_init(struct musb *musb)
|
||||
__raw_writel(phy_ctrl, USB_PHY_CTRL);
|
||||
}
|
||||
|
||||
/* On dm355, the default-A state machine needs DRVVBUS control.
|
||||
* If we won't be a host, there's no need to turn it on.
|
||||
*/
|
||||
if (cpu_is_davinci_dm355()) {
|
||||
u32 deepsleep = __raw_readl(DM355_DEEPSLEEP);
|
||||
|
||||
if (is_host_enabled(musb)) {
|
||||
deepsleep &= ~DRVVBUS_OVERRIDE;
|
||||
} else {
|
||||
deepsleep &= ~DRVVBUS_FORCE;
|
||||
deepsleep |= DRVVBUS_OVERRIDE;
|
||||
}
|
||||
__raw_writel(deepsleep, DM355_DEEPSLEEP);
|
||||
}
|
||||
|
||||
/* reset the controller */
|
||||
musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
|
||||
|
||||
@ -437,6 +454,15 @@ int musb_platform_exit(struct musb *musb)
|
||||
if (is_host_enabled(musb))
|
||||
del_timer_sync(&otg_workaround);
|
||||
|
||||
/* force VBUS off */
|
||||
if (cpu_is_davinci_dm355()) {
|
||||
u32 deepsleep = __raw_readl(DM355_DEEPSLEEP);
|
||||
|
||||
deepsleep &= ~DRVVBUS_FORCE;
|
||||
deepsleep |= DRVVBUS_OVERRIDE;
|
||||
__raw_writel(deepsleep, DM355_DEEPSLEEP);
|
||||
}
|
||||
|
||||
davinci_source_power(musb, 0 /*off*/, 1);
|
||||
|
||||
/* delay, to avoid problems with module reload */
|
||||
|
@ -373,7 +373,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb,
|
||||
musb_save_toggle(qh, is_in, urb);
|
||||
break;
|
||||
case USB_ENDPOINT_XFER_ISOC:
|
||||
if (urb->error_count)
|
||||
if (status == 0 && urb->error_count)
|
||||
status = -EXDEV;
|
||||
break;
|
||||
}
|
||||
@ -2235,13 +2235,30 @@ static void musb_h_stop(struct usb_hcd *hcd)
|
||||
static int musb_bus_suspend(struct usb_hcd *hcd)
|
||||
{
|
||||
struct musb *musb = hcd_to_musb(hcd);
|
||||
u8 devctl;
|
||||
|
||||
if (musb->xceiv->state == OTG_STATE_A_SUSPEND)
|
||||
if (!is_host_active(musb))
|
||||
return 0;
|
||||
|
||||
if (is_host_active(musb) && musb->is_active) {
|
||||
WARNING("trying to suspend as %s is_active=%i\n",
|
||||
otg_state_string(musb), musb->is_active);
|
||||
switch (musb->xceiv->state) {
|
||||
case OTG_STATE_A_SUSPEND:
|
||||
return 0;
|
||||
case OTG_STATE_A_WAIT_VRISE:
|
||||
/* ID could be grounded even if there's no device
|
||||
* on the other end of the cable. NOTE that the
|
||||
* A_WAIT_VRISE timers are messy with MUSB...
|
||||
*/
|
||||
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
|
||||
if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
|
||||
musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (musb->is_active) {
|
||||
WARNING("trying to suspend as %s while active\n",
|
||||
otg_state_string(musb));
|
||||
return -EBUSY;
|
||||
} else
|
||||
return 0;
|
||||
|
@ -59,18 +59,4 @@ config NOP_USB_XCEIV
|
||||
built-in with usb ip or which are autonomous and doesn't require any
|
||||
phy programming such as ISP1x04 etc.
|
||||
|
||||
config USB_LANGWELL_OTG
|
||||
tristate "Intel Langwell USB OTG dual-role support"
|
||||
depends on USB && MRST
|
||||
select USB_OTG
|
||||
select USB_OTG_UTILS
|
||||
help
|
||||
Say Y here if you want to build Intel Langwell USB OTG
|
||||
transciever driver in kernel. This driver implements role
|
||||
switch between EHCI host driver and Langwell USB OTG
|
||||
client driver.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called langwell_otg.
|
||||
|
||||
endif # USB || OTG
|
||||
|
@ -9,7 +9,6 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o
|
||||
obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o
|
||||
obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
|
||||
obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o
|
||||
obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o
|
||||
obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o
|
||||
|
||||
ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -53,6 +53,7 @@ EXPORT_SYMBOL(usb_nop_xceiv_register);
|
||||
void usb_nop_xceiv_unregister(void)
|
||||
{
|
||||
platform_device_unregister(pd);
|
||||
pd = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(usb_nop_xceiv_unregister);
|
||||
|
||||
|
@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options)
|
||||
kfree(tty);
|
||||
}
|
||||
}
|
||||
/* So we know not to kill the hardware on a hangup on this
|
||||
port. We have also bumped the use count by one so it won't go
|
||||
idle */
|
||||
/* Now that any required fake tty operations are completed restore
|
||||
* the tty port count */
|
||||
--port->port.count;
|
||||
/* The console is special in terms of closing the device so
|
||||
* indicate this port is now acting as a system console. */
|
||||
port->console = 1;
|
||||
retval = 0;
|
||||
|
||||
@ -204,7 +206,7 @@ static void usb_console_write(struct console *co,
|
||||
|
||||
dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
|
||||
|
||||
if (!port->port.count) {
|
||||
if (!port->console) {
|
||||
dbg("%s - port not opened", __func__);
|
||||
return;
|
||||
}
|
||||
@ -300,8 +302,7 @@ void usb_serial_console_exit(void)
|
||||
{
|
||||
if (usbcons_info.port) {
|
||||
unregister_console(&usbcons);
|
||||
if (usbcons_info.port->port.count)
|
||||
usbcons_info.port->port.count--;
|
||||
usbcons_info.port->console = 0;
|
||||
usbcons_info.port = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ static struct usb_device_id id_table [] = {
|
||||
{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
|
||||
{ USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
|
||||
{ USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */
|
||||
{ USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */
|
||||
{ USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */
|
||||
{ USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
|
||||
{ USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
|
||||
{ USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
|
||||
|
@ -1228,8 +1228,8 @@ static void cypress_read_int_callback(struct urb *urb)
|
||||
/* precursor to disconnect so just go away */
|
||||
return;
|
||||
case -EPIPE:
|
||||
usb_clear_halt(port->serial->dev, 0x81);
|
||||
break;
|
||||
/* Can't call usb_clear_halt while in_interrupt */
|
||||
/* FALLS THROUGH */
|
||||
default:
|
||||
/* something ugly is going on... */
|
||||
dev_err(&urb->dev->dev,
|
||||
|
@ -108,6 +108,7 @@ struct ftdi_sio_quirk {
|
||||
|
||||
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 void ftdi_USB_UIRT_setup(struct ftdi_private *priv);
|
||||
static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
|
||||
|
||||
@ -119,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = {
|
||||
.probe = ftdi_mtxorb_hack_setup,
|
||||
};
|
||||
|
||||
static struct ftdi_sio_quirk ftdi_NDI_device_quirk = {
|
||||
.probe = ftdi_NDI_device_setup,
|
||||
};
|
||||
|
||||
static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
|
||||
.port_probe = ftdi_USB_UIRT_setup,
|
||||
};
|
||||
@ -192,6 +197,7 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
|
||||
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
|
||||
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
|
||||
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
|
||||
@ -580,6 +586,9 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
|
||||
{ USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
|
||||
{ USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
|
||||
@ -645,6 +654,16 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
|
||||
{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
|
||||
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
|
||||
@ -661,6 +680,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, FTDI_TURTELIZER_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
|
||||
{ USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
|
||||
@ -668,7 +689,6 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
|
||||
{ USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) },
|
||||
{ USB_DEVICE(ATMEL_VID, STK541_PID) },
|
||||
{ USB_DEVICE(DE_VID, STB_PID) },
|
||||
{ USB_DEVICE(DE_VID, WHT_PID) },
|
||||
@ -1024,6 +1044,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
|
||||
case FT2232C: /* FT2232C chip */
|
||||
case FT232RL:
|
||||
if (baud <= 3000000) {
|
||||
__u16 product_id = le16_to_cpu(
|
||||
port->serial->dev->descriptor.idProduct);
|
||||
if (((FTDI_NDI_HUC_PID == product_id) ||
|
||||
(FTDI_NDI_SPECTRA_SCU_PID == product_id) ||
|
||||
(FTDI_NDI_FUTURE_2_PID == product_id) ||
|
||||
(FTDI_NDI_FUTURE_3_PID == product_id) ||
|
||||
(FTDI_NDI_AURORA_SCU_PID == product_id)) &&
|
||||
(baud == 19200)) {
|
||||
baud = 1200000;
|
||||
}
|
||||
div_value = ftdi_232bm_baud_to_divisor(baud);
|
||||
} else {
|
||||
dbg("%s - Baud rate too high!", __func__);
|
||||
@ -1554,6 +1584,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
|
||||
priv->force_rtscts = 1;
|
||||
} /* ftdi_HE_TIRA1_setup */
|
||||
|
||||
/*
|
||||
* Module parameter to control latency timer for NDI FTDI-based USB devices.
|
||||
* If this value is not set in modprobe.conf.local its value will be set to 1ms.
|
||||
*/
|
||||
static int ndi_latency_timer = 1;
|
||||
|
||||
/* Setup for the NDI FTDI-based USB devices, which requires hardwired
|
||||
* baudrate (19200 gets mapped to 1200000).
|
||||
*
|
||||
* Called from usbserial:serial_probe.
|
||||
*/
|
||||
static int ftdi_NDI_device_setup(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_device *udev = serial->dev;
|
||||
int latency = ndi_latency_timer;
|
||||
int rv = 0;
|
||||
char buf[1];
|
||||
|
||||
if (latency == 0)
|
||||
latency = 1;
|
||||
if (latency > 99)
|
||||
latency = 99;
|
||||
|
||||
dbg("%s setting NDI device latency to %d", __func__, latency);
|
||||
dev_info(&udev->dev, "NDI device with a latency value of %d", latency);
|
||||
|
||||
rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
|
||||
FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
|
||||
latency, 0, buf, 0, WDR_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko
|
||||
* Neo1973 Debug Board is reserved for JTAG interface and can be accessed from
|
||||
@ -2623,3 +2686,5 @@ MODULE_PARM_DESC(vendor, "User specified vendor ID (default="
|
||||
module_param(product, ushort, 0);
|
||||
MODULE_PARM_DESC(product, "User specified product ID");
|
||||
|
||||
module_param(ndi_latency_timer, int, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override");
|
||||
|
@ -506,6 +506,7 @@
|
||||
*
|
||||
* Armin Laeuger originally sent the PID for the UM 100 module.
|
||||
*/
|
||||
#define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG */
|
||||
#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */
|
||||
#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */
|
||||
#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */
|
||||
@ -614,6 +615,9 @@
|
||||
#define FTDI_CCSICDU20_0_PID 0xF9D0
|
||||
#define FTDI_CCSICDU40_1_PID 0xF9D1
|
||||
#define FTDI_CCSMACHX_2_PID 0xF9D2
|
||||
#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3
|
||||
#define FTDI_CCSICDU64_4_PID 0xF9D4
|
||||
#define FTDI_CCSPRIME8_5_PID 0xF9D5
|
||||
|
||||
/* Inside Accesso contactless reader (http://www.insidefr.com) */
|
||||
#define INSIDE_ACCESSO 0xFAD0
|
||||
@ -735,6 +739,15 @@
|
||||
/* Pyramid Computer GmbH */
|
||||
#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */
|
||||
|
||||
/*
|
||||
* NDI (www.ndigital.com) product ids
|
||||
*/
|
||||
#define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */
|
||||
#define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */
|
||||
#define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */
|
||||
#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */
|
||||
#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */
|
||||
|
||||
/*
|
||||
* Posiflex inc retail equipment (http://www.posiflex.com.tw)
|
||||
*/
|
||||
@ -848,9 +861,6 @@
|
||||
#define TML_VID 0x1B91 /* Vendor ID */
|
||||
#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */
|
||||
|
||||
/* NDI Polaris System */
|
||||
#define FTDI_NDI_HUC_PID 0xDA70
|
||||
|
||||
/* Propox devices */
|
||||
#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
|
||||
|
||||
@ -934,6 +944,8 @@
|
||||
#define MARVELL_VID 0x9e88
|
||||
#define MARVELL_SHEEVAPLUG_PID 0x9e8f
|
||||
|
||||
#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */
|
||||
|
||||
/*
|
||||
* BmRequestType: 1100 0000b
|
||||
* bRequest: FTDI_E2_READ
|
||||
|
@ -206,6 +206,7 @@ static int option_resume(struct usb_serial *serial);
|
||||
#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400
|
||||
#define NOVATELWIRELESS_PRODUCT_U727 0x5010
|
||||
#define NOVATELWIRELESS_PRODUCT_MC760 0x6000
|
||||
#define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002
|
||||
|
||||
/* FUTURE NOVATEL PRODUCTS */
|
||||
#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001
|
||||
@ -307,11 +308,20 @@ static int option_resume(struct usb_serial *serial);
|
||||
#define DLINK_VENDOR_ID 0x1186
|
||||
#define DLINK_PRODUCT_DWM_652 0x3e04
|
||||
|
||||
#define QISDA_VENDOR_ID 0x1da5
|
||||
#define QISDA_PRODUCT_H21_4512 0x4512
|
||||
#define QISDA_PRODUCT_H21_4523 0x4523
|
||||
#define QISDA_PRODUCT_H20_4515 0x4515
|
||||
#define QISDA_PRODUCT_H20_4519 0x4519
|
||||
|
||||
|
||||
/* TOSHIBA PRODUCTS */
|
||||
#define TOSHIBA_VENDOR_ID 0x0930
|
||||
#define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302
|
||||
|
||||
#define ALINK_VENDOR_ID 0x1e0e
|
||||
#define ALINK_PRODUCT_3GU 0x9200
|
||||
|
||||
static struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
|
||||
@ -430,6 +440,7 @@ static struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */
|
||||
@ -529,8 +540,13 @@ static struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
|
||||
{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
|
||||
{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
|
||||
{ USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
|
||||
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) },
|
||||
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
|
||||
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
|
||||
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) },
|
||||
{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
|
||||
{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||
@ -732,7 +748,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
memcpy(this_urb->transfer_buffer, buf, todo);
|
||||
this_urb->transfer_buffer_length = todo;
|
||||
|
||||
this_urb->dev = port->serial->dev;
|
||||
err = usb_submit_urb(this_urb, GFP_ATOMIC);
|
||||
if (err) {
|
||||
dbg("usb_submit_urb %p (write bulk) failed "
|
||||
@ -860,7 +875,6 @@ static void option_instat_callback(struct urb *urb)
|
||||
|
||||
/* Resubmit urb so we continue receiving IRQ data */
|
||||
if (status != -ESHUTDOWN && status != -ENOENT) {
|
||||
urb->dev = serial->dev;
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (err)
|
||||
dbg("%s: resubmit intr urb failed. (%d)",
|
||||
@ -921,23 +935,11 @@ static int option_open(struct tty_struct *tty,
|
||||
|
||||
dbg("%s", __func__);
|
||||
|
||||
/* Reset low level data toggle and start reading from endpoints */
|
||||
/* Start reading from the IN endpoint */
|
||||
for (i = 0; i < N_IN_URB; i++) {
|
||||
urb = portdata->in_urbs[i];
|
||||
if (!urb)
|
||||
continue;
|
||||
if (urb->dev != serial->dev) {
|
||||
dbg("%s: dev %p != %p", __func__,
|
||||
urb->dev, serial->dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure endpoint data toggle is synchronized with the
|
||||
* device
|
||||
*/
|
||||
usb_clear_halt(urb->dev, urb->pipe);
|
||||
|
||||
err = usb_submit_urb(urb, GFP_KERNEL);
|
||||
if (err) {
|
||||
dbg("%s: submit urb %d failed (%d) %d",
|
||||
@ -946,16 +948,6 @@ static int option_open(struct tty_struct *tty,
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset low level data toggle on out endpoints */
|
||||
for (i = 0; i < N_OUT_URB; i++) {
|
||||
urb = portdata->out_urbs[i];
|
||||
if (!urb)
|
||||
continue;
|
||||
urb->dev = serial->dev;
|
||||
/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
|
||||
usb_pipeout(urb->pipe), 0); */
|
||||
}
|
||||
|
||||
option_send_setup(port);
|
||||
|
||||
return 0;
|
||||
@ -1218,7 +1210,6 @@ static int option_resume(struct usb_serial *serial)
|
||||
dbg("%s: No interrupt URB for port %d\n", __func__, i);
|
||||
continue;
|
||||
}
|
||||
port->interrupt_in_urb->dev = serial->dev;
|
||||
err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
|
||||
dbg("Submitted interrupt URB for port %d (result %d)", i, err);
|
||||
if (err < 0) {
|
||||
|
@ -94,6 +94,7 @@ static struct usb_device_id id_table [] = {
|
||||
{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
|
||||
{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
|
||||
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
@ -122,3 +122,7 @@
|
||||
/* Hewlett-Packard LD220-HP POS Pole Display */
|
||||
#define HP_VENDOR_ID 0x03f0
|
||||
#define HP_LD220_PRODUCT_ID 0x3524
|
||||
|
||||
/* Cressi Edy (diving computer) PC interface */
|
||||
#define CRESSI_VENDOR_ID 0x04b8
|
||||
#define CRESSI_EDY_PRODUCT_ID 0x0521
|
||||
|
@ -181,35 +181,50 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = {
|
||||
};
|
||||
|
||||
static struct usb_device_id id_table [] = {
|
||||
{ USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
|
||||
{ USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */
|
||||
{ USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */
|
||||
|
||||
{ USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
|
||||
{ USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
|
||||
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
|
||||
{ USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */
|
||||
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
|
||||
{ USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
|
||||
{ USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
|
||||
{ USB_DEVICE(0x1199, 0x0022) }, /* Sierra Wireless EM5725 */
|
||||
{ USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
|
||||
{ USB_DEVICE(0x1199, 0x0224) }, /* Sierra Wireless MC5727 */
|
||||
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
|
||||
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
|
||||
{ USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
|
||||
{ USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
|
||||
/* Sierra Wireless C597 */
|
||||
/* Sierra Wireless C597 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
|
||||
/* Sierra Wireless Device */
|
||||
/* Sierra Wireless T598 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
|
||||
{ USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
|
||||
{ USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */
|
||||
{ USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */
|
||||
{ USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */
|
||||
{ USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */
|
||||
{ USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */
|
||||
{ USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */
|
||||
|
||||
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
|
||||
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
|
||||
{ USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
|
||||
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
|
||||
{ USB_DEVICE(0x1199, 0x6805) }, /* Sierra Wireless MC8765 */
|
||||
{ USB_DEVICE(0x1199, 0x6808) }, /* Sierra Wireless MC8755 */
|
||||
{ USB_DEVICE(0x1199, 0x6809) }, /* Sierra Wireless MC8765 */
|
||||
{ USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */
|
||||
{ USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */
|
||||
{ USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */
|
||||
{ USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */
|
||||
{ USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */
|
||||
{ USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */
|
||||
{ USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
|
||||
{ USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
|
||||
{ USB_DEVICE(0x1199, 0x6822) }, /* Sierra Wireless AirCard 875E */
|
||||
{ USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
|
||||
{ USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
|
||||
{ USB_DEVICE(0x1199, 0x6834) }, /* Sierra Wireless MC8780 */
|
||||
{ USB_DEVICE(0x1199, 0x6835) }, /* Sierra Wireless MC8781 */
|
||||
{ USB_DEVICE(0x1199, 0x6838) }, /* Sierra Wireless MC8780 */
|
||||
{ USB_DEVICE(0x1199, 0x6839) }, /* Sierra Wireless MC8781 */
|
||||
{ USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */
|
||||
{ USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
|
||||
/* Sierra Wireless MC8790, MC8791, MC8792 Composite */
|
||||
@ -227,16 +242,13 @@ static struct usb_device_id id_table [] = {
|
||||
{ USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
|
||||
/* Sierra Wireless C885 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
|
||||
/* Sierra Wireless Device */
|
||||
/* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
|
||||
/* Sierra Wireless Device */
|
||||
/* Sierra Wireless C22/C33 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)},
|
||||
/* Sierra Wireless Device */
|
||||
/* Sierra Wireless HSPA Non-Composite Device */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
|
||||
|
||||
{ USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
|
||||
{ USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
|
||||
|
||||
{ USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
|
||||
{ USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */
|
||||
.driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
|
||||
},
|
||||
@ -814,7 +826,7 @@ static int sierra_startup(struct usb_serial *serial)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sierra_disconnect(struct usb_serial *serial)
|
||||
static void sierra_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
struct usb_serial_port *port;
|
||||
@ -830,7 +842,6 @@ static void sierra_disconnect(struct usb_serial *serial)
|
||||
if (!portdata)
|
||||
continue;
|
||||
kfree(portdata);
|
||||
usb_set_serial_port_data(port, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -853,7 +864,7 @@ static struct usb_serial_driver sierra_device = {
|
||||
.tiocmget = sierra_tiocmget,
|
||||
.tiocmset = sierra_tiocmset,
|
||||
.attach = sierra_startup,
|
||||
.disconnect = sierra_disconnect,
|
||||
.release = sierra_release,
|
||||
.read_int_callback = sierra_instat_callback,
|
||||
};
|
||||
|
||||
|
@ -191,7 +191,6 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
|
||||
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
|
||||
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
|
||||
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
|
||||
{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
|
||||
};
|
||||
|
||||
static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
|
||||
@ -1658,7 +1657,7 @@ static int ti_do_download(struct usb_device *dev, int pipe,
|
||||
u8 cs = 0;
|
||||
int done;
|
||||
struct ti_firmware_header *header;
|
||||
int status;
|
||||
int status = 0;
|
||||
int len;
|
||||
|
||||
for (pos = sizeof(struct ti_firmware_header); pos < size; pos++)
|
||||
|
@ -221,7 +221,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
|
||||
tty->driver_data = port;
|
||||
tty_port_tty_set(&port->port, tty);
|
||||
|
||||
if (port->port.count == 1) {
|
||||
/* If the console is attached, the device is already open */
|
||||
if (port->port.count == 1 && !port->console) {
|
||||
|
||||
/* lock this module before we call it
|
||||
* this may fail, which means we must bail out,
|
||||
|
@ -118,6 +118,9 @@ static int option_inquiry(struct us_data *us)
|
||||
|
||||
result = memcmp(buffer+8, "Option", 6);
|
||||
|
||||
if (result != 0)
|
||||
result = memcmp(buffer+8, "ZCOPTION", 8);
|
||||
|
||||
/* Read the CSW */
|
||||
usb_stor_bulk_transfer_buf(us,
|
||||
us->recv_bulk_pipe,
|
||||
|
@ -888,8 +888,6 @@ struct usb_driver {
|
||||
* struct usb_device_driver - identifies USB device driver to usbcore
|
||||
* @name: The driver name should be unique among USB drivers,
|
||||
* and should normally be the same as the module name.
|
||||
* @nodename: Callback to provide a naming hint for a possible
|
||||
* device node to create.
|
||||
* @probe: Called to see if the driver is willing to manage a particular
|
||||
* device. If it is, probe returns zero and uses dev_set_drvdata()
|
||||
* to associate driver-specific data with the device. If unwilling
|
||||
@ -924,6 +922,8 @@ extern struct bus_type usb_bus_type;
|
||||
/**
|
||||
* struct usb_class_driver - identifies a USB driver that wants to use the USB major number
|
||||
* @name: the usb class device name for this driver. Will show up in sysfs.
|
||||
* @nodename: Callback to provide a naming hint for a possible
|
||||
* device node to create.
|
||||
* @fops: pointer to the struct file_operations of this driver.
|
||||
* @minor_base: the start of the minor range for this driver.
|
||||
*
|
||||
@ -1046,6 +1046,8 @@ typedef void (*usb_complete_t)(struct urb *);
|
||||
* the device driver is saying that it provided this DMA address,
|
||||
* which the host controller driver should use in preference to the
|
||||
* transfer_buffer.
|
||||
* @sg: scatter gather buffer list
|
||||
* @num_sgs: number of entries in the sg list
|
||||
* @transfer_buffer_length: How big is transfer_buffer. The transfer may
|
||||
* be broken up into chunks according to the current maximum packet
|
||||
* size for the endpoint, which is a function of the configuration
|
||||
|
@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Intel Langwell USB OTG transceiver driver
|
||||
* Copyright (C) 2008, Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LANGWELL_OTG_H__
|
||||
#define __LANGWELL_OTG_H__
|
||||
|
||||
/* notify transceiver driver about OTG events */
|
||||
extern void langwell_update_transceiver(void);
|
||||
/* HCD register bus driver */
|
||||
extern int langwell_register_host(struct pci_driver *host_driver);
|
||||
/* HCD unregister bus driver */
|
||||
extern void langwell_unregister_host(struct pci_driver *host_driver);
|
||||
/* DCD register bus driver */
|
||||
extern int langwell_register_peripheral(struct pci_driver *client_driver);
|
||||
/* DCD unregister bus driver */
|
||||
extern void langwell_unregister_peripheral(struct pci_driver *client_driver);
|
||||
/* No silent failure, output warning message */
|
||||
extern void langwell_otg_nsf_msg(unsigned long message);
|
||||
|
||||
#define CI_USBCMD 0x30
|
||||
# define USBCMD_RST BIT(1)
|
||||
# define USBCMD_RS BIT(0)
|
||||
#define CI_USBSTS 0x34
|
||||
# define USBSTS_SLI BIT(8)
|
||||
# define USBSTS_URI BIT(6)
|
||||
# define USBSTS_PCI BIT(2)
|
||||
#define CI_PORTSC1 0x74
|
||||
# define PORTSC_PP BIT(12)
|
||||
# define PORTSC_LS (BIT(11) | BIT(10))
|
||||
# define PORTSC_SUSP BIT(7)
|
||||
# define PORTSC_CCS BIT(0)
|
||||
#define CI_HOSTPC1 0xb4
|
||||
# define HOSTPC1_PHCD BIT(22)
|
||||
#define CI_OTGSC 0xf4
|
||||
# define OTGSC_DPIE BIT(30)
|
||||
# define OTGSC_1MSE BIT(29)
|
||||
# define OTGSC_BSEIE BIT(28)
|
||||
# define OTGSC_BSVIE BIT(27)
|
||||
# define OTGSC_ASVIE BIT(26)
|
||||
# define OTGSC_AVVIE BIT(25)
|
||||
# define OTGSC_IDIE BIT(24)
|
||||
# define OTGSC_DPIS BIT(22)
|
||||
# define OTGSC_1MSS BIT(21)
|
||||
# define OTGSC_BSEIS BIT(20)
|
||||
# define OTGSC_BSVIS BIT(19)
|
||||
# define OTGSC_ASVIS BIT(18)
|
||||
# define OTGSC_AVVIS BIT(17)
|
||||
# define OTGSC_IDIS BIT(16)
|
||||
# define OTGSC_DPS BIT(14)
|
||||
# define OTGSC_1MST BIT(13)
|
||||
# define OTGSC_BSE BIT(12)
|
||||
# define OTGSC_BSV BIT(11)
|
||||
# define OTGSC_ASV BIT(10)
|
||||
# define OTGSC_AVV BIT(9)
|
||||
# define OTGSC_ID BIT(8)
|
||||
# define OTGSC_HABA BIT(7)
|
||||
# define OTGSC_HADP BIT(6)
|
||||
# define OTGSC_IDPU BIT(5)
|
||||
# define OTGSC_DP BIT(4)
|
||||
# define OTGSC_OT BIT(3)
|
||||
# define OTGSC_HAAR BIT(2)
|
||||
# define OTGSC_VC BIT(1)
|
||||
# define OTGSC_VD BIT(0)
|
||||
# define OTGSC_INTEN_MASK (0x7f << 24)
|
||||
# define OTGSC_INTSTS_MASK (0x7f << 16)
|
||||
#define CI_USBMODE 0xf8
|
||||
# define USBMODE_CM (BIT(1) | BIT(0))
|
||||
# define USBMODE_IDLE 0
|
||||
# define USBMODE_DEVICE 0x2
|
||||
# define USBMODE_HOST 0x3
|
||||
|
||||
#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI)
|
||||
|
||||
struct otg_hsm {
|
||||
/* Input */
|
||||
int a_bus_resume;
|
||||
int a_bus_suspend;
|
||||
int a_conn;
|
||||
int a_sess_vld;
|
||||
int a_srp_det;
|
||||
int a_vbus_vld;
|
||||
int b_bus_resume;
|
||||
int b_bus_suspend;
|
||||
int b_conn;
|
||||
int b_se0_srp;
|
||||
int b_sess_end;
|
||||
int b_sess_vld;
|
||||
int id;
|
||||
|
||||
/* Internal variables */
|
||||
int a_set_b_hnp_en;
|
||||
int b_srp_done;
|
||||
int b_hnp_enable;
|
||||
|
||||
/* Timeout indicator for timers */
|
||||
int a_wait_vrise_tmout;
|
||||
int a_wait_bcon_tmout;
|
||||
int a_aidl_bdis_tmout;
|
||||
int b_ase0_brst_tmout;
|
||||
int b_bus_suspend_tmout;
|
||||
int b_srp_res_tmout;
|
||||
|
||||
/* Informative variables */
|
||||
int a_bus_drop;
|
||||
int a_bus_req;
|
||||
int a_clr_err;
|
||||
int a_suspend_req;
|
||||
int b_bus_req;
|
||||
|
||||
/* Output */
|
||||
int drv_vbus;
|
||||
int loc_conn;
|
||||
int loc_sof;
|
||||
|
||||
/* Others */
|
||||
int b_bus_suspend_vld;
|
||||
};
|
||||
|
||||
#define TA_WAIT_VRISE 100
|
||||
#define TA_WAIT_BCON 30000
|
||||
#define TA_AIDL_BDIS 15000
|
||||
#define TB_ASE0_BRST 5000
|
||||
#define TB_SE0_SRP 2
|
||||
#define TB_SRP_RES 100
|
||||
#define TB_BUS_SUSPEND 500
|
||||
|
||||
struct langwell_otg_timer {
|
||||
unsigned long expires; /* Number of count increase to timeout */
|
||||
unsigned long count; /* Tick counter */
|
||||
void (*function)(unsigned long); /* Timeout function */
|
||||
unsigned long data; /* Data passed to function */
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct langwell_otg {
|
||||
struct otg_transceiver otg;
|
||||
struct otg_hsm hsm;
|
||||
void __iomem *regs;
|
||||
unsigned region;
|
||||
struct pci_driver *host_ops;
|
||||
struct pci_driver *client_ops;
|
||||
struct pci_dev *pdev;
|
||||
struct work_struct work;
|
||||
struct workqueue_struct *qwork;
|
||||
spinlock_t lock;
|
||||
spinlock_t wq_lock;
|
||||
};
|
||||
|
||||
static inline struct langwell_otg *otg_to_langwell(struct otg_transceiver *otg)
|
||||
{
|
||||
return container_of(otg, struct langwell_otg, otg);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#define otg_dbg(fmt, args...) \
|
||||
printk(KERN_DEBUG fmt , ## args)
|
||||
#else
|
||||
#define otg_dbg(fmt, args...) \
|
||||
do { } while (0)
|
||||
#endif /* DEBUG */
|
||||
#endif /* __LANGWELL_OTG_H__ */
|
Loading…
Reference in New Issue
Block a user