Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6

* 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (21 commits)
  USB: cdc-acm: Adding second ACM channel support for Nokia N8
  USB, Mass Storage, composite, gadget: Fix build failure and memset of a struct
  USB: Fix trout build failure with ci13xxx_msm gadget
  USB: EHCI: fix scheduling while atomic during suspend
  USB: usb-storage: unusual_devs entry for Coby MP3 player
  USB: ftdi_sio: Add VID=0x0647, PID=0x0100 for Acton Research spectrograph
  USB: fix race between root-hub resume and wakeup requests
  USB: prevent buggy hubs from crashing the USB stack
  usb: r8a66597-udc: Fixed bufnum of Bulk
  USB: ftdi_sio: add ST Micro Connect Lite uart support
  USB: Storage: Add unusual_devs entry for VTech Kidizoom
  USB SL811HS HCD: Fix memory leak in sl811h_urb_enqueue()
  USB: ti_usb: fix module removal
  USB: io_edgeport: fix the reported firmware major and minor
  usb: ehci-omap: Show fatal probing time errors to end user
  usb: musb: introduce api for dma code to check compatibility with usb request
  usb: musb: maintain three states for buffer mappings instead of two
  usb: musb: disable double buffering when it's broken
  usb: musb: hsdma: change back to use musb_read/writew
  usb: musb: core: fix IRQ check
  ...
This commit is contained in:
Linus Torvalds 2011-02-10 12:20:40 -08:00
commit 67d019528e
27 changed files with 178 additions and 57 deletions

View File

@ -1607,6 +1607,7 @@ static const struct usb_device_id acm_ids[] = {
{ NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */ { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */
{ NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */ { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */
{ NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */ { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */
{ NOKIA_PCSUITE_ACM_INFO(0x0302), }, /* Nokia N8 */
{ SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */
/* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */

View File

@ -1955,7 +1955,6 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
dev_dbg(&rhdev->dev, "usb %s%s\n", dev_dbg(&rhdev->dev, "usb %s%s\n",
(msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume"); (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume");
clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
if (!hcd->driver->bus_resume) if (!hcd->driver->bus_resume)
return -ENOENT; return -ENOENT;
if (hcd->state == HC_STATE_RUNNING) if (hcd->state == HC_STATE_RUNNING)
@ -1963,6 +1962,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
hcd->state = HC_STATE_RESUMING; hcd->state = HC_STATE_RESUMING;
status = hcd->driver->bus_resume(hcd); status = hcd->driver->bus_resume(hcd);
clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
if (status == 0) { if (status == 0) {
/* TRSMRCY = 10 msec */ /* TRSMRCY = 10 msec */
msleep(10); msleep(10);

View File

@ -2753,6 +2753,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
udev->ttport = hdev->ttport; udev->ttport = hdev->ttport;
} else if (udev->speed != USB_SPEED_HIGH } else if (udev->speed != USB_SPEED_HIGH
&& hdev->speed == USB_SPEED_HIGH) { && hdev->speed == USB_SPEED_HIGH) {
if (!hub->tt.hub) {
dev_err(&udev->dev, "parent hub has no TT\n");
retval = -EINVAL;
goto fail;
}
udev->tt = &hub->tt; udev->tt = &hub->tt;
udev->ttport = port1; udev->ttport = port1;
} }

View File

@ -546,6 +546,8 @@ config USB_GADGET_CI13XXX_MSM
ci13xxx_udc core. ci13xxx_udc core.
This driver depends on OTG driver for PHY initialization, This driver depends on OTG driver for PHY initialization,
clock management, powering up VBUS, and power management. clock management, powering up VBUS, and power management.
This driver is not supported on boards like trout which
has an external PHY.
Say "y" to link the driver statically, or "m" to build a Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "ci13xxx_msm" and force all dynamically linked module called "ci13xxx_msm" and force all

View File

@ -293,6 +293,7 @@
#include <linux/usb/ch9.h> #include <linux/usb/ch9.h>
#include <linux/usb/gadget.h> #include <linux/usb/gadget.h>
#include <linux/usb/composite.h>
#include "gadget_chips.h" #include "gadget_chips.h"
@ -2763,7 +2764,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
common->free_storage_on_release = 1; common->free_storage_on_release = 1;
} else { } else {
memset(common, 0, sizeof common); memset(common, 0, sizeof *common);
common->free_storage_on_release = 0; common->free_storage_on_release = 0;
} }

View File

@ -258,7 +258,7 @@ static int pipe_buffer_setting(struct r8a66597 *r8a66597,
break; break;
case R8A66597_BULK: case R8A66597_BULK:
/* isochronous pipes may be used as bulk pipes */ /* isochronous pipes may be used as bulk pipes */
if (info->pipe > R8A66597_BASE_PIPENUM_BULK) if (info->pipe >= R8A66597_BASE_PIPENUM_BULK)
bufnum = info->pipe - R8A66597_BASE_PIPENUM_BULK; bufnum = info->pipe - R8A66597_BASE_PIPENUM_BULK;
else else
bufnum = info->pipe - R8A66597_BASE_PIPENUM_ISOC; bufnum = info->pipe - R8A66597_BASE_PIPENUM_ISOC;

View File

@ -151,6 +151,8 @@ config USB_EHCI_MSM
Qualcomm chipsets. Root Hub has inbuilt TT. Qualcomm chipsets. Root Hub has inbuilt TT.
This driver depends on OTG driver for PHY initialization, This driver depends on OTG driver for PHY initialization,
clock management, powering up VBUS, and power management. clock management, powering up VBUS, and power management.
This driver is not supported on boards like trout which
has an external PHY.
config USB_EHCI_HCD_PPC_OF config USB_EHCI_HCD_PPC_OF
bool "EHCI support for PPC USB controller on OF platform bus" bool "EHCI support for PPC USB controller on OF platform bus"

View File

@ -227,8 +227,8 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
* mark HW unaccessible. The PM and USB cores make sure that * mark HW unaccessible. The PM and USB cores make sure that
* the root hub is either suspended or stopped. * the root hub is either suspended or stopped.
*/ */
spin_lock_irqsave(&ehci->lock, flags);
ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev)); ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev));
spin_lock_irqsave(&ehci->lock, flags);
ehci_writel(ehci, 0, &ehci->regs->intr_enable); ehci_writel(ehci, 0, &ehci->regs->intr_enable);
(void)ehci_readl(ehci, &ehci->regs->intr_enable); (void)ehci_readl(ehci, &ehci->regs->intr_enable);

View File

@ -111,6 +111,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
{ {
int port; int port;
u32 temp; u32 temp;
unsigned long flags;
/* If remote wakeup is enabled for the root hub but disabled /* If remote wakeup is enabled for the root hub but disabled
* for the controller, we must adjust all the port wakeup flags * for the controller, we must adjust all the port wakeup flags
@ -120,6 +121,8 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || do_wakeup) if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || do_wakeup)
return; return;
spin_lock_irqsave(&ehci->lock, flags);
/* clear phy low-power mode before changing wakeup flags */ /* clear phy low-power mode before changing wakeup flags */
if (ehci->has_hostpc) { if (ehci->has_hostpc) {
port = HCS_N_PORTS(ehci->hcs_params); port = HCS_N_PORTS(ehci->hcs_params);
@ -131,7 +134,9 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
temp = ehci_readl(ehci, hostpc_reg); temp = ehci_readl(ehci, hostpc_reg);
ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg); ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg);
} }
spin_unlock_irqrestore(&ehci->lock, flags);
msleep(5); msleep(5);
spin_lock_irqsave(&ehci->lock, flags);
} }
port = HCS_N_PORTS(ehci->hcs_params); port = HCS_N_PORTS(ehci->hcs_params);
@ -170,6 +175,8 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
/* Does the root hub have a port wakeup pending? */ /* Does the root hub have a port wakeup pending? */
if (!suspending && (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)) if (!suspending && (ehci_readl(ehci, &ehci->regs->status) & STS_PCD))
usb_hcd_resume_root_hub(ehci_to_hcd(ehci)); usb_hcd_resume_root_hub(ehci_to_hcd(ehci));
spin_unlock_irqrestore(&ehci->lock, flags);
} }
static int ehci_bus_suspend (struct usb_hcd *hcd) static int ehci_bus_suspend (struct usb_hcd *hcd)

View File

@ -796,7 +796,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev, hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
dev_name(&pdev->dev)); dev_name(&pdev->dev));
if (!hcd) { if (!hcd) {
dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret); dev_err(&pdev->dev, "failed to create hcd with err %d\n", ret);
ret = -ENOMEM; ret = -ENOMEM;
goto err_create_hcd; goto err_create_hcd;
} }
@ -864,7 +864,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
ret = omap_start_ehc(omap, hcd); ret = omap_start_ehc(omap, hcd);
if (ret) { if (ret) {
dev_dbg(&pdev->dev, "failed to start ehci\n"); dev_err(&pdev->dev, "failed to start ehci with err %d\n", ret);
goto err_start; goto err_start;
} }
@ -879,7 +879,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
if (ret) { if (ret) {
dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); dev_err(&pdev->dev, "failed to add hcd with err %d\n", ret);
goto err_add_hcd; goto err_add_hcd;
} }

View File

@ -367,8 +367,8 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
* mark HW unaccessible. The PM and USB cores make sure that * mark HW unaccessible. The PM and USB cores make sure that
* the root hub is either suspended or stopped. * the root hub is either suspended or stopped.
*/ */
spin_lock_irqsave (&ehci->lock, flags);
ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup); ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup);
spin_lock_irqsave (&ehci->lock, flags);
ehci_writel(ehci, 0, &ehci->regs->intr_enable); ehci_writel(ehci, 0, &ehci->regs->intr_enable);
(void)ehci_readl(ehci, &ehci->regs->intr_enable); (void)ehci_readl(ehci, &ehci->regs->intr_enable);

View File

@ -861,6 +861,7 @@ static int sl811h_urb_enqueue(
DBG("dev %d ep%d maxpacket %d\n", DBG("dev %d ep%d maxpacket %d\n",
udev->devnum, epnum, ep->maxpacket); udev->devnum, epnum, ep->maxpacket);
retval = -EINVAL; retval = -EINVAL;
kfree(ep);
goto fail; goto fail;
} }

View File

@ -404,6 +404,7 @@ static int bfin_musb_init(struct musb *musb)
musb->xceiv->set_power = bfin_musb_set_power; musb->xceiv->set_power = bfin_musb_set_power;
musb->isr = blackfin_interrupt; musb->isr = blackfin_interrupt;
musb->double_buffer_not_ok = true;
return 0; return 0;
} }

View File

@ -128,12 +128,7 @@ MODULE_ALIAS("platform:" MUSB_DRIVER_NAME);
static inline struct musb *dev_to_musb(struct device *dev) static inline struct musb *dev_to_musb(struct device *dev)
{ {
#ifdef CONFIG_USB_MUSB_HDRC_HCD
/* usbcore insists dev->driver_data is a "struct hcd *" */
return hcd_to_musb(dev_get_drvdata(dev));
#else
return dev_get_drvdata(dev); return dev_get_drvdata(dev);
#endif
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
@ -1876,10 +1871,9 @@ allocate_instance(struct device *dev,
musb = kzalloc(sizeof *musb, GFP_KERNEL); musb = kzalloc(sizeof *musb, GFP_KERNEL);
if (!musb) if (!musb)
return NULL; return NULL;
dev_set_drvdata(dev, musb);
#endif #endif
dev_set_drvdata(dev, musb);
musb->mregs = mbase; musb->mregs = mbase;
musb->ctrl_base = mbase; musb->ctrl_base = mbase;
musb->nIrq = -ENODEV; musb->nIrq = -ENODEV;
@ -2191,7 +2185,7 @@ static int __init musb_probe(struct platform_device *pdev)
void __iomem *base; void __iomem *base;
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iomem || irq == 0) if (!iomem || irq <= 0)
return -ENODEV; return -ENODEV;
base = ioremap(iomem->start, resource_size(iomem)); base = ioremap(iomem->start, resource_size(iomem));

View File

@ -488,6 +488,18 @@ struct musb {
unsigned set_address:1; unsigned set_address:1;
unsigned test_mode:1; unsigned test_mode:1;
unsigned softconnect:1; unsigned softconnect:1;
/*
* FIXME: Remove this flag.
*
* This is only added to allow Blackfin to work
* with current driver. For some unknown reason
* Blackfin doesn't work with double buffering
* and that's enabled by default.
*
* We added this flag to forcefully disable double
* buffering until we get it working.
*/
unsigned double_buffer_not_ok:1 __deprecated;
u8 address; u8 address;
u8 test_mode_nr; u8 test_mode_nr;

View File

@ -169,6 +169,9 @@ struct dma_controller {
dma_addr_t dma_addr, dma_addr_t dma_addr,
u32 length); u32 length);
int (*channel_abort)(struct dma_channel *); int (*channel_abort)(struct dma_channel *);
int (*is_compatible)(struct dma_channel *channel,
u16 maxpacket,
void *buf, u32 length);
}; };
/* called after channel_program(), may indicate a fault */ /* called after channel_program(), may indicate a fault */

