Commit 51feb98d authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 8f8f0134 dc7520c1
...@@ -387,6 +387,7 @@ static void acm_rx_tasklet(unsigned long _acm) ...@@ -387,6 +387,7 @@ static void acm_rx_tasklet(unsigned long _acm)
struct acm_ru *rcv; struct acm_ru *rcv;
unsigned long flags; unsigned long flags;
unsigned char throttled; unsigned char throttled;
struct usb_host_endpoint *ep;
dbg("Entering acm_rx_tasklet"); dbg("Entering acm_rx_tasklet");
...@@ -462,11 +463,20 @@ static void acm_rx_tasklet(unsigned long _acm) ...@@ -462,11 +463,20 @@ static void acm_rx_tasklet(unsigned long _acm)
rcv->buffer = buf; rcv->buffer = buf;
usb_fill_bulk_urb(rcv->urb, acm->dev, ep = (usb_pipein(acm->rx_endpoint) ? acm->dev->ep_in : acm->dev->ep_out)
acm->rx_endpoint, [usb_pipeendpoint(acm->rx_endpoint)];
buf->base, if (usb_endpoint_xfer_int(&ep->desc))
acm->readsize, usb_fill_int_urb(rcv->urb, acm->dev,
acm_read_bulk, rcv); 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_dma = buf->dma;
rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
...@@ -1227,9 +1237,14 @@ static int acm_probe(struct usb_interface *intf, ...@@ -1227,9 +1237,14 @@ static int acm_probe(struct usb_interface *intf,
goto alloc_fail7; goto alloc_fail7;
} }
usb_fill_bulk_urb(snd->urb, usb_dev, if (usb_endpoint_xfer_int(epwrite))
usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), usb_fill_int_urb(snd->urb, usb_dev,
NULL, acm->writesize, acm_write_bulk, snd); 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->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
snd->instance = acm; snd->instance = acm;
} }
......
...@@ -751,7 +751,7 @@ static int get_capabilities(struct usbtmc_device_data *data) ...@@ -751,7 +751,7 @@ static int get_capabilities(struct usbtmc_device_data *data)
{ {
struct device *dev = &data->usb_dev->dev; struct device *dev = &data->usb_dev->dev;
char *buffer; char *buffer;
int rv; int rv = 0;
buffer = kmalloc(0x18, GFP_KERNEL); buffer = kmalloc(0x18, GFP_KERNEL);
if (!buffer) if (!buffer)
...@@ -763,7 +763,7 @@ static int get_capabilities(struct usbtmc_device_data *data) ...@@ -763,7 +763,7 @@ static int get_capabilities(struct usbtmc_device_data *data)
0, 0, buffer, 0x18, USBTMC_TIMEOUT); 0, 0, buffer, 0x18, USBTMC_TIMEOUT);
if (rv < 0) { if (rv < 0) {
dev_err(dev, "usb_control_msg returned %d\n", rv); 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]); dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
...@@ -773,7 +773,8 @@ static int get_capabilities(struct usbtmc_device_data *data) ...@@ -773,7 +773,8 @@ static int get_capabilities(struct usbtmc_device_data *data)
dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]);
if (buffer[0] != USBTMC_STATUS_SUCCESS) { if (buffer[0] != USBTMC_STATUS_SUCCESS) {
dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
return -EPERM; rv = -EPERM;
goto err_out;
} }
data->capabilities.interface_capabilities = buffer[4]; data->capabilities.interface_capabilities = buffer[4];
...@@ -781,8 +782,9 @@ static int get_capabilities(struct usbtmc_device_data *data) ...@@ -781,8 +782,9 @@ static int get_capabilities(struct usbtmc_device_data *data)
data->capabilities.usb488_interface_capabilities = buffer[14]; data->capabilities.usb488_interface_capabilities = buffer[14];
data->capabilities.usb488_device_capabilities = buffer[15]; data->capabilities.usb488_device_capabilities = buffer[15];
err_out:
kfree(buffer); kfree(buffer);
return 0; return rv;
} }
#define capability_attribute(name) \ #define capability_attribute(name) \
......
...@@ -28,7 +28,7 @@ comment "Miscellaneous USB options" ...@@ -28,7 +28,7 @@ comment "Miscellaneous USB options"
depends on USB depends on USB
config USB_DEVICEFS config USB_DEVICEFS
bool "USB device filesystem (DEPRECATED)" if EMBEDDED bool "USB device filesystem (DEPRECATED)"
depends on USB depends on USB
---help--- ---help---
If you say Y here (and to "/proc file system support" in the "File 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[] = ...@@ -136,17 +136,19 @@ static const struct class_info clas_info[] =
{USB_CLASS_AUDIO, "audio"}, {USB_CLASS_AUDIO, "audio"},
{USB_CLASS_COMM, "comm."}, {USB_CLASS_COMM, "comm."},
{USB_CLASS_HID, "HID"}, {USB_CLASS_HID, "HID"},
{USB_CLASS_HUB, "hub"},
{USB_CLASS_PHYSICAL, "PID"}, {USB_CLASS_PHYSICAL, "PID"},
{USB_CLASS_STILL_IMAGE, "still"},
{USB_CLASS_PRINTER, "print"}, {USB_CLASS_PRINTER, "print"},
{USB_CLASS_MASS_STORAGE, "stor."}, {USB_CLASS_MASS_STORAGE, "stor."},
{USB_CLASS_HUB, "hub"},
{USB_CLASS_CDC_DATA, "data"}, {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_CSCID, "scard"},
{USB_CLASS_CONTENT_SEC, "c-sec"}, {USB_CLASS_CONTENT_SEC, "c-sec"},
{USB_CLASS_VIDEO, "video"}, {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 */ {-1, "unk."} /* leave as last */
}; };
......
...@@ -325,21 +325,34 @@ static void async_completed(struct urb *urb) ...@@ -325,21 +325,34 @@ static void async_completed(struct urb *urb)
struct async *as = urb->context; struct async *as = urb->context;
struct dev_state *ps = as->ps; struct dev_state *ps = as->ps;
struct siginfo sinfo; struct siginfo sinfo;
struct pid *pid = NULL;
uid_t uid = 0;
uid_t euid = 0;
u32 secid = 0;
int signr;
spin_lock(&ps->lock); spin_lock(&ps->lock);
list_move_tail(&as->asynclist, &ps->async_completed); list_move_tail(&as->asynclist, &ps->async_completed);
spin_unlock(&ps->lock);
as->status = urb->status; as->status = urb->status;
if (as->signr) { signr = as->signr;
if (signr) {
sinfo.si_signo = as->signr; sinfo.si_signo = as->signr;
sinfo.si_errno = as->status; sinfo.si_errno = as->status;
sinfo.si_code = SI_ASYNCIO; sinfo.si_code = SI_ASYNCIO;
sinfo.si_addr = as->userurb; sinfo.si_addr = as->userurb;
kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid, pid = as->pid;
as->euid, as->secid); uid = as->uid;
euid = as->euid;
secid = as->secid;
} }
snoop(&urb->dev->dev, "urb complete\n"); snoop(&urb->dev->dev, "urb complete\n");
snoop_urb(urb, as->userurb); 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); wake_up(&ps->wait);
} }
...@@ -982,7 +995,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ...@@ -982,7 +995,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
USBDEVFS_URB_ZERO_PACKET | USBDEVFS_URB_ZERO_PACKET |
USBDEVFS_URB_NO_INTERRUPT)) USBDEVFS_URB_NO_INTERRUPT))
return -EINVAL; return -EINVAL;
if (!uurb->buffer) if (uurb->buffer_length > 0 && !uurb->buffer)
return -EINVAL; return -EINVAL;
if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL &&
(uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) {
...@@ -1038,11 +1051,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ...@@ -1038,11 +1051,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
is_in = 0; is_in = 0;
uurb->endpoint &= ~USB_DIR_IN; 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 " snoop(&ps->dev->dev, "control urb: bRequest=%02x "
"bRrequestType=%02x wValue=%04x " "bRrequestType=%02x wValue=%04x "
"wIndex=%04x wLength=%04x\n", "wIndex=%04x wLength=%04x\n",
...@@ -1062,9 +1070,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ...@@ -1062,9 +1070,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
uurb->number_of_packets = 0; uurb->number_of_packets = 0;
if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
return -EINVAL; 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"); snoop(&ps->dev->dev, "bulk urb\n");
break; break;
...@@ -1106,28 +1111,35 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ...@@ -1106,28 +1111,35 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
return -EINVAL; return -EINVAL;
if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
return -EINVAL; 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"); snoop(&ps->dev->dev, "interrupt urb\n");
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
as = alloc_async(uurb->number_of_packets); if (uurb->buffer_length > 0 &&
if (!as) { !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
uurb->buffer, uurb->buffer_length)) {
kfree(isopkt); kfree(isopkt);
kfree(dr); kfree(dr);
return -ENOMEM; return -EFAULT;
} }
as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL); as = alloc_async(uurb->number_of_packets);
if (!as->urb->transfer_buffer) { if (!as) {
kfree(isopkt); kfree(isopkt);
kfree(dr); kfree(dr);
free_async(as);
return -ENOMEM; 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->dev = ps->dev;
as->urb->pipe = (uurb->type << 30) | as->urb->pipe = (uurb->type << 30) |
__create_pipe(ps->dev, uurb->endpoint & 0xf) | __create_pipe(ps->dev, uurb->endpoint & 0xf) |
...@@ -1169,7 +1181,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ...@@ -1169,7 +1181,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
kfree(isopkt); kfree(isopkt);
as->ps = ps; as->ps = ps;
as->userurb = arg; as->userurb = arg;
if (uurb->endpoint & USB_DIR_IN) if (is_in && uurb->buffer_length > 0)
as->userbuffer = uurb->buffer; as->userbuffer = uurb->buffer;
else else
as->userbuffer = NULL; as->userbuffer = NULL;
...@@ -1179,9 +1191,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ...@@ -1179,9 +1191,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
as->uid = cred->uid; as->uid = cred->uid;
as->euid = cred->euid; as->euid = cred->euid;
security_task_getsecid(current, &as->secid); 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, if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,
as->urb->transfer_buffer_length)) { uurb->buffer_length)) {
free_async(as); free_async(as);
return -EFAULT; return -EFAULT;
} }
...@@ -1231,22 +1243,22 @@ static int processcompl(struct async *as, void __user * __user *arg) ...@@ -1231,22 +1243,22 @@ static int processcompl(struct async *as, void __user * __user *arg)
if (as->userbuffer) if (as->userbuffer)
if (copy_to_user(as->userbuffer, urb->transfer_buffer, if (copy_to_user(as->userbuffer, urb->transfer_buffer,
urb->transfer_buffer_length)) urb->transfer_buffer_length))
return -EFAULT; goto err_out;
if (put_user(as->status, &userurb->status)) if (put_user(as->status, &userurb->status))
return -EFAULT; goto err_out;
if (put_user(urb->actual_length, &userurb->actual_length)) if (put_user(urb->actual_length, &userurb->actual_length))
return -EFAULT; goto err_out;
if (put_user(urb->error_count, &userurb->error_count)) if (put_user(urb->error_count, &userurb->error_count))
return -EFAULT; goto err_out;
if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { if (usb_endpoint_xfer_isoc(&urb->ep->desc)) {
for (i = 0; i < urb->number_of_packets; i++) { for (i = 0; i < urb->number_of_packets; i++) {
if (put_user(urb->iso_frame_desc[i].actual_length, if (put_user(urb->iso_frame_desc[i].actual_length,
&userurb->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, if (put_user(urb->iso_frame_desc[i].status,
&userurb->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) ...@@ -1255,6 +1267,10 @@ static int processcompl(struct async *as, void __user * __user *arg)
if (put_user(addr, (void __user * __user *)arg)) if (put_user(addr, (void __user * __user *)arg))
return -EFAULT; return -EFAULT;
return 0; return 0;
err_out:
free_async(as);
return -EFAULT;
} }
static struct async *reap_as(struct dev_state *ps) static struct async *reap_as(struct dev_state *ps)
......
...@@ -227,6 +227,10 @@ struct hc_driver { ...@@ -227,6 +227,10 @@ struct hc_driver {
/* has a port been handed over to a companion? */ /* has a port been handed over to a companion? */
int (*port_handed_over)(struct usb_hcd *, int); 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 */ /* xHCI specific functions */
/* Called by usb_alloc_dev to alloc HC device structures */ /* Called by usb_alloc_dev to alloc HC device structures */
int (*alloc_dev)(struct usb_hcd *, struct usb_device *); 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) ...@@ -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 * talking to TTs must queue control transfers (not just bulk and iso), so
* both can talk to the same hub concurrently. * 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 = struct usb_hub *hub =
container_of(work, struct usb_hub, tt.kevent); container_of(work, struct usb_hub, tt.clear_work);
unsigned long flags; unsigned long flags;
int limit = 100; int limit = 100;
...@@ -462,6 +462,7 @@ static void hub_tt_kevent (struct work_struct *work) ...@@ -462,6 +462,7 @@ static void hub_tt_kevent (struct work_struct *work)
struct list_head *next; struct list_head *next;
struct usb_tt_clear *clear; struct usb_tt_clear *clear;
struct usb_device *hdev = hub->hdev; struct usb_device *hdev = hub->hdev;
const struct hc_driver *drv;
int status; int status;
next = hub->tt.clear_list.next; next = hub->tt.clear_list.next;
...@@ -471,21 +472,25 @@ static void hub_tt_kevent (struct work_struct *work) ...@@ -471,21 +472,25 @@ static void hub_tt_kevent (struct work_struct *work)
/* drop lock so HCD can concurrently report other TT errors */ /* drop lock so HCD can concurrently report other TT errors */
spin_unlock_irqrestore (&hub->tt.lock, flags); spin_unlock_irqrestore (&hub->tt.lock, flags);
status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt); status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt);
spin_lock_irqsave (&hub->tt.lock, flags);
if (status) if (status)
dev_err (&hdev->dev, dev_err (&hdev->dev,
"clear tt %d (%04x) error %d\n", "clear tt %d (%04x) error %d\n",
clear->tt, clear->devinfo, status); 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); kfree(clear);
spin_lock_irqsave(&hub->tt.lock, flags);
} }
spin_unlock_irqrestore (&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 * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
* @udev: the device whose split transaction failed * @urb: an URB associated with the failed or incomplete split transaction
* @pipe: identifies the endpoint of the failed transaction
* *
* High speed HCDs use this to tell the hub driver that some split control or * 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 * 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) ...@@ -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) * It may not be possible for that hub to handle additional full (or low)
* speed transactions until that state is fully cleared out. * 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; struct usb_tt *tt = udev->tt;
unsigned long flags; unsigned long flags;
struct usb_tt_clear *clear; struct usb_tt_clear *clear;
...@@ -508,7 +515,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) ...@@ -508,7 +515,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) { if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) {
dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
/* FIXME recover somehow ... RESET_TT? */ /* FIXME recover somehow ... RESET_TT? */
return; return -ENOMEM;
} }
/* info that CLEAR_TT_BUFFER needs */ /* info that CLEAR_TT_BUFFER needs */
...@@ -520,14 +527,19 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) ...@@ -520,14 +527,19 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
: (USB_ENDPOINT_XFER_BULK << 11); : (USB_ENDPOINT_XFER_BULK << 11);
if (usb_pipein (pipe)) if (usb_pipein (pipe))
clear->devinfo |= 1 << 15; 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 */ /* tell keventd to clear state for this TT */
spin_lock_irqsave (&tt->lock, flags); spin_lock_irqsave (&tt->lock, flags);
list_add_tail (&clear->clear_list, &tt->clear_list); list_add_tail (&clear->clear_list, &tt->clear_list);
schedule_work (&tt->kevent); schedule_work(&tt->clear_work);
spin_unlock_irqrestore (&tt->lock, flags); 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 /* If do_delay is false, return the number of milliseconds the caller
* needs to delay. * needs to delay.
...@@ -818,7 +830,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) ...@@ -818,7 +830,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
if (hub->has_indicators) if (hub->has_indicators)
cancel_delayed_work_sync(&hub->leds); cancel_delayed_work_sync(&hub->leds);
if (hub->tt.hub) if (hub->tt.hub)
cancel_work_sync(&hub->tt.kevent); cancel_work_sync(&hub->tt.clear_work);
} }
/* caller has locked the hub device */ /* caller has locked the hub device */
...@@ -935,7 +947,7 @@ static int hub_configure(struct usb_hub *hub, ...@@ -935,7 +947,7 @@ static int hub_configure(struct usb_hub *hub,
spin_lock_init (&hub->tt.lock); spin_lock_init (&hub->tt.lock);
INIT_LIST_HEAD (&hub->tt.clear_list); 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) { switch (hdev->descriptor.bDeviceProtocol) {
case 0: case 0:
break; break;
......
...@@ -188,16 +188,18 @@ struct usb_tt { ...@@ -188,16 +188,18 @@ struct usb_tt {
/* for control/bulk error recovery (CLEAR_TT_BUFFER) */ /* for control/bulk error recovery (CLEAR_TT_BUFFER) */
spinlock_t lock; spinlock_t lock;
struct list_head clear_list; /* of usb_tt_clear */ struct list_head clear_list; /* of usb_tt_clear */
struct work_struct kevent; struct work_struct clear_work;
}; };
struct usb_tt_clear { struct usb_tt_clear {
struct list_head clear_list; struct list_head clear_list;
unsigned tt; unsigned tt;
u16 devinfo; 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 *); extern void usb_ep0_reinit(struct usb_device *);
#endif /* __LINUX_HUB_H */ #endif /* __LINUX_HUB_H */
...@@ -806,6 +806,48 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid, ...@@ -806,6 +806,48 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
return rc; 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 * usb_string - returns UTF-8 version of a string descriptor
* @dev: the device whose string descriptor is being retrieved * @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) ...@@ -837,24 +879,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
if (!tbuf) if (!tbuf)
return -ENOMEM; return -ENOMEM;
/* get langid for strings if it's not yet known */ err = usb_get_langid(dev, tbuf);
if (!dev->have_langid) { if (err < 0)
err = usb_string_sub(dev, 0, 0, tbuf); goto errout;
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_string_sub(dev, dev->string_langid, index, tbuf); err = usb_string_sub(dev, dev->string_langid, index, tbuf);
if (err < 0) if (err < 0)
......
...@@ -286,6 +286,27 @@ config USB_S3C_HSOTG ...@@ -286,6 +286,27 @@ config USB_S3C_HSOTG
default USB_GADGET default USB_GADGET
select USB_GADGET_SELECTED 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 config USB_GADGET_S3C2410
boolean "S3C2410 USB Device Controller" boolean "S3C2410 USB Device Controller"
depends on ARCH_S3C2410 depends on ARCH_S3C2410
...@@ -321,27 +342,6 @@ config USB_GADGET_MUSB_HDRC ...@@ -321,27 +342,6 @@ config USB_GADGET_MUSB_HDRC
This OTG-capable silicon IP is used in dual designs including This OTG-capable silicon IP is used in dual designs including
the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin 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 config USB_GADGET_M66592
boolean "Renesas M66592 USB Peripheral Controller" boolean "Renesas M66592 USB Peripheral Controller"
select USB_GADGET_DUALSPEED select USB_GADGET_DUALSPEED
...@@ -604,6 +604,7 @@ config USB_ZERO_HNPTEST ...@@ -604,6 +604,7 @@ config USB_ZERO_HNPTEST
config USB_AUDIO config USB_AUDIO
tristate "Audio Gadget (EXPERIMENTAL)" tristate "Audio Gadget (EXPERIMENTAL)"
depends on SND depends on SND
select SND_PCM
help help
Gadget Audio is compatible with USB Audio Class specification 1.0. Gadget Audio is compatible with USB Audio Class specification 1.0.
It will include at least one AudioControl interface, zero or more It will include at least one AudioControl interface, zero or more
......
...@@ -42,9 +42,9 @@ ...@@ -42,9 +42,9 @@
* Instead: allocate your own, using normal USB-IF procedures. * Instead: allocate your own, using normal USB-IF procedures.
*/ */
/* Thanks to NetChip Technologies for donating this product ID. */ /* Thanks to Linux Foundation for donating this product ID. */
#define AUDIO_VENDOR_NUM 0x0525 /* NetChip */ #define AUDIO_VENDOR_NUM 0x1d6b /* Linux Foundation */
#define AUDIO_PRODUCT_NUM 0xa4a1 /* Linux-USB Audio Gadget */ #define AUDIO_PRODUCT_NUM 0x0101 /* Linux-USB Audio Gadget */
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -293,15 +293,16 @@ static int __init eth_bind(struct usb_composite_dev *cdev) ...@@ -293,15 +293,16 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
/* CDC Subset */ /* CDC Subset */
eth_config_driver.label = "CDC Subset/SAFE"; eth_config_driver.label = "CDC Subset/SAFE";
device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM), device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM);
device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM), device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM);
device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; if (!has_rndis())
device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
} }
if (has_rndis()) { if (has_rndis()) {
/* RNDIS plus ECM-or-Subset */ /* RNDIS plus ECM-or-Subset */
device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM), device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM);
device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM), device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM);
device_desc.bNumConfigurations = 2; device_desc.bNumConfigurations = 2;
} }
......
...@@ -139,7 +139,7 @@ static int is_vbus_present(void) ...@@ -139,7 +139,7 @@ static int is_vbus_present(void)
{ {
struct pxa2xx_udc_mach_info *mach = the_controller->mach; 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); int value = gpio_get_value(mach->gpio_vbus);
if (mach->gpio_vbus_inverted) if (mach->gpio_vbus_inverted)
...@@ -158,7 +158,7 @@ static void pullup_off(void) ...@@ -158,7 +158,7 @@ static void pullup_off(void)
struct pxa2xx_udc_mach_info *mach = the_controller->mach; struct pxa2xx_udc_mach_info *mach = the_controller->mach;
int off_level = mach->gpio_pullup_inverted; 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); gpio_set_value(mach->gpio_pullup, off_level);
else if (mach->udc_command) else if (mach->udc_command)
mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
...@@ -169,7 +169,7 @@ static void pullup_on(void) ...@@ -169,7 +169,7 @@ static void pullup_on(void)
struct pxa2xx_udc_mach_info *mach = the_controller->mach; struct pxa2xx_udc_mach_info *mach = the_controller->mach;
int on_level = !mach->gpio_pullup_inverted; 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); gpio_set_value(mach->gpio_pullup, on_level);
else if (mach->udc_command) else if (mach->udc_command)
mach->udc_command(PXA2XX_UDC_CMD_CONNECT); mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
...@@ -1000,7 +1000,7 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active) ...@@ -1000,7 +1000,7 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active)
udc = container_of(_gadget, struct pxa25x_udc, gadget); udc = container_of(_gadget, struct pxa25x_udc, gadget);
/* not all boards support pullup control */ /* 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; return -EOPNOTSUPP;
udc->pullup = (is_active != 0); udc->pullup = (is_active != 0);
...@@ -1802,11 +1802,13 @@ pxa25x_udc_irq(int irq, void *_dev) ...@@ -1802,11 +1802,13 @@ pxa25x_udc_irq(int irq, void *_dev)
USIR0 |= tmp; USIR0 |= tmp;
handled = 1; handled = 1;
} }
#ifndef CONFIG_USB_PXA25X_SMALL
if (usir1 & tmp) { if (usir1 & tmp) {
handle_ep(&dev->ep[i+8]); handle_ep(&dev->ep[i+8]);
USIR1 |= tmp; USIR1 |= tmp;
handled = 1; handled = 1;
} }
#endif
} }
} }
...@@ -2160,7 +2162,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) ...@@ -2160,7 +2162,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
dev->dev = &pdev->dev; dev->dev = &pdev->dev;
dev->mach = pdev->dev.platform_data; 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, if ((retval = gpio_request(dev->mach->gpio_vbus,
"pxa25x_udc GPIO VBUS"))) { "pxa25x_udc GPIO VBUS"))) {
dev_dbg(&pdev->dev, dev_dbg(&pdev->dev,
...@@ -2173,7 +2175,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) ...@@ -2173,7 +2175,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
} else } else
vbus_irq = 0; vbus_irq = 0;
if (dev->mach->gpio_pullup) { if (gpio_is_valid(dev->mach->gpio_pullup)) {
if ((retval = gpio_request(dev->mach->gpio_pullup, if ((retval = gpio_request(dev->mach->gpio_pullup,
"pca25x_udc GPIO PULLUP"))) { "pca25x_udc GPIO PULLUP"))) {
dev_dbg(&pdev->dev, dev_dbg(&pdev->dev,
...@@ -2256,10 +2258,10 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) ...@@ -2256,10 +2258,10 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
#endif #endif
free_irq(irq, dev); free_irq(irq, dev);
err_irq1: err_irq1:
if (dev->mach->gpio_pullup) if (gpio_is_valid(dev->mach->gpio_pullup))
gpio_free(dev->mach->gpio_pullup); gpio_free(dev->mach->gpio_pullup);
err_gpio_pullup: err_gpio_pullup:
if (dev->mach->gpio_vbus) if (gpio_is_valid(dev->mach->gpio_vbus))
gpio_free(dev->mach->gpio_vbus); gpio_free(dev->mach->gpio_vbus);
err_gpio_vbus: err_gpio_vbus:
clk_put(dev->clk); clk_put(dev->clk);
...@@ -2294,11 +2296,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) ...@@ -2294,11 +2296,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
free_irq(LUBBOCK_USB_IRQ, dev); free_irq(LUBBOCK_USB_IRQ, dev);
} }
#endif #endif
if (dev->mach->gpio_vbus) { if (gpio_is_valid(dev->mach->gpio_vbus)) {
free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev);
gpio_free(dev->mach->gpio_vbus); 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); gpio_free(dev->mach->gpio_pullup);
clk_put(dev->clk); clk_put(dev->clk);
...@@ -2329,7 +2331,7 @@ static int pxa25x_udc_suspend(struct platform_device *dev, pm_message_t state) ...@@ -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); struct pxa25x_udc *udc = platform_get_drvdata(dev);
unsigned long flags; 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"); WARNING("USB host won't detect disconnect!\n");
udc->suspended = 1; udc->suspended = 1;
......
...@@ -442,6 +442,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, ...@@ -442,6 +442,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
case OID_802_3_MAC_OPTIONS: case OID_802_3_MAC_OPTIONS:
pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__);
*outbuf = cpu_to_le32(0);
retval = 0;
break; break;
/* ieee802.3 statistics OIDs (table 4-4) */ /* ieee802.3 statistics OIDs (table 4-4) */
......
...@@ -181,26 +181,27 @@ config USB_OHCI_HCD_PPC_SOC ...@@ -181,26 +181,27 @@ config USB_OHCI_HCD_PPC_SOC
Enables support for the USB controller on the MPC52xx or Enables support for the USB controller on the MPC52xx or
STB03xxx processor chip. If unsure, say Y. 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 config USB_OHCI_HCD_PPC_OF_BE
bool "Support big endian HC" bool "OHCI support for OF platform bus (big endian)"
depends on USB_OHCI_HCD_PPC_OF depends on USB_OHCI_HCD && PPC_OF
default y
select USB_OHCI_BIG_ENDIAN_DESC select USB_OHCI_BIG_ENDIAN_DESC
select USB_OHCI_BIG_ENDIAN_MMIO 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 config USB_OHCI_HCD_PPC_OF_LE
bool "Support little endian HC" bool "OHCI support for OF platform bus (little endian)"
depends on USB_OHCI_HCD_PPC_OF depends on USB_OHCI_HCD && PPC_OF
default n
select USB_OHCI_LITTLE_ENDIAN 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 config USB_OHCI_HCD_PCI
bool "OHCI support for PCI-bus USB controllers" bool "OHCI support for PCI-bus USB controllers"
......
...@@ -113,6 +113,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { ...@@ -113,6 +113,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
.bus_resume = ehci_bus_resume, .bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port, .relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over, .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) static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
......
...@@ -325,6 +325,8 @@ static const struct hc_driver ehci_fsl_hc_driver = { ...@@ -325,6 +325,8 @@ static const struct hc_driver ehci_fsl_hc_driver = {
.bus_resume = ehci_bus_resume, .bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port, .relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over, .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) static int ehci_fsl_drv_probe(struct platform_device *pdev)
......
...@@ -1003,6 +1003,8 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) ...@@ -1003,6 +1003,8 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
schedule_timeout_uninterruptible(1); schedule_timeout_uninterruptible(1);
goto rescan; goto rescan;
case QH_STATE_IDLE: /* fully unlinked */ case QH_STATE_IDLE: /* fully unlinked */
if (qh->clearing_tt)
goto idle_timeout;
if (list_empty (&qh->qtd_list)) { if (list_empty (&qh->qtd_list)) {
qh_put (qh); qh_put (qh);
break; break;
...@@ -1030,12 +1032,14 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) ...@@ -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_hcd *ehci = hcd_to_ehci(hcd);
struct ehci_qh *qh; struct ehci_qh *qh;
int eptype = usb_endpoint_type(&ep->desc); 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) if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
return; return;
rescan: spin_lock_irqsave(&ehci->lock, flags);
spin_lock_irq(&ehci->lock);
qh = ep->hcpriv; qh = ep->hcpriv;
/* For Bulk and Interrupt endpoints we maintain the toggle state /* 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) ...@@ -1044,29 +1048,24 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
* the toggle bit in the QH. * the toggle bit in the QH.
*/ */
if (qh) { if (qh) {
usb_settoggle(qh->dev, epnum, is_out, 0);
if (!list_empty(&qh->qtd_list)) { if (!list_empty(&qh->qtd_list)) {
WARN_ONCE(1, "clear_halt for a busy endpoint\n"); WARN_ONCE(1, "clear_halt for a busy endpoint\n");
} else if (qh->qh_state == QH_STATE_IDLE) { } else if (qh->qh_state == QH_STATE_LINKED) {
qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
} else { /* The toggle value in the QH can't be updated
/* It's not safe to write into the overlay area * while the QH is active. Unlink it now;
* while the QH is active. Unlink it first and * re-linking will call qh_refresh().
* wait for the unlink to complete.
*/ */
if (qh->qh_state == QH_STATE_LINKED) { if (eptype == USB_ENDPOINT_XFER_BULK) {
if (eptype == USB_ENDPOINT_XFER_BULK) { unlink_async(ehci, qh);
unlink_async(ehci, qh); } else {
} else { intr_deschedule(ehci, qh);
intr_deschedule(ehci, qh); (void) qh_schedule(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) static int ehci_get_frame (struct usb_hcd *hcd)
......
...@@ -61,6 +61,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = { ...@@ -61,6 +61,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = {
#endif #endif
.relinquish_port = ehci_relinquish_port, .relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over, .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) static int ixp4xx_ehci_probe(struct platform_device *pdev)
......
...@@ -165,6 +165,8 @@ static const struct hc_driver ehci_orion_hc_driver = { ...@@ -165,6 +165,8 @@ static const struct hc_driver ehci_orion_hc_driver = {
.bus_resume = ehci_bus_resume, .bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port, .relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over, .port_handed_over = ehci_port_handed_over,
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
}; };
static void __init static void __init
......
...@@ -404,6 +404,8 @@ static const struct hc_driver ehci_pci_hc_driver = { ...@@ -404,6 +404,8 @@ static const struct hc_driver ehci_pci_hc_driver = {
.bus_resume = ehci_bus_resume, .bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port, .relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over, .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 = { ...@@ -79,6 +79,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
#endif #endif
.relinquish_port = ehci_relinquish_port, .relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over, .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 = { ...@@ -75,6 +75,8 @@ static const struct hc_driver ps3_ehci_hc_driver = {
#endif #endif
.relinquish_port = ehci_relinquish_port, .relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over, .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) 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) ...@@ -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_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
qh->hw_alt_next = EHCI_LIST_END(ehci); 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 */ /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
wmb (); wmb ();
qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); 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) ...@@ -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 ( static int qtd_copy_status (
struct ehci_hcd *ehci, struct ehci_hcd *ehci,
struct urb *urb, struct urb *urb,
...@@ -149,6 +214,14 @@ static int qtd_copy_status ( ...@@ -149,6 +214,14 @@ static int qtd_copy_status (
if (token & QTD_STS_BABBLE) { if (token & QTD_STS_BABBLE) {
/* FIXME "must" disable babbling device's port too */ /* FIXME "must" disable babbling device's port too */
status = -EOVERFLOW; 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) { } else if (token & QTD_STS_MMF) {
/* fs/ls interrupt xfer missed the complete-split */ /* fs/ls interrupt xfer missed the complete-split */
status = -EPROTO; status = -EPROTO;
...@@ -157,21 +230,15 @@ static int qtd_copy_status ( ...@@ -157,21 +230,15 @@ static int qtd_copy_status (
? -ENOSR /* hc couldn't read data */ ? -ENOSR /* hc couldn't read data */
: -ECOMM; /* hc couldn't write data */ : -ECOMM; /* hc couldn't write data */
} else if (token & QTD_STS_XACT) { } else if (token & QTD_STS_XACT) {
/* timeout, bad crc, wrong PID, etc; retried */ /* timeout, bad CRC, wrong PID, etc */
if (QTD_CERR (token)) ehci_dbg(ehci, "devpath %s ep%d%s 3strikes\n",
status = -EPIPE; urb->dev->devpath,
else { usb_pipeendpoint(urb->pipe),
ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n", usb_pipein(urb->pipe) ? "in" : "out");
urb->dev->devpath, status = -EPROTO;
usb_pipeendpoint (urb->pipe), } else { /* unknown */
usb_pipein (urb->pipe) ? "in" : "out");
status = -EPROTO;
}
/* CERR nonzero + no errors + halt --> stall */
} else if (QTD_CERR (token))
status = -EPIPE;
else /* unknown */
status = -EPROTO; status = -EPROTO;
}
ehci_vdbg (ehci, ehci_vdbg (ehci,
"dev%d ep%d%s qtd token %08x --> status %d\n", "dev%d ep%d%s qtd token %08x --> status %d\n",
...@@ -179,28 +246,6 @@ static int qtd_copy_status ( ...@@ -179,28 +246,6 @@ static int qtd_copy_status (
usb_pipeendpoint (urb->pipe), usb_pipeendpoint (urb->pipe),
usb_pipein (urb->pipe) ? "in" : "out", usb_pipein (urb->pipe) ? "in" : "out",
token, status); 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; return status;
...@@ -391,9 +436,16 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) ...@@ -391,9 +436,16 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
/* qh unlinked; token in overlay may be most current */ /* qh unlinked; token in overlay may be most current */
if (state == QH_STATE_IDLE if (state == QH_STATE_IDLE
&& cpu_to_hc32(ehci, qtd->qtd_dma) && cpu_to_hc32(ehci, qtd->qtd_dma)
== qh->hw_current) == qh->hw_current) {
token = hc32_to_cpu(ehci, qh->hw_token); 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 /* force halt for unlinked or blocked qh, so we'll
* patch the qh later and so that completions can't * patch the qh later and so that completions can't
* activate it while we "know" it's stopped. * activate it while we "know" it's stopped.
...@@ -419,6 +471,13 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) ...@@ -419,6 +471,13 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
&& (qtd->hw_alt_next && (qtd->hw_alt_next
& EHCI_LIST_END(ehci))) & EHCI_LIST_END(ehci)))
last_status = -EINPROGRESS; 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, /* if we're removing something not at the queue head,
...@@ -834,6 +893,7 @@ qh_make ( ...@@ -834,6 +893,7 @@ qh_make (
qh->qh_state = QH_STATE_IDLE; qh->qh_state = QH_STATE_IDLE;
qh->hw_info1 = cpu_to_hc32(ehci, info1); qh->hw_info1 = cpu_to_hc32(ehci, info1);
qh->hw_info2 = cpu_to_hc32(ehci, info2); qh->hw_info2 = cpu_to_hc32(ehci, info2);
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
qh_refresh (ehci, qh); qh_refresh (ehci, qh);
return qh; return qh;
} }
...@@ -847,6 +907,10 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *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); __hc32 dma = QH_NEXT(ehci, qh->qh_dma);
struct ehci_qh *head; 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? */ /* (re)start the async schedule? */
head = ehci->async; head = ehci->async;
timer_action_done (ehci, TIMER_ASYNC_OFF); timer_action_done (ehci, TIMER_ASYNC_OFF);
...@@ -864,7 +928,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) ...@@ -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) if (qh->qh_state == QH_STATE_IDLE)
qh_refresh (ehci, qh); qh_refresh (ehci, qh);
......
...@@ -1619,11 +1619,14 @@ itd_complete ( ...@@ -1619,11 +1619,14 @@ itd_complete (
desc->status = -EPROTO; desc->status = -EPROTO;
/* HC need not update length with this error */ /* HC need not update length with this error */
if (!(t & EHCI_ISOC_BABBLE)) if (!(t & EHCI_ISOC_BABBLE)) {
desc->actual_length = EHCI_ITD_LENGTH (t); desc->actual_length = EHCI_ITD_LENGTH(t);
urb->actual_length += desc->actual_length;
}
} else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
desc->status = 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 { } else {
/* URB was too late */ /* URB was too late */
desc->status = -EXDEV; desc->status = -EXDEV;
...@@ -2014,7 +2017,8 @@ sitd_complete ( ...@@ -2014,7 +2017,8 @@ sitd_complete (
desc->status = -EPROTO; desc->status = -EPROTO;
} else { } else {
desc->status = 0; 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; stream->depth -= stream->interval << 3;
......
...@@ -354,7 +354,9 @@ struct ehci_qh { ...@@ -354,7 +354,9 @@ struct ehci_qh {
unsigned short period; /* polling interval */ unsigned short period; /* polling interval */
unsigned short start; /* where polling starts */ unsigned short start; /* where polling starts */
#define NO_FRAME ((unsigned short)~0) /* pick new start */ #define NO_FRAME ((unsigned short)~0) /* pick new start */
struct usb_device *dev; /* access to TT */ struct usb_device *dev; /* access to TT */
unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
} __attribute__ ((aligned (32))); } __attribute__ ((aligned (32)));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -576,9 +576,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) ...@@ -576,9 +576,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
out_be16(&usb->fhci->regs->usb_event, out_be16(&usb->fhci->regs->usb_event,
usb->saved_msk); usb->saved_msk);
} else if (usb->port_status == FHCI_PORT_DISABLED) { } else if (usb->port_status == FHCI_PORT_DISABLED) {
if (fhci_ioports_check_bus_state(fhci) == 1 && if (fhci_ioports_check_bus_state(fhci) == 1)
usb->port_status != FHCI_PORT_LOW &&
usb->port_status != FHCI_PORT_FULL)
fhci_device_connected_interrupt(fhci); fhci_device_connected_interrupt(fhci);
} }
usb_er &= ~USB_E_RESET_MASK; usb_er &= ~USB_E_RESET_MASK;
...@@ -605,9 +603,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) ...@@ -605,9 +603,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
} }
if (usb_er & USB_E_IDLE_MASK) { if (usb_er & USB_E_IDLE_MASK) {
if (usb->port_status == FHCI_PORT_DISABLED && if (usb->port_status == FHCI_PORT_DISABLED) {
usb->port_status != FHCI_PORT_LOW &&
usb->port_status != FHCI_PORT_FULL) {
usb_er &= ~USB_E_RESET_MASK; usb_er &= ~USB_E_RESET_MASK;
fhci_device_connected_interrupt(fhci); fhci_device_connected_interrupt(fhci);
} else if (usb->port_status == } else if (usb->port_status ==
......
...@@ -361,7 +361,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev) ...@@ -361,7 +361,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev)
static struct platform_driver isp1760_plat_driver = { static struct platform_driver isp1760_plat_driver = {
.probe = isp1760_plat_probe, .probe = isp1760_plat_probe,
.remove = isp1760_plat_remove, .remove = __devexit_p(isp1760_plat_remove),
.driver = { .driver = {
.name = "isp1760", .name = "isp1760",
}, },
......
...@@ -35,13 +35,14 @@ ...@@ -35,13 +35,14 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/memory.h> #include <mach/memory.h>
#include <mach/gpio.h> #include <mach/gpio.h>
#include <mach/cputype.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include "musb_core.h" #include "musb_core.h"
#ifdef CONFIG_MACH_DAVINCI_EVM #ifdef CONFIG_MACH_DAVINCI_EVM
#define GPIO_nVBUS_DRV 87 #define GPIO_nVBUS_DRV 144
#endif #endif
#include "davinci.h" #include "davinci.h"
...@@ -329,7 +330,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) ...@@ -329,7 +330,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
WARNING("VBUS error workaround (delay coming)\n"); WARNING("VBUS error workaround (delay coming)\n");
} else if (is_host_enabled(musb) && drvvbus) { } else if (is_host_enabled(musb) && drvvbus) {
musb->is_active = 1;
MUSB_HST_MODE(musb); MUSB_HST_MODE(musb);
musb->xceiv->default_a = 1; musb->xceiv->default_a = 1;
musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
...@@ -343,7 +343,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) ...@@ -343,7 +343,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); 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); davinci_source_power(musb, drvvbus, 0);
DBG(2, "VBUS %s (%s)%s, devctl %02x\n", DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
drvvbus ? "on" : "off", drvvbus ? "on" : "off",
...@@ -411,6 +413,21 @@ int __init musb_platform_init(struct musb *musb) ...@@ -411,6 +413,21 @@ int __init musb_platform_init(struct musb *musb)
__raw_writel(phy_ctrl, USB_PHY_CTRL); __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 */ /* reset the controller */
musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
...@@ -437,6 +454,15 @@ int musb_platform_exit(struct musb *musb) ...@@ -437,6 +454,15 @@ int musb_platform_exit(struct musb *musb)
if (is_host_enabled(musb)) if (is_host_enabled(musb))
del_timer_sync(&otg_workaround); 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); davinci_source_power(musb, 0 /*off*/, 1);
/* delay, to avoid problems with module reload */ /* delay, to avoid problems with module reload */
......
...@@ -373,7 +373,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, ...@@ -373,7 +373,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb,
musb_save_toggle(qh, is_in, urb); musb_save_toggle(qh, is_in, urb);
break; break;
case USB_ENDPOINT_XFER_ISOC: case USB_ENDPOINT_XFER_ISOC:
if (urb->error_count) if (status == 0 && urb->error_count)
status = -EXDEV; status = -EXDEV;
break; break;
} }
...@@ -2235,13 +2235,30 @@ static void musb_h_stop(struct usb_hcd *hcd) ...@@ -2235,13 +2235,30 @@ static void musb_h_stop(struct usb_hcd *hcd)
static int musb_bus_suspend(struct usb_hcd *hcd) static int musb_bus_suspend(struct usb_hcd *hcd)
{ {
struct musb *musb = hcd_to_musb(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; return 0;
if (is_host_active(musb) && musb->is_active) { switch (musb->xceiv->state) {
WARNING("trying to suspend as %s is_active=%i\n", case OTG_STATE_A_SUSPEND:
otg_state_string(musb), musb->is_active); 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; return -EBUSY;
} else } else
return 0; return 0;
......
...@@ -59,18 +59,4 @@ config NOP_USB_XCEIV ...@@ -59,18 +59,4 @@ config NOP_USB_XCEIV
built-in with usb ip or which are autonomous and doesn't require any built-in with usb ip or which are autonomous and doesn't require any
phy programming such as ISP1x04 etc. 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 endif # USB || OTG
...@@ -9,7 +9,6 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o ...@@ -9,7 +9,6 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o
obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o
obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
obj-$(CONFIG_TWL4030_USB) += twl4030-usb.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 obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o
ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG
......
This diff is collapsed.
...@@ -53,6 +53,7 @@ EXPORT_SYMBOL(usb_nop_xceiv_register); ...@@ -53,6 +53,7 @@ EXPORT_SYMBOL(usb_nop_xceiv_register);
void usb_nop_xceiv_unregister(void) void usb_nop_xceiv_unregister(void)
{ {
platform_device_unregister(pd); platform_device_unregister(pd);
pd = NULL;
} }
EXPORT_SYMBOL(usb_nop_xceiv_unregister); EXPORT_SYMBOL(usb_nop_xceiv_unregister);
......
...@@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options) ...@@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options)
kfree(tty); kfree(tty);
} }
} }
/* So we know not to kill the hardware on a hangup on this /* Now that any required fake tty operations are completed restore
port. We have also bumped the use count by one so it won't go * the tty port count */
idle */ --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; port->console = 1;
retval = 0; retval = 0;
...@@ -204,7 +206,7 @@ static void usb_console_write(struct console *co, ...@@ -204,7 +206,7 @@ static void usb_console_write(struct console *co,
dbg("%s - port %d, %d byte(s)", __func__, port->number, count); dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
if (!port->port.count) { if (!port->console) {
dbg("%s - port not opened", __func__); dbg("%s - port not opened", __func__);
return; return;
} }
...@@ -300,8 +302,7 @@ void usb_serial_console_exit(void) ...@@ -300,8 +302,7 @@ void usb_serial_console_exit(void)
{ {
if (usbcons_info.port) { if (usbcons_info.port) {
unregister_console(&usbcons); unregister_console(&usbcons);
if (usbcons_info.port->port.count) usbcons_info.port->console = 0;
usbcons_info.port->port.count--;
usbcons_info.port = NULL; usbcons_info.port = NULL;
} }
} }
......
...@@ -67,6 +67,8 @@ static struct usb_device_id id_table [] = { ...@@ -67,6 +67,8 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
{ USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
{ USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */ { 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, 0x800A) }, /* SPORTident BSM7-D-USB main station */
{ USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
{ USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
......
...@@ -1228,8 +1228,8 @@ static void cypress_read_int_callback(struct urb *urb) ...@@ -1228,8 +1228,8 @@ static void cypress_read_int_callback(struct urb *urb)
/* precursor to disconnect so just go away */ /* precursor to disconnect so just go away */
return; return;
case -EPIPE: case -EPIPE:
usb_clear_halt(port->serial->dev, 0x81); /* Can't call usb_clear_halt while in_interrupt */
break; /* FALLS THROUGH */
default: default:
/* something ugly is going on... */ /* something ugly is going on... */
dev_err(&urb->dev->dev, dev_err(&urb->dev->dev,
......
...@@ -108,6 +108,7 @@ struct ftdi_sio_quirk { ...@@ -108,6 +108,7 @@ struct ftdi_sio_quirk {
static int ftdi_jtag_probe(struct usb_serial *serial); static int ftdi_jtag_probe(struct usb_serial *serial);
static int ftdi_mtxorb_hack_setup(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_USB_UIRT_setup(struct ftdi_private *priv);
static void ftdi_HE_TIRA1_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 = { ...@@ -119,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = {
.probe = ftdi_mtxorb_hack_setup, .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 = { static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
.port_probe = ftdi_USB_UIRT_setup, .port_probe = ftdi_USB_UIRT_setup,
}; };
...@@ -192,6 +197,7 @@ static struct usb_device_id id_table_combined [] = { ...@@ -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_4_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_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_0100_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
...@@ -580,6 +586,9 @@ static struct usb_device_id id_table_combined [] = { ...@@ -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_CCSICDU20_0_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_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(FTDI_VID, INSIDE_ACCESSO) },
{ USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
{ USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
...@@ -645,6 +654,16 @@ static struct usb_device_id id_table_combined [] = { ...@@ -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_13S_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_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(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
...@@ -661,6 +680,8 @@ static struct usb_device_id id_table_combined [] = { ...@@ -661,6 +680,8 @@ static struct usb_device_id id_table_combined [] = {
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, .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(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
{ USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
{ USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
...@@ -668,7 +689,6 @@ static struct usb_device_id id_table_combined [] = { ...@@ -668,7 +689,6 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
{ USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
{ USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_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(ATMEL_VID, STK541_PID) },
{ USB_DEVICE(DE_VID, STB_PID) }, { USB_DEVICE(DE_VID, STB_PID) },
{ USB_DEVICE(DE_VID, WHT_PID) }, { USB_DEVICE(DE_VID, WHT_PID) },
...@@ -1024,6 +1044,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, ...@@ -1024,6 +1044,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
case FT2232C: /* FT2232C chip */ case FT2232C: /* FT2232C chip */
case FT232RL: case FT232RL:
if (baud <= 3000000) { 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); div_value = ftdi_232bm_baud_to_divisor(baud);
} else { } else {
dbg("%s - Baud rate too high!", __func__); dbg("%s - Baud rate too high!", __func__);
...@@ -1554,6 +1584,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) ...@@ -1554,6 +1584,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
priv->force_rtscts = 1; priv->force_rtscts = 1;
} /* ftdi_HE_TIRA1_setup */ } /* 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 * 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 * 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=" ...@@ -2623,3 +2686,5 @@ MODULE_PARM_DESC(vendor, "User specified vendor ID (default="
module_param(product, ushort, 0); module_param(product, ushort, 0);
MODULE_PARM_DESC(product, "User specified product ID"); 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 @@ ...@@ -506,6 +506,7 @@
* *
* Armin Laeuger originally sent the PID for the UM 100 module. * 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_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */
#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ #define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */
#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ #define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */
...@@ -614,6 +615,9 @@ ...@@ -614,6 +615,9 @@
#define FTDI_CCSICDU20_0_PID 0xF9D0 #define FTDI_CCSICDU20_0_PID 0xF9D0
#define FTDI_CCSICDU40_1_PID 0xF9D1 #define FTDI_CCSICDU40_1_PID 0xF9D1
#define FTDI_CCSMACHX_2_PID 0xF9D2 #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) */ /* Inside Accesso contactless reader (http://www.insidefr.com) */
#define INSIDE_ACCESSO 0xFAD0 #define INSIDE_ACCESSO 0xFAD0
...@@ -735,6 +739,15 @@ ...@@ -735,6 +739,15 @@
/* Pyramid Computer GmbH */ /* Pyramid Computer GmbH */
#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ #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) * Posiflex inc retail equipment (http://www.posiflex.com.tw)
*/ */
...@@ -848,9 +861,6 @@ ...@@ -848,9 +861,6 @@
#define TML_VID 0x1B91 /* Vendor ID */ #define TML_VID 0x1B91 /* Vendor ID */
#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */
/* NDI Polaris System */
#define FTDI_NDI_HUC_PID 0xDA70
/* Propox devices */ /* Propox devices */
#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
...@@ -934,6 +944,8 @@ ...@@ -934,6 +944,8 @@
#define MARVELL_VID 0x9e88 #define MARVELL_VID 0x9e88
#define MARVELL_SHEEVAPLUG_PID 0x9e8f #define MARVELL_SHEEVAPLUG_PID 0x9e8f
#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */
/* /*
* BmRequestType: 1100 0000b * BmRequestType: 1100 0000b
* bRequest: FTDI_E2_READ * bRequest: FTDI_E2_READ
......
...@@ -206,6 +206,7 @@ static int option_resume(struct usb_serial *serial); ...@@ -206,6 +206,7 @@ static int option_resume(struct usb_serial *serial);
#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400
#define NOVATELWIRELESS_PRODUCT_U727 0x5010 #define NOVATELWIRELESS_PRODUCT_U727 0x5010
#define NOVATELWIRELESS_PRODUCT_MC760 0x6000 #define NOVATELWIRELESS_PRODUCT_MC760 0x6000
#define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002
/* FUTURE NOVATEL PRODUCTS */ /* FUTURE NOVATEL PRODUCTS */
#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001
...@@ -307,11 +308,20 @@ static int option_resume(struct usb_serial *serial); ...@@ -307,11 +308,20 @@ static int option_resume(struct usb_serial *serial);
#define DLINK_VENDOR_ID 0x1186 #define DLINK_VENDOR_ID 0x1186
#define DLINK_PRODUCT_DWM_652 0x3e04 #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 */ /* TOSHIBA PRODUCTS */
#define TOSHIBA_VENDOR_ID 0x0930 #define TOSHIBA_VENDOR_ID 0x0930
#define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 #define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302
#define ALINK_VENDOR_ID 0x1e0e
#define ALINK_PRODUCT_3GU 0x9200
static struct usb_device_id option_ids[] = { static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
...@@ -430,6 +440,7 @@ static struct usb_device_id option_ids[] = { ...@@ -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_MC727) }, /* Novatel MC727/U727/USB727 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* 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_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_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_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA 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[] = { ...@@ -529,8 +540,13 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, { 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(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 */ { } /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(usb, option_ids); MODULE_DEVICE_TABLE(usb, option_ids);
...@@ -732,7 +748,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port, ...@@ -732,7 +748,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
memcpy(this_urb->transfer_buffer, buf, todo); memcpy(this_urb->transfer_buffer, buf, todo);
this_urb->transfer_buffer_length = todo; this_urb->transfer_buffer_length = todo;
this_urb->dev = port->serial->dev;
err = usb_submit_urb(this_urb, GFP_ATOMIC); err = usb_submit_urb(this_urb, GFP_ATOMIC);
if (err) { if (err) {
dbg("usb_submit_urb %p (write bulk) failed " dbg("usb_submit_urb %p (write bulk) failed "
...@@ -860,7 +875,6 @@ static void option_instat_callback(struct urb *urb) ...@@ -860,7 +875,6 @@ static void option_instat_callback(struct urb *urb)
/* Resubmit urb so we continue receiving IRQ data */ /* Resubmit urb so we continue receiving IRQ data */
if (status != -ESHUTDOWN && status != -ENOENT) { if (status != -ESHUTDOWN && status != -ENOENT) {
urb->dev = serial->dev;
err = usb_submit_urb(urb, GFP_ATOMIC); err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) if (err)
dbg("%s: resubmit intr urb failed. (%d)", dbg("%s: resubmit intr urb failed. (%d)",
...@@ -921,23 +935,11 @@ static int option_open(struct tty_struct *tty, ...@@ -921,23 +935,11 @@ static int option_open(struct tty_struct *tty,
dbg("%s", __func__); 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++) { for (i = 0; i < N_IN_URB; i++) {
urb = portdata->in_urbs[i]; urb = portdata->in_urbs[i];
if (!urb) if (!urb)
continue; 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); err = usb_submit_urb(urb, GFP_KERNEL);
if (err) { if (err) {
dbg("%s: submit urb %d failed (%d) %d", dbg("%s: submit urb %d failed (%d) %d",
...@@ -946,16 +948,6 @@ static int option_open(struct tty_struct *tty, ...@@ -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); option_send_setup(port);
return 0; return 0;
...@@ -1218,7 +1210,6 @@ static int option_resume(struct usb_serial *serial) ...@@ -1218,7 +1210,6 @@ static int option_resume(struct usb_serial *serial)
dbg("%s: No interrupt URB for port %d\n", __func__, i); dbg("%s: No interrupt URB for port %d\n", __func__, i);
continue; continue;
} }
port->interrupt_in_urb->dev = serial->dev;
err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
dbg("Submitted interrupt URB for port %d (result %d)", i, err); dbg("Submitted interrupt URB for port %d (result %d)", i, err);
if (err < 0) { if (err < 0) {
......
...@@ -94,6 +94,7 @@ static struct usb_device_id id_table [] = { ...@@ -94,6 +94,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -122,3 +122,7 @@ ...@@ -122,3 +122,7 @@
/* Hewlett-Packard LD220-HP POS Pole Display */ /* Hewlett-Packard LD220-HP POS Pole Display */
#define HP_VENDOR_ID 0x03f0 #define HP_VENDOR_ID 0x03f0
#define HP_LD220_PRODUCT_ID 0x3524 #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 = { ...@@ -181,35 +181,50 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = {
}; };
static struct usb_device_id id_table [] = { 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, 0x0017) }, /* Sierra Wireless EM5625 */
{ USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0218) }, /* 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, 0x0020) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
{ USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ { 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, 0x0019) }, /* Sierra Wireless AirCard 595 */
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ { 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 */ { 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) }, { 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_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
{ USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */ { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */
{ USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */ { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */
{ USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */ { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */
{ USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
{ USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ { 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, 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(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, 0x6820) }, /* Sierra Wireless AirCard 875 */
{ USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ { 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, 0x6832) }, /* Sierra Wireless MC8780 */
{ USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ { 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, 0x683A) }, /* Sierra Wireless MC8785 */
{ USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
/* Sierra Wireless MC8790, MC8791, MC8792 Composite */ /* Sierra Wireless MC8790, MC8791, MC8792 Composite */
...@@ -227,16 +242,13 @@ static struct usb_device_id id_table [] = { ...@@ -227,16 +242,13 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
/* Sierra Wireless C885 */ /* Sierra Wireless C885 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, { 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)}, { 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)}, { 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_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
{ USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
{ USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
{ USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
{ USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */
.driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
}, },
...@@ -814,7 +826,7 @@ static int sierra_startup(struct usb_serial *serial) ...@@ -814,7 +826,7 @@ static int sierra_startup(struct usb_serial *serial)
return 0; return 0;
} }
static void sierra_disconnect(struct usb_serial *serial) static void sierra_release(struct usb_serial *serial)
{ {
int i; int i;
struct usb_serial_port *port; struct usb_serial_port *port;
...@@ -830,7 +842,6 @@ static void sierra_disconnect(struct usb_serial *serial) ...@@ -830,7 +842,6 @@ static void sierra_disconnect(struct usb_serial *serial)
if (!portdata) if (!portdata)
continue; continue;
kfree(portdata); kfree(portdata);
usb_set_serial_port_data(port, NULL);
} }
} }
...@@ -853,7 +864,7 @@ static struct usb_serial_driver sierra_device = { ...@@ -853,7 +864,7 @@ static struct usb_serial_driver sierra_device = {
.tiocmget = sierra_tiocmget, .tiocmget = sierra_tiocmget,
.tiocmset = sierra_tiocmset, .tiocmset = sierra_tiocmset,
.attach = sierra_startup, .attach = sierra_startup,
.disconnect = sierra_disconnect, .release = sierra_release,
.read_int_callback = sierra_instat_callback, .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] = { ...@@ -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_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_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] = { 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, ...@@ -1658,7 +1657,7 @@ static int ti_do_download(struct usb_device *dev, int pipe,
u8 cs = 0; u8 cs = 0;
int done; int done;
struct ti_firmware_header *header; struct ti_firmware_header *header;
int status; int status = 0;
int len; int len;
for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) 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) ...@@ -221,7 +221,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
tty->driver_data = port; tty->driver_data = port;
tty_port_tty_set(&port->port, tty); 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 /* lock this module before we call it
* this may fail, which means we must bail out, * this may fail, which means we must bail out,
......
...@@ -118,6 +118,9 @@ static int option_inquiry(struct us_data *us) ...@@ -118,6 +118,9 @@ static int option_inquiry(struct us_data *us)
result = memcmp(buffer+8, "Option", 6); result = memcmp(buffer+8, "Option", 6);
if (result != 0)
result = memcmp(buffer+8, "ZCOPTION", 8);
/* Read the CSW */ /* Read the CSW */
usb_stor_bulk_transfer_buf(us, usb_stor_bulk_transfer_buf(us,
us->recv_bulk_pipe, us->recv_bulk_pipe,
......
...@@ -888,8 +888,6 @@ struct usb_driver { ...@@ -888,8 +888,6 @@ struct usb_driver {
* struct usb_device_driver - identifies USB device driver to usbcore * struct usb_device_driver - identifies USB device driver to usbcore
* @name: The driver name should be unique among USB drivers, * @name: The driver name should be unique among USB drivers,
* and should normally be the same as the module name. * 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 * @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() * device. If it is, probe returns zero and uses dev_set_drvdata()
* to associate driver-specific data with the device. If unwilling * to associate driver-specific data with the device. If unwilling
...@@ -924,6 +922,8 @@ extern struct bus_type usb_bus_type; ...@@ -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 * 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. * @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. * @fops: pointer to the struct file_operations of this driver.
* @minor_base: the start of the minor range for this driver. * @minor_base: the start of the minor range for this driver.
* *
...@@ -1046,6 +1046,8 @@ typedef void (*usb_complete_t)(struct urb *); ...@@ -1046,6 +1046,8 @@ typedef void (*usb_complete_t)(struct urb *);
* the device driver is saying that it provided this DMA address, * the device driver is saying that it provided this DMA address,
* which the host controller driver should use in preference to the * which the host controller driver should use in preference to the
* transfer_buffer. * 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 * @transfer_buffer_length: How big is transfer_buffer. The transfer may
* be broken up into chunks according to the current maximum packet * be broken up into chunks according to the current maximum packet
* size for the endpoint, which is a function of the configuration * size for the endpoint, which is a function of the configuration
......
/*
* 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__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment