Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (21 commits)
  USB: musb: fix srp sysfs entry deletion
  USB: musb: resume suspended root hub on disconnect
  USB: musb: use right poll limit for low speed devices
  USB: musb: be careful with 64K+ transfer lengths, host side
  USB: musb: fix data toggle saving with shared FIFO
  USB: musb: host endpoint_disable() oops fixes
  USB: musb: fix urb_dequeue() method
  USB: musb: fix musb_host_tx() for shared endpoint FIFO
  USB: musb: be careful with 64K+ transfer lengths (gadget side)
  usb: musb: make Davinci *work* in mainline
  USB: usb_get_string should check the descriptor type
  USB: gadget: fix build error in omap_apollon_2420_defconfig
  USB: g_file_storage: automatically disable stalls under Atmel
  USB: usb-storage: add IGNORE_RESIDUE flag for Genesys Logic adapters
  USB: Quirk for Hummingbird huc56s / Conexant ACM modem
  USB: serial: add support for second revision of Ericsson F3507G WWAN card
  USB: cdc-acm: add usb id for motomagx phones
  USB: option: add BenQ 3g modem information
  usb: gadget: obex: select correct ep descriptors
  USB: EHCI: slow down ITD reuse
  ...
  • Loading branch information
Linus Torvalds committed Feb 28, 2009
2 parents 7187adb + e747951 commit 3c4f115
Show file tree
Hide file tree
Showing 19 changed files with 176 additions and 75 deletions.
6 changes: 3 additions & 3 deletions arch/arm/mach-davinci/board-evm.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
gpio_request(gpio + 7, "nCF_SEL");
gpio_direction_output(gpio + 7, 1);

/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
setup_usb(500, 8);

return 0;
}

Expand Down Expand Up @@ -417,9 +420,6 @@ static __init void davinci_evm_init(void)
platform_add_devices(davinci_evm_devices,
ARRAY_SIZE(davinci_evm_devices));
evm_init_i2c();

/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
setup_usb(500, 8);
}

static __init void davinci_evm_irq_init(void)
Expand Down
5 changes: 5 additions & 0 deletions arch/arm/mach-davinci/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,11 @@ static struct clk davinci_clks[] = {
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_GPIO,
},
{
.name = "usb",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_USB,
},
{
.name = "AEMIFCLK",
.rate = &commonrate,
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-davinci/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ static struct musb_hdrc_platform_data usb_data = {
#elif defined(CONFIG_USB_MUSB_HOST)
.mode = MUSB_HOST,
#endif
.clock = "usb",
.config = &musb_config,
};

Expand Down
9 changes: 9 additions & 0 deletions drivers/usb/class/cdc-acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,15 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
{ USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
},
{ USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
.driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on
data interface instead of
communications interface.
Maybe we should define a new
quirk for this. */
},

/* control interfaces with various AT-command sets */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
Expand Down
11 changes: 8 additions & 3 deletions drivers/usb/core/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type,
if (result <= 0 && result != -ETIMEDOUT)
continue;
if (result > 1 && ((u8 *)buf)[1] != type) {
result = -EPROTO;
result = -ENODATA;
continue;
}
break;
Expand Down Expand Up @@ -696,8 +696,13 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid,
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(USB_DT_STRING << 8) + index, langid, buf, size,
USB_CTRL_GET_TIMEOUT);
if (!(result == 0 || result == -EPIPE))
break;
if (result == 0 || result == -EPIPE)
continue;
if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) {
result = -ENODATA;
continue;
}
break;
}
return result;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/gadget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ config USB_GADGET_OMAP
boolean "OMAP USB Device Controller"
depends on ARCH_OMAP
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG
select USB_OTG_UTILS if ARCH_OMAP
help
Many Texas Instruments OMAP processors have flexible full
speed USB device controllers, with support for up to 30
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/gadget/f_obex.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,9 @@ obex_bind(struct usb_configuration *c, struct usb_function *f)
f->hs_descriptors = usb_copy_descriptors(hs_function);

obex->hs.obex_in = usb_find_endpoint(hs_function,
f->descriptors, &obex_hs_ep_in_desc);
f->hs_descriptors, &obex_hs_ep_in_desc);
obex->hs.obex_out = usb_find_endpoint(hs_function,
f->descriptors, &obex_hs_ep_out_desc);
f->hs_descriptors, &obex_hs_ep_out_desc);
}