View File

@ -92,11 +92,33 @@
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
#define is_buffer_mapped(req) (is_dma_capable() && \
(req->map_state != UN_MAPPED))
/* Maps the buffer to dma */ /* Maps the buffer to dma */
static inline void map_dma_buffer(struct musb_request *request, static inline void map_dma_buffer(struct musb_request *request,
struct musb *musb) struct musb *musb, struct musb_ep *musb_ep)
{ {
int compatible = true;
struct dma_controller *dma = musb->dma_controller;
request->map_state = UN_MAPPED;
if (!is_dma_capable() || !musb_ep->dma)
return;
/* Check if DMA engine can handle this request.
* DMA code must reject the USB request explicitly.
* Default behaviour is to map the request.
*/
if (dma->is_compatible)
compatible = dma->is_compatible(musb_ep->dma,
musb_ep->packet_sz, request->request.buf,
request->request.length);
if (!compatible)
return;
if (request->request.dma == DMA_ADDR_INVALID) { if (request->request.dma == DMA_ADDR_INVALID) {
request->request.dma = dma_map_single( request->request.dma = dma_map_single(
musb->controller, musb->controller,
@ -105,7 +127,7 @@ static inline void map_dma_buffer(struct musb_request *request,
request->tx request->tx
? DMA_TO_DEVICE ? DMA_TO_DEVICE
: DMA_FROM_DEVICE); : DMA_FROM_DEVICE);
request->mapped = 1; request->map_state = MUSB_MAPPED;
} else { } else {
dma_sync_single_for_device(musb->controller, dma_sync_single_for_device(musb->controller,
request->request.dma, request->request.dma,
@ -113,7 +135,7 @@ static inline void map_dma_buffer(struct musb_request *request,
request->tx request->tx
? DMA_TO_DEVICE ? DMA_TO_DEVICE
: DMA_FROM_DEVICE); : DMA_FROM_DEVICE);
request->mapped = 0; request->map_state = PRE_MAPPED;
} }
} }
@ -121,11 +143,14 @@ static inline void map_dma_buffer(struct musb_request *request,
static inline void unmap_dma_buffer(struct musb_request *request, static inline void unmap_dma_buffer(struct musb_request *request,
struct musb *musb) struct musb *musb)
{ {
if (!is_buffer_mapped(request))
return;
if (request->request.dma == DMA_ADDR_INVALID) { if (request->request.dma == DMA_ADDR_INVALID) {
DBG(20, "not unmapping a never mapped buffer\n"); DBG(20, "not unmapping a never mapped buffer\n");
return; return;
} }
if (request->mapped) { if (request->map_state == MUSB_MAPPED) {
dma_unmap_single(musb->controller, dma_unmap_single(musb->controller,
request->request.dma, request->request.dma,
request->request.length, request->request.length,
@ -133,16 +158,15 @@ static inline void unmap_dma_buffer(struct musb_request *request,
? DMA_TO_DEVICE ? DMA_TO_DEVICE
: DMA_FROM_DEVICE); : DMA_FROM_DEVICE);
request->request.dma = DMA_ADDR_INVALID; request->request.dma = DMA_ADDR_INVALID;
request->mapped = 0; } else { /* PRE_MAPPED */
} else {
dma_sync_single_for_cpu(musb->controller, dma_sync_single_for_cpu(musb->controller,
request->request.dma, request->request.dma,
request->request.length, request->request.length,
request->tx request->tx
? DMA_TO_DEVICE ? DMA_TO_DEVICE
: DMA_FROM_DEVICE); : DMA_FROM_DEVICE);
} }
request->map_state = UN_MAPPED;
} }
/* /*
@ -172,8 +196,7 @@ __acquires(ep->musb->lock)
ep->busy = 1; ep->busy = 1;
spin_unlock(&musb->lock); spin_unlock(&musb->lock);
if (is_dma_capable() && ep->dma) unmap_dma_buffer(req, musb);
unmap_dma_buffer(req, musb);
if (request->status == 0) if (request->status == 0)
DBG(5, "%s done request %p, %d/%d\n", DBG(5, "%s done request %p, %d/%d\n",
ep->end_point.name, request, ep->end_point.name, request,
@ -335,7 +358,7 @@ static void txstate(struct musb *musb, struct musb_request *req)
csr); csr);
#ifndef CONFIG_MUSB_PIO_ONLY #ifndef CONFIG_MUSB_PIO_ONLY
if (is_dma_capable() && musb_ep->dma) { if (is_buffer_mapped(req)) {
struct dma_controller *c = musb->dma_controller; struct dma_controller *c = musb->dma_controller;
size_t request_size; size_t request_size;
@ -436,8 +459,7 @@ static void txstate(struct musb *musb, struct musb_request *req)
* Unmap the dma buffer back to cpu if dma channel * Unmap the dma buffer back to cpu if dma channel
* programming fails * programming fails
*/ */
if (is_dma_capable() && musb_ep->dma) unmap_dma_buffer(req, musb);
unmap_dma_buffer(req, musb);
musb_write_fifo(musb_ep->hw_ep, fifo_count, musb_write_fifo(musb_ep->hw_ep, fifo_count,
(u8 *) (request->buf + request->actual)); (u8 *) (request->buf + request->actual));
@ -627,7 +649,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
return; return;
} }
if (is_cppi_enabled() && musb_ep->dma) { if (is_cppi_enabled() && is_buffer_mapped(req)) {
struct dma_controller *c = musb->dma_controller; struct dma_controller *c = musb->dma_controller;
struct dma_channel *channel = musb_ep->dma; struct dma_channel *channel = musb_ep->dma;
@ -658,7 +680,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
len = musb_readw(epio, MUSB_RXCOUNT); len = musb_readw(epio, MUSB_RXCOUNT);
if (request->actual < request->length) { if (request->actual < request->length) {
#ifdef CONFIG_USB_INVENTRA_DMA #ifdef CONFIG_USB_INVENTRA_DMA
if (is_dma_capable() && musb_ep->dma) { if (is_buffer_mapped(req)) {
struct dma_controller *c; struct dma_controller *c;
struct dma_channel *channel; struct dma_channel *channel;
int use_dma = 0; int use_dma = 0;
@ -742,7 +764,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
fifo_count = min_t(unsigned, len, fifo_count); fifo_count = min_t(unsigned, len, fifo_count);
#ifdef CONFIG_USB_TUSB_OMAP_DMA #ifdef CONFIG_USB_TUSB_OMAP_DMA
if (tusb_dma_omap() && musb_ep->dma) { if (tusb_dma_omap() && is_buffer_mapped(req)) {
struct dma_controller *c = musb->dma_controller; struct dma_controller *c = musb->dma_controller;
struct dma_channel *channel = musb_ep->dma; struct dma_channel *channel = musb_ep->dma;
u32 dma_addr = request->dma + request->actual; u32 dma_addr = request->dma + request->actual;
@ -762,7 +784,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
* programming fails. This buffer is mapped if the * programming fails. This buffer is mapped if the
* channel allocation is successful * channel allocation is successful
*/ */
if (is_dma_capable() && musb_ep->dma) { if (is_buffer_mapped(req)) {
unmap_dma_buffer(req, musb); unmap_dma_buffer(req, musb);
/* /*
@ -989,7 +1011,11 @@ static int musb_gadget_enable(struct usb_ep *ep,
/* Set TXMAXP with the FIFO size of the endpoint /* Set TXMAXP with the FIFO size of the endpoint
* to disable double buffering mode. * to disable double buffering mode.
*/ */
musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); if (musb->double_buffer_not_ok)
musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx);
else
musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz
| (musb_ep->hb_mult << 11));
csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;
if (musb_readw(regs, MUSB_TXCSR) if (musb_readw(regs, MUSB_TXCSR)
@ -1025,7 +1051,11 @@ static int musb_gadget_enable(struct usb_ep *ep,
/* Set RXMAXP with the FIFO size of the endpoint /* Set RXMAXP with the FIFO size of the endpoint
* to disable double buffering mode. * to disable double buffering mode.
*/ */
musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); if (musb->double_buffer_not_ok)
musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_tx);
else
musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz
| (musb_ep->hb_mult << 11));
/* force shared fifo to OUT-only mode */ /* force shared fifo to OUT-only mode */
if (hw_ep->is_shared_fifo) { if (hw_ep->is_shared_fifo) {
@ -1214,10 +1244,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
request->epnum = musb_ep->current_epnum; request->epnum = musb_ep->current_epnum;
request->tx = musb_ep->is_in; request->tx = musb_ep->is_in;
if (is_dma_capable() && musb_ep->dma) map_dma_buffer(request, musb, musb_ep);
map_dma_buffer(request, musb);
else
request->mapped = 0;
spin_lock_irqsave(&musb->lock, lockflags); spin_lock_irqsave(&musb->lock, lockflags);

View File

@ -35,13 +35,19 @@
#ifndef __MUSB_GADGET_H #ifndef __MUSB_GADGET_H
#define __MUSB_GADGET_H #define __MUSB_GADGET_H
enum buffer_map_state {
UN_MAPPED = 0,
PRE_MAPPED,
MUSB_MAPPED
};
struct musb_request { struct musb_request {
struct usb_request request; struct usb_request request;
struct musb_ep *ep; struct musb_ep *ep;
struct musb *musb; struct musb *musb;
u8 tx; /* endpoint direction */ u8 tx; /* endpoint direction */
u8 epnum; u8 epnum;
u8 mapped; enum buffer_map_state map_state;
}; };
static inline struct musb_request *to_musb_request(struct usb_request *req) static inline struct musb_request *to_musb_request(struct usb_request *req)

View File

@ -609,7 +609,7 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
/* Set RXMAXP with the FIFO size of the endpoint /* Set RXMAXP with the FIFO size of the endpoint
* to disable double buffer mode. * to disable double buffer mode.
*/ */
if (musb->hwvers < MUSB_HWVERS_2000) if (musb->double_buffer_not_ok)
musb_writew(ep->regs, MUSB_RXMAXP, ep->max_packet_sz_rx); musb_writew(ep->regs, MUSB_RXMAXP, ep->max_packet_sz_rx);
else else
musb_writew(ep->regs, MUSB_RXMAXP, musb_writew(ep->regs, MUSB_RXMAXP,
@ -784,14 +784,13 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
/* protocol/endpoint/interval/NAKlimit */ /* protocol/endpoint/interval/NAKlimit */
if (epnum) { if (epnum) {
musb_writeb(epio, MUSB_TXTYPE, qh->type_reg); musb_writeb(epio, MUSB_TXTYPE, qh->type_reg);
if (can_bulk_split(musb, qh->type)) if (musb->double_buffer_not_ok)
musb_writew(epio, MUSB_TXMAXP, musb_writew(epio, MUSB_TXMAXP,
packet_sz hw_ep->max_packet_sz_tx);
| ((hw_ep->max_packet_sz_tx /
packet_sz) - 1) << 11);
else else
musb_writew(epio, MUSB_TXMAXP, musb_writew(epio, MUSB_TXMAXP,
packet_sz); qh->maxpacket |
((qh->hb_mult - 1) << 11));
musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg); musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg);
} else { } else {
musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg); musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg);

View File

@ -94,24 +94,33 @@ static inline void musb_write_hsdma_addr(void __iomem *mbase,
{ {
musb_writew(mbase, musb_writew(mbase,
MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW), MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW),
((u16)((u32) dma_addr & 0xFFFF))); dma_addr);
musb_writew(mbase, musb_writew(mbase,
MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH), MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH),
((u16)(((u32) dma_addr >> 16) & 0xFFFF))); (dma_addr >> 16));
} }
static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel) static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel)
{ {
return musb_readl(mbase, u32 count = musb_readw(mbase,
MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH)); MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH));
count = count << 16;
count |= musb_readw(mbase,
MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW));
return count;
} }
static inline void musb_write_hsdma_count(void __iomem *mbase, static inline void musb_write_hsdma_count(void __iomem *mbase,
u8 bchannel, u32 len) u8 bchannel, u32 len)
{ {
musb_writel(mbase, musb_writew(mbase,
MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW),len);
musb_writew(mbase,
MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH), MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH),
len); (len >> 16));
} }
#endif /* CONFIG_BLACKFIN */ #endif /* CONFIG_BLACKFIN */

