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: (25 commits)
  USB: net: asix: add support for Cables-to-Go USB Ethernet adapter
  USB: gadget: cdc-acm deadlock fix
  USB: EHCI: fix divide-by-zero bug
  USB: EHCI: fix handling of dead controllers
  usb: r8a66597-hcd: fix wrong data access in SuperH on-chip USB
  ub: stub pre_reset and post_reset to fix oops
  USB: SISUSB2VGA driver: add 0x0711, 0x0903
  usb: unusual devs patch for Nokia 7610 Supernova
  USB: remove optional bus bindings in isp1760, fixing runtime warning
  + usb-serial-cp2101-add-enfora-gsm2228.patch added to -mm tree
  USB: storage: adjust comment in Kconfig
  USB: Fix PS3 USB shutdown problems
  USB: unusual_devs entry for Argosy USB mass-storage interface
  USB: cdc-acm.c: fix recursive lock in acm_start_wb error path
  USB: CP2101 Add device ID for AMB2560
  USB: mention URB_FREE_BUFFER in usb_free_urb documentation
  USB: Add YISO u893 usb modem vendor and product IDs to option driver
  usb: musb: fix BULK request on different available endpoints
  usb: musb: fix debug global variable name
  usb: musb: Removes compilation warning in gadget mode
  ...
This commit is contained in:
Linus Torvalds 2008-11-13 15:55:07 -08:00
commit 9c7c354645
27 changed files with 218 additions and 122 deletions

View File

@ -1546,8 +1546,6 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
/* /*
* Reset management * Reset management
* XXX Move usb_reset_device to khubd. Hogging kevent is not a good thing.
* XXX Make usb_sync_reset asynchronous.
*/ */
static void ub_reset_enter(struct ub_dev *sc, int try) static void ub_reset_enter(struct ub_dev *sc, int try)
@ -1632,6 +1630,22 @@ static void ub_reset_task(struct work_struct *work)
spin_unlock_irqrestore(sc->lock, flags); spin_unlock_irqrestore(sc->lock, flags);
} }
/*
* XXX Reset brackets are too much hassle to implement, so just stub them
* in order to prevent forced unbinding (which deadlocks solid when our
* ->disconnect method waits for the reset to complete and this kills keventd).
*
* XXX Tell Alan to move usb_unlock_device inside of usb_reset_device,
* or else the post_reset is invoked, and restats I/O on a locked device.
*/
static int ub_pre_reset(struct usb_interface *iface) {
return 0;
}
static int ub_post_reset(struct usb_interface *iface) {
return 0;
}
/* /*
* This is called from a process context. * This is called from a process context.
*/ */
@ -2446,6 +2460,8 @@ static struct usb_driver ub_driver = {
.probe = ub_probe, .probe = ub_probe,
.disconnect = ub_disconnect, .disconnect = ub_disconnect,
.id_table = ub_usb_ids, .id_table = ub_usb_ids,
.pre_reset = ub_pre_reset,
.post_reset = ub_post_reset,
}; };
static int __init ub_init(void) static int __init ub_init(void)

View File

@ -1444,6 +1444,10 @@ static const struct usb_device_id products [] = {
// Apple USB Ethernet Adapter // Apple USB Ethernet Adapter
USB_DEVICE(0x05ac, 0x1402), USB_DEVICE(0x05ac, 0x1402),
.driver_info = (unsigned long) &ax88772_info, .driver_info = (unsigned long) &ax88772_info,
}, {
// Cables-to-Go USB Ethernet Adapter
USB_DEVICE(0x0b95, 0x772a),
.driver_info = (unsigned long) &ax88772_info,
}, },
{ }, // END { }, // END
}; };

View File

@ -158,16 +158,12 @@ static int acm_wb_is_avail(struct acm *acm)
} }
/* /*
* Finish write. * Finish write. Caller must hold acm->write_lock
*/ */
static void acm_write_done(struct acm *acm, struct acm_wb *wb) static void acm_write_done(struct acm *acm, struct acm_wb *wb)
{ {
unsigned long flags;
spin_lock_irqsave(&acm->write_lock, flags);
wb->use = 0; wb->use = 0;
acm->transmitting--; acm->transmitting--;
spin_unlock_irqrestore(&acm->write_lock, flags);
} }
/* /*
@ -482,6 +478,7 @@ static void acm_write_bulk(struct urb *urb)
{ {
struct acm_wb *wb = urb->context; struct acm_wb *wb = urb->context;
struct acm *acm = wb->instance; struct acm *acm = wb->instance;
unsigned long flags;
if (verbose || urb->status if (verbose || urb->status
|| (urb->actual_length != urb->transfer_buffer_length)) || (urb->actual_length != urb->transfer_buffer_length))
@ -490,7 +487,9 @@ static void acm_write_bulk(struct urb *urb)
urb->transfer_buffer_length, urb->transfer_buffer_length,
urb->status); urb->status);
spin_lock_irqsave(&acm->write_lock, flags);
acm_write_done(acm, wb); acm_write_done(acm, wb);
spin_unlock_irqrestore(&acm->write_lock, flags);
if (ACM_READY(acm)) if (ACM_READY(acm))
schedule_work(&acm->work); schedule_work(&acm->work);
else else

View File

@ -1091,6 +1091,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
continue; continue;
dev_dbg(&dev->dev, "unregistering interface %s\n", dev_dbg(&dev->dev, "unregistering interface %s\n",
dev_name(&interface->dev)); dev_name(&interface->dev));
interface->unregistering = 1;
usb_remove_sysfs_intf_files(interface); usb_remove_sysfs_intf_files(interface);
device_del(&interface->dev); device_del(&interface->dev);
} }

View File

@ -840,7 +840,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
struct usb_host_interface *alt = intf->cur_altsetting; struct usb_host_interface *alt = intf->cur_altsetting;
int retval; int retval;
if (intf->sysfs_files_created) if (intf->sysfs_files_created || intf->unregistering)
return 0; return 0;
/* The interface string may be present in some altsettings /* The interface string may be present in some altsettings

View File

@ -85,8 +85,8 @@ EXPORT_SYMBOL_GPL(usb_alloc_urb);
* Must be called when a user of a urb is finished with it. When the last user * Must be called when a user of a urb is finished with it. When the last user
* of the urb calls this function, the memory of the urb is freed. * of the urb calls this function, the memory of the urb is freed.
* *
* Note: The transfer buffer associated with the urb is not freed, that must be * Note: The transfer buffer associated with the urb is not freed unless the
* done elsewhere. * URB_FREE_BUFFER transfer flag is set.
*/ */
void usb_free_urb(struct urb *urb) void usb_free_urb(struct urb *urb)
{ {

View File

@ -463,7 +463,11 @@ static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value,
notify->wLength = cpu_to_le16(length); notify->wLength = cpu_to_le16(length);
memcpy(buf, data, length); memcpy(buf, data, length);
/* ep_queue() can complete immediately if it fills the fifo... */
spin_unlock(&acm->lock);
status = usb_ep_queue(ep, req, GFP_ATOMIC); status = usb_ep_queue(ep, req, GFP_ATOMIC);
spin_lock(&acm->lock);
if (status < 0) { if (status < 0) {
ERROR(acm->port.func.config->cdev, ERROR(acm->port.func.config->cdev,
"acm ttyGS%d can't notify serial state, %d\n", "acm ttyGS%d can't notify serial state, %d\n",

View File

@ -110,29 +110,18 @@ config USB_ISP116X_HCD
config USB_ISP1760_HCD config USB_ISP1760_HCD
tristate "ISP 1760 HCD support" tristate "ISP 1760 HCD support"
depends on USB && EXPERIMENTAL depends on USB && EXPERIMENTAL && (PCI || PPC_OF)
---help--- ---help---
The ISP1760 chip is a USB 2.0 host controller. The ISP1760 chip is a USB 2.0 host controller.
This driver does not support isochronous transfers or OTG. This driver does not support isochronous transfers or OTG.
This USB controller is usually attached to a non-DMA-Master
capable bus. NXP's eval kit brings this chip on PCI card
where the chip itself is behind a PLB to simulate such
a bus.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called isp1760-hcd. module will be called isp1760.
config USB_ISP1760_PCI
bool "Support for the PCI bus"
depends on USB_ISP1760_HCD && PCI
---help---
Enables support for the device present on the PCI bus.
This should only be required if you happen to have the eval kit from
NXP and you are going to test it.
config USB_ISP1760_OF
bool "Support for the OF platform bus"
depends on USB_ISP1760_HCD && PPC_OF
---help---
Enables support for the device present on the PowerPC
OpenFirmware platform bus.
config USB_OHCI_HCD config USB_OHCI_HCD
tristate "OHCI HCD support" tristate "OHCI HCD support"

View File

@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd)
static irqreturn_t ehci_irq (struct usb_hcd *hcd) static irqreturn_t ehci_irq (struct usb_hcd *hcd)
{ {
struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_hcd *ehci = hcd_to_ehci (hcd);
u32 status, pcd_status = 0, cmd; u32 status, masked_status, pcd_status = 0, cmd;
int bh; int bh;
spin_lock (&ehci->lock); spin_lock (&ehci->lock);
@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
goto dead; goto dead;
} }
status &= INTR_MASK; masked_status = status & INTR_MASK;
if (!status) { /* irq sharing? */ if (!masked_status) { /* irq sharing? */
spin_unlock(&ehci->lock); spin_unlock(&ehci->lock);
return IRQ_NONE; return IRQ_NONE;
} }
/* clear (just) interrupts */ /* clear (just) interrupts */
ehci_writel(ehci, status, &ehci->regs->status); ehci_writel(ehci, masked_status, &ehci->regs->status);
cmd = ehci_readl(ehci, &ehci->regs->command); cmd = ehci_readl(ehci, &ehci->regs->command);
bh = 0; bh = 0;
@ -734,18 +734,17 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
/* PCI errors [4.15.2.4] */ /* PCI errors [4.15.2.4] */
if (unlikely ((status & STS_FATAL) != 0)) { if (unlikely ((status & STS_FATAL) != 0)) {
ehci_err(ehci, "fatal error\n");
dbg_cmd(ehci, "fatal", cmd); dbg_cmd(ehci, "fatal", cmd);
dbg_status(ehci, "fatal", status); dbg_status(ehci, "fatal", status);
if (status & STS_HALT) { ehci_halt(ehci);
ehci_err (ehci, "fatal error\n");
dead: dead:
ehci_reset (ehci); ehci_reset(ehci);
ehci_writel(ehci, 0, &ehci->regs->configured_flag); ehci_writel(ehci, 0, &ehci->regs->configured_flag);
/* generic layer kills/unlinks all urbs, then /* generic layer kills/unlinks all urbs, then
* uses ehci_stop to clean up the rest * uses ehci_stop to clean up the rest
*/ */
bh = 1; bh = 1;
}
} }
if (bh) if (bh)

View File

@ -205,6 +205,7 @@ static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
tmp = hcd->irq; tmp = hcd->irq;
ehci_shutdown(hcd);
usb_remove_hcd(hcd); usb_remove_hcd(hcd);
ps3_system_bus_set_driver_data(dev, NULL); ps3_system_bus_set_driver_data(dev, NULL);

View File

@ -918,7 +918,7 @@ iso_stream_init (
*/ */
stream->usecs = HS_USECS_ISO (maxp); stream->usecs = HS_USECS_ISO (maxp);
bandwidth = stream->usecs * 8; bandwidth = stream->usecs * 8;
bandwidth /= 1 << (interval - 1); bandwidth /= interval;
} else { } else {
u32 addr; u32 addr;
@ -951,7 +951,7 @@ iso_stream_init (
} else } else
stream->raw_mask = smask_out [hs_transfers - 1]; stream->raw_mask = smask_out [hs_transfers - 1];
bandwidth = stream->usecs + stream->c_usecs; bandwidth = stream->usecs + stream->c_usecs;
bandwidth /= 1 << (interval + 2); bandwidth /= interval << 3;
/* stream->splits gets created from raw_mask later */ /* stream->splits gets created from raw_mask later */
stream->address = cpu_to_hc32(ehci, addr); stream->address = cpu_to_hc32(ehci, addr);

View File

@ -14,16 +14,16 @@
#include "../core/hcd.h" #include "../core/hcd.h"
#include "isp1760-hcd.h" #include "isp1760-hcd.h"
#ifdef CONFIG_USB_ISP1760_OF #ifdef CONFIG_PPC_OF
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#endif #endif
#ifdef CONFIG_USB_ISP1760_PCI #ifdef CONFIG_PCI
#include <linux/pci.h> #include <linux/pci.h>
#endif #endif
#ifdef CONFIG_USB_ISP1760_OF #ifdef CONFIG_PPC_OF
static int of_isp1760_probe(struct of_device *dev, static int of_isp1760_probe(struct of_device *dev,
const struct of_device_id *match) const struct of_device_id *match)
{ {
@ -128,7 +128,7 @@ static struct of_platform_driver isp1760_of_driver = {
}; };
#endif #endif
#ifdef CONFIG_USB_ISP1760_PCI #ifdef CONFIG_PCI
static u32 nxp_pci_io_base; static u32 nxp_pci_io_base;
static u32 iolength; static u32 iolength;
static u32 pci_mem_phy0; static u32 pci_mem_phy0;
@ -288,28 +288,28 @@ static struct pci_driver isp1761_pci_driver = {
static int __init isp1760_init(void) static int __init isp1760_init(void)
{ {
int ret = -ENODEV; int ret;
init_kmem_once(); init_kmem_once();
#ifdef CONFIG_USB_ISP1760_OF #ifdef CONFIG_PPC_OF
ret = of_register_platform_driver(&isp1760_of_driver); ret = of_register_platform_driver(&isp1760_of_driver);
if (ret) { if (ret) {
deinit_kmem_cache(); deinit_kmem_cache();
return ret; return ret;
} }
#endif #endif
#ifdef CONFIG_USB_ISP1760_PCI #ifdef CONFIG_PCI
ret = pci_register_driver(&isp1761_pci_driver); ret = pci_register_driver(&isp1761_pci_driver);
if (ret) if (ret)
goto unreg_of; goto unreg_of;
#endif #endif
return ret; return ret;
#ifdef CONFIG_USB_ISP1760_PCI #ifdef CONFIG_PCI
unreg_of: unreg_of:
#endif #endif
#ifdef CONFIG_USB_ISP1760_OF #ifdef CONFIG_PPC_OF
of_unregister_platform_driver(&isp1760_of_driver); of_unregister_platform_driver(&isp1760_of_driver);
#endif #endif
deinit_kmem_cache(); deinit_kmem_cache();
@ -319,10 +319,10 @@ module_init(isp1760_init);
static void __exit isp1760_exit(void) static void __exit isp1760_exit(void)
{ {
#ifdef CONFIG_USB_ISP1760_OF #ifdef CONFIG_PPC_OF
of_unregister_platform_driver(&isp1760_of_driver); of_unregister_platform_driver(&isp1760_of_driver);
#endif #endif
#ifdef CONFIG_USB_ISP1760_PCI #ifdef CONFIG_PCI
pci_unregister_driver(&isp1761_pci_driver); pci_unregister_driver(&isp1761_pci_driver);
#endif #endif
deinit_kmem_cache(); deinit_kmem_cache();

View File

@ -192,7 +192,7 @@ static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
return result; return result;
} }
static int ps3_ohci_remove (struct ps3_system_bus_device *dev) static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
{ {
unsigned int tmp; unsigned int tmp;
struct usb_hcd *hcd = struct usb_hcd *hcd =
@ -205,6 +205,7 @@ static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
tmp = hcd->irq; tmp = hcd->irq;
ohci_shutdown(hcd);
usb_remove_hcd(hcd); usb_remove_hcd(hcd);
ps3_system_bus_set_driver_data(dev, NULL); ps3_system_bus_set_driver_data(dev, NULL);

View File

@ -1763,11 +1763,12 @@ static void r8a66597_timer(unsigned long _r8a66597)
{ {
struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597;
unsigned long flags; unsigned long flags;
int port;
spin_lock_irqsave(&r8a66597->lock, flags); spin_lock_irqsave(&r8a66597->lock, flags);
r8a66597_root_hub_control(r8a66597, 0); for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
r8a66597_root_hub_control(r8a66597, 1); r8a66597_root_hub_control(r8a66597, port);
spin_unlock_irqrestore(&r8a66597->lock, flags); spin_unlock_irqrestore(&r8a66597->lock, flags);
} }

View File

@ -3270,6 +3270,7 @@ static struct usb_device_id sisusb_table [] = {
{ USB_DEVICE(0x0711, 0x0900) }, { USB_DEVICE(0x0711, 0x0900) },
{ USB_DEVICE(0x0711, 0x0901) }, { USB_DEVICE(0x0711, 0x0901) },
{ USB_DEVICE(0x0711, 0x0902) }, { USB_DEVICE(0x0711, 0x0902) },
{ USB_DEVICE(0x0711, 0x0903) },
{ USB_DEVICE(0x0711, 0x0918) }, { USB_DEVICE(0x0711, 0x0918) },
{ USB_DEVICE(0x182d, 0x021c) }, { USB_DEVICE(0x182d, 0x021c) },
{ USB_DEVICE(0x182d, 0x0269) }, { USB_DEVICE(0x182d, 0x0269) },

View File

@ -620,7 +620,7 @@ static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
__func__); __func__);
retval = -EFAULT; retval = -EFAULT;
} else { } else {
dev_dbg(&dev->dev, "%s: recv %d bytes from pipe %d\n", dev_dbg(&dev->dev, "%s: recv %zd bytes from pipe %d\n",
__func__, usb_data.count, usb_data.pipe); __func__, usb_data.count, usb_data.pipe);
} }

View File

@ -114,8 +114,8 @@
unsigned debug; unsigned musb_debug;
module_param(debug, uint, S_IRUGO | S_IWUSR); module_param(musb_debug, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); MODULE_PARM_DESC(debug, "Debug message level. Default = 0");
#define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
@ -2248,7 +2248,7 @@ static int __init musb_init(void)
"host" "host"
#endif #endif
", debug=%d\n", ", debug=%d\n",
musb_driver_name, debug); musb_driver_name, musb_debug);
return platform_driver_probe(&musb_driver, musb_probe); return platform_driver_probe(&musb_driver, musb_probe);
} }

View File

@ -48,11 +48,11 @@
__func__, __LINE__ , ## args); \ __func__, __LINE__ , ## args); \
} } while (0) } } while (0)
extern unsigned debug; extern unsigned musb_debug;
static inline int _dbg_level(unsigned l) static inline int _dbg_level(unsigned l)
{ {
return debug >= l; return musb_debug >= l;
} }
#define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args) #define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args)

View File

@ -378,6 +378,19 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
switch (qh->type) { switch (qh->type) {
case USB_ENDPOINT_XFER_CONTROL:
case USB_ENDPOINT_XFER_BULK:
/* fifo policy for these lists, except that NAKing
* should rotate a qh to the end (for fairness).
*/
if (qh->mux == 1) {
head = qh->ring.prev;
list_del(&qh->ring);
kfree(qh);
qh = first_qh(head);
break;
}
case USB_ENDPOINT_XFER_ISOC: case USB_ENDPOINT_XFER_ISOC:
case USB_ENDPOINT_XFER_INT: case USB_ENDPOINT_XFER_INT:
/* this is where periodic bandwidth should be /* this is where periodic bandwidth should be
@ -388,17 +401,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
kfree(qh); kfree(qh);
qh = NULL; qh = NULL;
break; break;
case USB_ENDPOINT_XFER_CONTROL:
case USB_ENDPOINT_XFER_BULK:
/* fifo policy for these lists, except that NAKing
* should rotate a qh to the end (for fairness).
*/
head = qh->ring.prev;
list_del(&qh->ring);
kfree(qh);
qh = first_qh(head);
break;
} }
} }
return qh; return qh;
@ -1507,10 +1509,29 @@ void musb_host_rx(struct musb *musb, u8 epnum)
musb_writew(hw_ep->regs, MUSB_RXCSR, val); musb_writew(hw_ep->regs, MUSB_RXCSR, val);
#ifdef CONFIG_USB_INVENTRA_DMA #ifdef CONFIG_USB_INVENTRA_DMA
if (usb_pipeisoc(pipe)) {
struct usb_iso_packet_descriptor *d;
d = urb->iso_frame_desc + qh->iso_idx;
d->actual_length = xfer_len;
/* even if there was an error, we did the dma
* for iso_frame_desc->length
*/
if (d->status != EILSEQ && d->status != -EOVERFLOW)
d->status = 0;
if (++qh->iso_idx >= urb->number_of_packets)
done = true;
else
done = false;
} else {
/* done if urb buffer is full or short packet is recd */ /* done if urb buffer is full or short packet is recd */
done = (urb->actual_length + xfer_len >= done = (urb->actual_length + xfer_len >=
urb->transfer_buffer_length urb->transfer_buffer_length
|| dma->actual_len < qh->maxpacket); || dma->actual_len < qh->maxpacket);
}
/* send IN token for next packet, without AUTOREQ */ /* send IN token for next packet, without AUTOREQ */
if (!done) { if (!done) {
@ -1547,7 +1568,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
if (dma) { if (dma) {
struct dma_controller *c; struct dma_controller *c;
u16 rx_count; u16 rx_count;
int ret; int ret, length;
dma_addr_t buf;
rx_count = musb_readw(epio, MUSB_RXCOUNT); rx_count = musb_readw(epio, MUSB_RXCOUNT);
@ -1560,6 +1582,35 @@ void musb_host_rx(struct musb *musb, u8 epnum)
c = musb->dma_controller; c = musb->dma_controller;
if (usb_pipeisoc(pipe)) {
int status = 0;
struct usb_iso_packet_descriptor *d;
d = urb->iso_frame_desc + qh->iso_idx;
if (iso_err) {
status = -EILSEQ;
urb->error_count++;
}
if (rx_count > d->length) {
if (status == 0) {
status = -EOVERFLOW;
urb->error_count++;
}
DBG(2, "** OVERFLOW %d into %d\n",\
rx_count, d->length);
length = d->length;
} else
length = rx_count;
d->status = status;
buf = urb->transfer_dma + d->offset;
} else {
length = rx_count;
buf = urb->transfer_dma +
urb->actual_length;
}
dma->desired_mode = 0; dma->desired_mode = 0;
#ifdef USE_MODE1 #ifdef USE_MODE1
/* because of the issue below, mode 1 will /* because of the issue below, mode 1 will
@ -1571,6 +1622,12 @@ void musb_host_rx(struct musb *musb, u8 epnum)
urb->actual_length) urb->actual_length)
> qh->maxpacket) > qh->maxpacket)
dma->desired_mode = 1; dma->desired_mode = 1;
if (rx_count < hw_ep->max_packet_sz_rx) {
length = rx_count;
dma->bDesiredMode = 0;
} else {
length = urb->transfer_buffer_length;
}
#endif #endif
/* Disadvantage of using mode 1: /* Disadvantage of using mode 1:
@ -1608,12 +1665,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
*/ */
ret = c->channel_program( ret = c->channel_program(
dma, qh->maxpacket, dma, qh->maxpacket,
dma->desired_mode, dma->desired_mode, buf, length);
urb->transfer_dma
+ urb->actual_length,
(dma->desired_mode == 0)
? rx_count
: urb->transfer_buffer_length);
if (!ret) { if (!ret) {
c->channel_release(dma); c->channel_release(dma);
@ -1631,19 +1683,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)
} }
} }
if (dma && usb_pipeisoc(pipe)) {
struct usb_iso_packet_descriptor *d;
int iso_stat = status;
d = urb->iso_frame_desc + qh->iso_idx;
d->actual_length += xfer_len;
if (iso_err) {
iso_stat = -EILSEQ;
urb->error_count++;
}
d->status = iso_stat;
}
finish: finish:
urb->actual_length += xfer_len; urb->actual_length += xfer_len;
qh->offset += xfer_len; qh->offset += xfer_len;
@ -1671,22 +1710,9 @@ static int musb_schedule(
struct list_head *head = NULL; struct list_head *head = NULL;
/* use fixed hardware for control and bulk */ /* use fixed hardware for control and bulk */
switch (qh->type) { if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
case USB_ENDPOINT_XFER_CONTROL:
head = &musb->control; head = &musb->control;
hw_ep = musb->control_ep; hw_ep = musb->control_ep;
break;
case USB_ENDPOINT_XFER_BULK:
hw_ep = musb->bulk_ep;
if (is_in)
head = &musb->in_bulk;
else
head = &musb->out_bulk;
break;
}
if (head) {
idle = list_empty(head);
list_add_tail(&qh->ring, head);
goto success; goto success;
} }
@ -1725,19 +1751,34 @@ static int musb_schedule(
else else
diff = hw_ep->max_packet_sz_tx - qh->maxpacket; diff = hw_ep->max_packet_sz_tx - qh->maxpacket;
if (diff > 0 && best_diff > diff) { if (diff >= 0 && best_diff > diff) {
best_diff = diff; best_diff = diff;
best_end = epnum; best_end = epnum;
} }
} }
if (best_end < 0) /* use bulk reserved ep1 if no other ep is free */
if (best_end > 0 && qh->type == USB_ENDPOINT_XFER_BULK) {
hw_ep = musb->bulk_ep;
if (is_in)
head = &musb->in_bulk;
else
head = &musb->out_bulk;
goto success;
} else if (best_end < 0) {
return -ENOSPC; return -ENOSPC;
}
idle = 1; idle = 1;
qh->mux = 0;
hw_ep = musb->endpoints + best_end; hw_ep = musb->endpoints + best_end;
musb->periodic[best_end] = qh; musb->periodic[best_end] = qh;
DBG(4, "qh %p periodic slot %d\n", qh, best_end); DBG(4, "qh %p periodic slot %d\n", qh, best_end);
success: success:
if (head) {
idle = list_empty(head);
list_add_tail(&qh->ring, head);
qh->mux = 1;
}
qh->hw_ep = hw_ep; qh->hw_ep = hw_ep;
qh->hep->hcpriv = qh; qh->hep->hcpriv = qh;
if (idle) if (idle)
@ -2015,11 +2056,13 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
sched = &musb->control; sched = &musb->control;
break; break;
case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_BULK:
if (usb_pipein(urb->pipe)) if (qh->mux == 1) {
sched = &musb->in_bulk; if (usb_pipein(urb->pipe))
else sched = &musb->in_bulk;
sched = &musb->out_bulk; else
break; sched = &musb->out_bulk;
break;
}
default: default:
/* REVISIT when we get a schedule tree, periodic /* REVISIT when we get a schedule tree, periodic
* transfers won't always be at the head of a * transfers won't always be at the head of a
@ -2067,11 +2110,13 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
sched = &musb->control; sched = &musb->control;
break; break;
case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_BULK:
if (is_in) if (qh->mux == 1) {
sched = &musb->in_bulk; if (is_in)
else sched = &musb->in_bulk;
sched = &musb->out_bulk; else
break; sched = &musb->out_bulk;
break;
}
default: default:
/* REVISIT when we get a schedule tree, periodic transfers /* REVISIT when we get a schedule tree, periodic transfers
* won't always be at the head of a singleton queue... * won't always be at the head of a singleton queue...

View File

@ -53,6 +53,7 @@ struct musb_qh {
struct list_head ring; /* of musb_qh */ struct list_head ring; /* of musb_qh */
/* struct musb_qh *next; */ /* for periodic tree */ /* struct musb_qh *next; */ /* for periodic tree */
u8 mux; /* qh multiplexed to hw_ep */
unsigned offset; /* in urb->transfer_buffer */ unsigned offset; /* in urb->transfer_buffer */
unsigned segsize; /* current xfer fragment */ unsigned segsize; /* current xfer fragment */

View File

@ -53,7 +53,9 @@ static void musb_do_idle(unsigned long _musb)
{ {
struct musb *musb = (void *)_musb; struct musb *musb = (void *)_musb;
unsigned long flags; unsigned long flags;
#ifdef CONFIG_USB_MUSB_HDRC_HCD
u8 power; u8 power;
#endif
u8 devctl; u8 devctl;
devctl = musb_readb(musb->mregs, MUSB_DEVCTL); devctl = musb_readb(musb->mregs, MUSB_DEVCTL);

View File

@ -605,7 +605,7 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
if (musb->board_mode != MUSB_OTG) { if (musb->board_mode != MUSB_OTG) {
ERR("Changing mode currently only supported in OTG mode\n"); ERR("Changing mode currently only supported in OTG mode\n");
return; return -EINVAL;
} }
otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT);

View File

@ -67,6 +67,7 @@ static struct usb_device_id id_table [] = {
{ 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 */
{ USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */
{ USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
{ USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */
{ USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
@ -85,6 +86,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
{ USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
{ USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */

View File

@ -160,6 +160,11 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define NOVATELWIRELESS_VENDOR_ID 0x1410 #define NOVATELWIRELESS_VENDOR_ID 0x1410
/* YISO PRODUCTS */
#define YISO_VENDOR_ID 0x0EAB
#define YISO_PRODUCT_U893 0xC893
/* MERLIN EVDO PRODUCTS */ /* MERLIN EVDO PRODUCTS */
#define NOVATELWIRELESS_PRODUCT_V640 0x1100 #define NOVATELWIRELESS_PRODUCT_V640 0x1100
#define NOVATELWIRELESS_PRODUCT_V620 0x1110 #define NOVATELWIRELESS_PRODUCT_V620 0x1110
@ -408,6 +413,7 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
{ USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) }, { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) },
{ USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) }, { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
{ USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) },

View File

@ -2,8 +2,8 @@
# USB Storage driver configuration # USB Storage driver configuration
# #
comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'" comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;"
comment "may also be needed; see USB_STORAGE Help for more information" comment "see USB_STORAGE Help for more information"
depends on USB depends on USB
config USB_STORAGE config USB_STORAGE

View File

@ -253,6 +253,14 @@ UNUSUAL_DEV( 0x0421, 0x006a, 0x0000, 0x0591,
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ), US_FL_FIX_CAPACITY ),
/* Submitted by Ricky Wong Yung Fei <evilbladewarrior@gmail.com> */
/* Nokia 7610 Supernova - Too many sectors reported in usb storage mode */
UNUSUAL_DEV( 0x0421, 0x00f5, 0x0000, 0x0470,
"Nokia",
"7610 Supernova",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
"SMSC", "SMSC",
@ -418,6 +426,13 @@ UNUSUAL_DEV( 0x04b0, 0x0417, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY), US_FL_FIX_CAPACITY),
/* Reported by paul ready <lxtwin@homecall.co.uk> */
UNUSUAL_DEV( 0x04b0, 0x0419, 0x0100, 0x0200,
"NIKON",
"NIKON DSC D300",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY),
/* Reported by Doug Maxey (dwm@austin.ibm.com) */ /* Reported by Doug Maxey (dwm@austin.ibm.com) */
UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x0110, UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x0110,
"IBM", "IBM",
@ -1258,6 +1273,13 @@ UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001,
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY), US_FL_FIX_INQUIRY),
/* Reported by Luciano Rocha <luciano@eurotux.com> */
UNUSUAL_DEV( 0x0840, 0x0082, 0x0001, 0x0001,
"Argosy",
"Storage",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY),
/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
* Flag will support Bulk devices which use a standards-violating 32-byte * Flag will support Bulk devices which use a standards-violating 32-byte
* Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with

View File

@ -108,6 +108,7 @@ enum usb_interface_condition {
* (in probe()), bound to a driver, or unbinding (in disconnect()) * (in probe()), bound to a driver, or unbinding (in disconnect())
* @is_active: flag set when the interface is bound and not suspended. * @is_active: flag set when the interface is bound and not suspended.
* @sysfs_files_created: sysfs attributes exist * @sysfs_files_created: sysfs attributes exist
* @unregistering: flag set when the interface is being unregistered
* @needs_remote_wakeup: flag set when the driver requires remote-wakeup * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
* capability during autosuspend. * capability during autosuspend.
* @needs_altsetting0: flag set when a set-interface request for altsetting 0 * @needs_altsetting0: flag set when a set-interface request for altsetting 0
@ -163,6 +164,7 @@ struct usb_interface {
enum usb_interface_condition condition; /* state of binding */ enum usb_interface_condition condition; /* state of binding */
unsigned is_active:1; /* the interface is not suspended */ unsigned is_active:1; /* the interface is not suspended */
unsigned sysfs_files_created:1; /* the sysfs attributes exist */ unsigned sysfs_files_created:1; /* the sysfs attributes exist */
unsigned unregistering:1; /* unregistration is in progress */
unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */
unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned needs_binding:1; /* needs delayed unbind/rebind */