/* Avoid letting this gadget enumerate until the userspace
Expand Down
6 changes: 5 additions & 1 deletion drivers/usb/gadget/file_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -3879,7 +3879,11 @@ static int __init check_parameters(struct fsg_dev *fsg)
mod_data.protocol_type = USB_SC_SCSI;
mod_data.protocol_name = "Transparent SCSI";

if (gadget_is_sh(fsg->gadget))
/* Some peripheral controllers are known not to be able to
* halt bulk endpoints correctly. If one of them is present,
* disable stalls.
*/
if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget))
mod_data.can_stall = 0;

if (mod_data.release == 0xffff) { // Parameter wasn't set
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/gadget/fsl_usb2_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,10 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num,
}
if (zlt)
tmp |= EP_QUEUE_HEAD_ZLT_SEL;

p_QH->max_pkt_length = cpu_to_le32(tmp);
p_QH->next_dtd_ptr = 1;
p_QH->size_ioc_int_sts = 0;

return;
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ static int ehci_init(struct usb_hcd *hcd)
* periodic_size can shrink by USBCMD update if hcc_params allows.
*/
ehci->periodic_size = DEFAULT_I_TDPS;
INIT_LIST_HEAD(&ehci->cached_itd_list);
if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
return retval;

Expand All @@ -497,6 +498,7 @@ static int ehci_init(struct usb_hcd *hcd)

ehci->reclaim = NULL;
ehci->next_uframe = -1;
ehci->clock_frame = -1;

/*
* dedicate a qh for the async ring head, since we couldn't unlink
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/host/ehci-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ static inline void qh_put (struct ehci_qh *qh)

static void ehci_mem_cleanup (struct ehci_hcd *ehci)
{
free_cached_itd_list(ehci);
if (ehci->async)
qh_put (ehci->async);
ehci->async = NULL;
Expand Down
56 changes: 48 additions & 8 deletions drivers/usb/host/ehci-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,8 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)

is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0;
stream->bEndpointAddress &= 0x0f;
stream->ep->hcpriv = NULL;
if (stream->ep)
stream->ep->hcpriv = NULL;

if (stream->rescheduled) {
ehci_info (ehci, "ep%d%s-iso rescheduled "
Expand Down Expand Up @@ -1653,14 +1654,28 @@ itd_complete (
(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
}
iso_stream_put (ehci, stream);
/* OK to recycle this ITD now that its completion callback ran. */

done:
usb_put_urb(urb);
itd->urb = NULL;
itd->stream = NULL;
list_move(&itd->itd_list, &stream->free_list);
iso_stream_put(ehci, stream);

if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
/* OK to recycle this ITD now. */
itd->stream = NULL;
list_move(&itd->itd_list, &stream->free_list);
iso_stream_put(ehci, stream);
} else {
/* HW might remember this ITD, so we can't recycle it yet.
* Move it to a safe place until a new frame starts.
*/
list_move(&itd->itd_list, &ehci->cached_itd_list);
if (stream->refcount == 2) {
/* If iso_stream_put() were called here, stream
* would be freed. Instead, just prevent reuse.
*/
stream->ep->hcpriv = NULL;
stream->ep = NULL;
}
}
return retval;
}

Expand Down Expand Up @@ -2101,6 +2116,20 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,

/*-------------------------------------------------------------------------*/

static void free_cached_itd_list(struct ehci_hcd *ehci)
{
struct ehci_itd *itd, *n;

list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
struct ehci_iso_stream *stream = itd->stream;
itd->stream = NULL;
list_move(&itd->itd_list, &stream->free_list);
iso_stream_put(ehci, stream);
}
}

/*-------------------------------------------------------------------------*/

static void
scan_periodic (struct ehci_hcd *ehci)
{
Expand All @@ -2115,10 +2144,17 @@ scan_periodic (struct ehci_hcd *ehci)
* Touches as few pages as possible: cache-friendly.
*/
now_uframe = ehci->next_uframe;
if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
clock = ehci_readl(ehci, &ehci->regs->frame_index);
else
clock_frame = (clock >> 3) % ehci->periodic_size;
} else {
clock = now_uframe + mod - 1;
clock_frame = -1;
}
if (ehci->clock_frame != clock_frame) {
free_cached_itd_list(ehci);
ehci->clock_frame = clock_frame;
}
clock %= mod;
clock_frame = clock >> 3;

Expand Down Expand Up @@ -2277,6 +2313,10 @@ scan_periodic (struct ehci_hcd *ehci)
/* rescan the rest of this frame, then ... */
clock = now;
clock_frame = clock >> 3;
if (ehci->clock_frame != clock_frame) {
free_cached_itd_list(ehci);
ehci->clock_frame = clock_frame;
}
} else {
now_uframe++;
now_uframe %= mod;
Expand Down
6 changes: 6 additions & 0 deletions drivers/usb/host/ehci.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ struct ehci_hcd { /* one per controller */
int next_uframe; /* scan periodic, start here */
unsigned periodic_sched; /* periodic activity count */

/* list of itds completed while clock_frame was still active */
struct list_head cached_itd_list;
unsigned clock_frame;

/* per root hub port */
unsigned long reset_done [EHCI_MAX_ROOT_PORTS];

Expand Down Expand Up @@ -220,6 +224,8 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
}
}

static void free_cached_itd_list(struct ehci_hcd *ehci);

/*-------------------------------------------------------------------------*/

#include <linux/usb/ehci_def.h>
Expand Down
15 changes: 4 additions & 11 deletions drivers/usb/musb/davinci.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,18 +377,8 @@ int __init musb_platform_init(struct musb *musb)
u32 revision;

musb->mregs += DAVINCI_BASE_OFFSET;
#if 0
/* REVISIT there's something odd about clocking, this
* didn't appear do the job ...
*/
musb->clock = clk_get(pDevice, "usb");
if (IS_ERR(musb->clock))
return PTR_ERR(musb->clock);

status = clk_enable(musb->clock);
if (status < 0)
return -ENODEV;
#endif
clk_enable(musb->clock);

/* returns zero if e.g. not clocked */
revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
Expand Down Expand Up @@ -453,5 +443,8 @@ int musb_platform_exit(struct musb *musb)
}

phy_off();

clk_disable(musb->clock);

return 0;
}
13 changes: 7 additions & 6 deletions drivers/usb/musb/musb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@


unsigned musb_debug;
module_param(musb_debug, uint, S_IRUGO | S_IWUSR);
module_param_named(debug, musb_debug, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug message level. Default = 0");

#define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
Expand Down Expand Up @@ -767,6 +767,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
#ifdef CONFIG_USB_MUSB_HDRC_HCD
case OTG_STATE_A_HOST:
case OTG_STATE_A_SUSPEND:
usb_hcd_resume_root_hub(musb_to_hcd(musb));
musb_root_disconnect(musb);
if (musb->a_wait_bcon != 0)
musb_platform_try_idle(musb, jiffies
Expand Down Expand Up @@ -1815,7 +1816,7 @@ static void musb_free(struct musb *musb)
#ifdef CONFIG_SYSFS
device_remove_file(musb->controller, &dev_attr_mode);
device_remove_file(musb->controller, &dev_attr_vbus);
#ifdef CONFIG_USB_MUSB_OTG
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
device_remove_file(musb->controller, &dev_attr_srp);
#endif
#endif
Expand Down Expand Up @@ -2063,7 +2064,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
#ifdef CONFIG_SYSFS
device_remove_file(musb->controller, &dev_attr_mode);
device_remove_file(musb->controller, &dev_attr_vbus);
#ifdef CONFIG_USB_MUSB_OTG
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
device_remove_file(musb->controller, &dev_attr_srp);
#endif
#endif
Expand Down Expand Up @@ -2243,10 +2244,10 @@ static int __init musb_init(void)
return platform_driver_probe(&musb_driver, musb_probe);
}

/* make us init after usbcore and before usb
* gadget and host-side drivers start to register
/* make us init after usbcore and i2c (transceivers, regulators, etc)
* and before usb gadget and host-side drivers start to register
*/
subsys_initcall(musb_init);
fs_initcall(musb_init);

static void __exit musb_cleanup(void)
{
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/musb/musb_gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
struct usb_request *request = &req->request;
struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
void __iomem *epio = musb->endpoints[epnum].regs;
u16 fifo_count = 0;
unsigned fifo_count = 0;
u16 len = musb_ep->packet_sz;

csr = musb_readw(epio, MUSB_RXCSR);
Expand Down Expand Up @@ -687,7 +687,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
len, fifo_count,
musb_ep->packet_sz);

fifo_count = min(len, fifo_count);
fifo_count = min_t(unsigned, len, fifo_count);

#ifdef CONFIG_USB_TUSB_OMAP_DMA
if (tusb_dma_omap() && musb_ep->dma) {
Expand Down
Loading

0 comments on commit 3c4f115

Please sign in to comment.