View File

@ -103,6 +103,8 @@ config USB_MSM_OTG_72K
required after resetting the hardware and power management. required after resetting the hardware and power management.
This driver is required even for peripheral only or host only This driver is required even for peripheral only or host only
mode configurations. mode configurations.
This driver is not supported on boards like trout which
has an external PHY.
config AB8500_USB config AB8500_USB
tristate "AB8500 USB Transceiver Driver" tristate "AB8500 USB Transceiver Driver"

View File

@ -100,6 +100,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 int ftdi_NDI_device_setup(struct usb_serial *serial);
static int ftdi_stmclite_probe(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);
@ -123,6 +124,10 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
.port_probe = ftdi_HE_TIRA1_setup, .port_probe = ftdi_HE_TIRA1_setup,
}; };
static struct ftdi_sio_quirk ftdi_stmclite_quirk = {
.probe = ftdi_stmclite_probe,
};
/* /*
* The 8U232AM has the same API as the sio except for: * The 8U232AM has the same API as the sio except for:
* - it can support MUCH higher baudrates; up to: * - it can support MUCH higher baudrates; up to:
@ -616,6 +621,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) },
{ USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, { USB_DEVICE(TTI_VID, TTI_QL355P_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
{ USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) },
{ USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
@ -810,6 +816,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
{ USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(ST_VID, ST_STMCLT1030_PID),
.driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
{ }, /* Optional parameter entry */ { }, /* Optional parameter entry */
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
@ -1708,6 +1716,25 @@ static int ftdi_jtag_probe(struct usb_serial *serial)
return 0; return 0;
} }
/*
* First and second port on STMCLiteadaptors is reserved for JTAG interface
* and the forth port for pio
*/
static int ftdi_stmclite_probe(struct usb_serial *serial)
{
struct usb_device *udev = serial->dev;
struct usb_interface *interface = serial->interface;
dbg("%s", __func__);
if (interface == udev->actconfig->interface[2])
return 0;
dev_info(&udev->dev, "Ignoring serial port reserved for JTAG\n");
return -ENODEV;
}
/* /*
* The Matrix Orbital VK204-25-USB has an invalid IN endpoint. * The Matrix Orbital VK204-25-USB has an invalid IN endpoint.
* We have to correct it if we want to read from it. * We have to correct it if we want to read from it.

View File

@ -517,6 +517,12 @@
#define RATOC_VENDOR_ID 0x0584 #define RATOC_VENDOR_ID 0x0584
#define RATOC_PRODUCT_ID_USB60F 0xb020 #define RATOC_PRODUCT_ID_USB60F 0xb020
/*
* Acton Research Corp.
*/
#define ACTON_VID 0x0647 /* Vendor ID */
#define ACTON_SPECTRAPRO_PID 0x0100
/* /*
* Contec products (http://www.contec.com) * Contec products (http://www.contec.com)
* Submitted by Daniel Sangorrin * Submitted by Daniel Sangorrin
@ -1033,6 +1039,12 @@
#define STB_PID 0x0001 /* Sensor Terminal Board */ #define STB_PID 0x0001 /* Sensor Terminal Board */
#define WHT_PID 0x0004 /* Wireless Handheld Terminal */ #define WHT_PID 0x0004 /* Wireless Handheld Terminal */
/*
* STMicroelectonics
*/
#define ST_VID 0x0483
#define ST_STMCLT1030_PID 0x3747 /* ST Micro Connect Lite STMCLT1030 */
/* /*
* Papouch products (http://www.papouch.com/) * Papouch products (http://www.papouch.com/)
* Submitted by Folkert van Heusden * Submitted by Folkert van Heusden

View File

@ -2889,8 +2889,8 @@ static void load_application_firmware(struct edgeport_serial *edge_serial)
dbg("%s %d.%d.%d", fw_info, rec->data[0], rec->data[1], build); dbg("%s %d.%d.%d", fw_info, rec->data[0], rec->data[1], build);
edge_serial->product_info.FirmwareMajorVersion = fw->data[0]; edge_serial->product_info.FirmwareMajorVersion = rec->data[0];
edge_serial->product_info.FirmwareMinorVersion = fw->data[1]; edge_serial->product_info.FirmwareMinorVersion = rec->data[1];
edge_serial->product_info.FirmwareBuildNumber = cpu_to_le16(build); edge_serial->product_info.FirmwareBuildNumber = cpu_to_le16(build);
for (rec = ihex_next_binrec(rec); rec; for (rec = ihex_next_binrec(rec); rec;

View File

@ -369,9 +369,9 @@ failed_1port:
static void __exit ti_exit(void) static void __exit ti_exit(void)
{ {
usb_deregister(&ti_usb_driver);
usb_serial_deregister(&ti_1port_device); usb_serial_deregister(&ti_1port_device);
usb_serial_deregister(&ti_2port_device); usb_serial_deregister(&ti_2port_device);
usb_deregister(&ti_usb_driver);
} }

View File

@ -1397,6 +1397,13 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100,
USB_SC_DEVICE, USB_PR_DEVICE, NULL, USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ), US_FL_IGNORE_RESIDUE ),
/* Submitted by Nick Holloway */
UNUSUAL_DEV( 0x0f88, 0x042e, 0x0100, 0x0100,
"VTech",
"Kidizoom",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
/* Reported by Michael Stattmann <michael@stattmann.com> */ /* Reported by Michael Stattmann <michael@stattmann.com> */
UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
"Sony Ericsson", "Sony Ericsson",
@ -1890,6 +1897,13 @@ UNUSUAL_DEV( 0x1e68, 0x001b, 0x0000, 0x0000,
USB_SC_DEVICE, USB_PR_DEVICE, NULL, USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ), US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ),
/* Reported by Jasper Mackenzie <scarletpimpernal@hotmail.com> */
UNUSUAL_DEV( 0x1e74, 0x4621, 0x0000, 0x0000,
"Coby Electronics",
"MP3 Player",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ),
UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001,
"ST", "ST",
"2A", "2A",

View File

@ -16,12 +16,8 @@
#ifndef __LINUX_USB_GADGET_MSM72K_UDC_H__ #ifndef __LINUX_USB_GADGET_MSM72K_UDC_H__
#define __LINUX_USB_GADGET_MSM72K_UDC_H__ #define __LINUX_USB_GADGET_MSM72K_UDC_H__
#ifdef CONFIG_ARCH_MSM7X00A
#define USB_SBUSCFG (MSM_USB_BASE + 0x0090)
#else
#define USB_AHBBURST (MSM_USB_BASE + 0x0090) #define USB_AHBBURST (MSM_USB_BASE + 0x0090)
#define USB_AHBMODE (MSM_USB_BASE + 0x0098) #define USB_AHBMODE (MSM_USB_BASE + 0x0098)
#endif
#define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ #define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */
#define USB_USBCMD (MSM_USB_BASE + 0x0140) #define USB_USBCMD (MSM_USB_BASE + 0x0140)