Commit dd26bf6d 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: (22 commits)
  WUSB: correct format of wusb_chid sysfs file
  WUSB: fix oops when completing URBs for disconnected devices
  WUSB: disconnect all devices when stopping a WUSB HCD
  USB: whci-hcd: check return value of usb_hcd_link_urb_to_ep()
  USB: whci-hcd: provide a endpoint_reset method
  USB: add reset endpoint operations
  USB device codes for Motorola phone.
  usb-storage: fix mistake in Makefile
  USB: usb-serial ch341: support for DTR/RTS/CTS
  Revert USB: usb-serial ch341: support for DTR/RTS/CTS
  USB: musb: fix possible panic while resuming
  USB: musb: fix isochronous TXDMA (take 2)
  USB: musb: sanitize clearing TXCSR DMA bits (take 2)
  USB: musb: bugfixes for multi-packet TXDMA support
  USB: musb_host, fix ep0 fifo flushing
  USB: usb-storage: augment unusual_devs entry for Simple Tech/Datafab
  USB: musb_host, minor enqueue locking fix (v2)
  USB: fix oops in cdc-wdm in case of malformed descriptors
  USB: qcserial: Add extra device IDs
  USB: option: Add ids for D-Link DWM-652 3.5G modem
  ...
parents 7217fa98 fca10c81
......@@ -1025,6 +1025,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{
struct urb *urb = &sc->work_urb;
struct bulk_cs_wrap *bcs;
int endp;
int len;
int rc;
......@@ -1033,6 +1034,10 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
return;
}
endp = usb_pipeendpoint(sc->last_pipe);
if (usb_pipein(sc->last_pipe))
endp |= USB_DIR_IN;
if (cmd->state == UB_CMDST_CLEAR) {
if (urb->status == -EPIPE) {
/*
......@@ -1048,9 +1053,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
* We ignore the result for the halt clear.
*/
/* reset the endpoint toggle */
usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
usb_pipeout(sc->last_pipe), 0);
usb_reset_endpoint(sc->dev, endp);
ub_state_sense(sc, cmd);
......@@ -1065,9 +1068,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
* We ignore the result for the halt clear.
*/
/* reset the endpoint toggle */
usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
usb_pipeout(sc->last_pipe), 0);
usb_reset_endpoint(sc->dev, endp);
ub_state_stat(sc, cmd);
......@@ -1082,9 +1083,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
* We ignore the result for the halt clear.
*/
/* reset the endpoint toggle */
usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
usb_pipeout(sc->last_pipe), 0);
usb_reset_endpoint(sc->dev, endp);
ub_state_stat_counted(sc, cmd);
......@@ -2119,8 +2118,7 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe)
del_timer_sync(&timer);
usb_kill_urb(&sc->work_urb);
/* reset the endpoint toggle */
usb_settoggle(sc->dev, endp, usb_pipeout(sc->last_pipe), 0);
usb_reset_endpoint(sc->dev, endp);
return 0;
}
......
......@@ -149,14 +149,7 @@ static void usb_ctrl_complete(struct urb *urb)
if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) {
/* Special case handling for pipe reset */
le16_to_cpus(&ctrl_msg->dr.wIndex);
/* toggle is reset on clear */
usb_settoggle(adapter->usb_dev,
ctrl_msg->dr.wIndex & ~USB_DIR_IN,
(ctrl_msg->dr.wIndex & USB_DIR_IN) == 0,
0);
usb_reset_endpoint(adapter->usb_dev, ctrl_msg->dr.wIndex);
}
if (ctrl_msg->complete)
......
......@@ -1461,7 +1461,6 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
return ret;
}
usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
......
......@@ -652,7 +652,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
iface = &intf->altsetting[0];
ep = &iface->endpoint[0].desc;
if (!usb_endpoint_is_int_in(ep)) {
if (!ep || !usb_endpoint_is_int_in(ep)) {
rv = -EINVAL;
goto err;
}
......
......@@ -841,7 +841,7 @@ static int proc_resetep(struct dev_state *ps, void __user *arg)
ret = checkintf(ps, ret);
if (ret)
return ret;
usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0);
usb_reset_endpoint(ps->dev, ep);
return 0;
}
......
......@@ -1539,6 +1539,32 @@ void usb_hcd_disable_endpoint(struct usb_device *udev,
hcd->driver->endpoint_disable(hcd, ep);
}
/**
* usb_hcd_reset_endpoint - reset host endpoint state
* @udev: USB device.
* @ep: the endpoint to reset.
*
* Resets any host endpoint state such as the toggle bit, sequence
* number and current window.
*/
void usb_hcd_reset_endpoint(struct usb_device *udev,
struct usb_host_endpoint *ep)
{
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
if (hcd->driver->endpoint_reset)
hcd->driver->endpoint_reset(hcd, ep);
else {
int epnum = usb_endpoint_num(&ep->desc);
int is_out = usb_endpoint_dir_out(&ep->desc);
int is_control = usb_endpoint_xfer_control(&ep->desc);
usb_settoggle(udev, epnum, is_out, 0);
if (is_control)
usb_settoggle(udev, epnum, !is_out, 0);
}
}
/* Protect against drivers that try to unlink URBs after the device
* is gone, by waiting until all unlinks for @udev are finished.
* Since we don't currently track URBs by device, simply wait until
......
......@@ -206,6 +206,11 @@ struct hc_driver {
void (*endpoint_disable)(struct usb_hcd *hcd,
struct usb_host_endpoint *ep);
/* (optional) reset any endpoint state such as sequence number
and current window */
void (*endpoint_reset)(struct usb_hcd *hcd,
struct usb_host_endpoint *ep);
/* root hub support */
int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
int (*hub_control) (struct usb_hcd *hcd,
......@@ -234,6 +239,8 @@ extern void usb_hcd_flush_endpoint(struct usb_device *udev,
struct usb_host_endpoint *ep);
extern void usb_hcd_disable_endpoint(struct usb_device *udev,
struct usb_host_endpoint *ep);
extern void usb_hcd_reset_endpoint(struct usb_device *udev,
struct usb_host_endpoint *ep);
extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
extern int usb_hcd_get_frame_number(struct usb_device *udev);
......@@ -279,6 +286,13 @@ extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
extern void usb_hc_died(struct usb_hcd *hcd);
extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep)))
#define usb_settoggle(dev, ep, out, bit) \
((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \
((bit) << (ep)))
/* -------------------------------------------------------------------------- */
/* Enumeration is only for the hub driver, or HCD virtual root hubs */
......
......@@ -1002,8 +1002,7 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
* the copy in usb-storage, for as long as we need two copies.
*/
/* toggle was reset by the clear */
usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
usb_reset_endpoint(dev, endp);
return 0;
}
......@@ -1075,6 +1074,30 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
}
}
/**
* usb_reset_endpoint - Reset an endpoint's state.
* @dev: the device whose endpoint is to be reset
* @epaddr: the endpoint's address. Endpoint number for output,
* endpoint number + USB_DIR_IN for input
*
* Resets any host-side endpoint state such as the toggle bit,
* sequence number or current window.
*/
void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr)
{
unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
struct usb_host_endpoint *ep;
if (usb_endpoint_out(epaddr))
ep = dev->ep_out[epnum];
else
ep = dev->ep_in[epnum];
if (ep)
usb_hcd_reset_endpoint(dev, ep);
}
EXPORT_SYMBOL_GPL(usb_reset_endpoint);
/**
* usb_disable_interface -- Disable all endpoints for an interface
* @dev: the device whose interface is being disabled
......@@ -1117,7 +1140,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
usb_disable_endpoint(dev, i, true);
usb_disable_endpoint(dev, i + USB_DIR_IN, true);
}
dev->toggle[0] = dev->toggle[1] = 0;
/* getting rid of interfaces will disconnect
* any drivers bound to them (a key side effect)
......@@ -1154,28 +1176,24 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
* usb_enable_endpoint - Enable an endpoint for USB communications
* @dev: the device whose interface is being enabled
* @ep: the endpoint
* @reset_toggle: flag to set the endpoint's toggle back to 0
* @reset_ep: flag to reset the endpoint state
*
* Resets the endpoint toggle if asked, and sets dev->ep_{in,out} pointers.
* Resets the endpoint state if asked, and sets dev->ep_{in,out} pointers.
* For control endpoints, both the input and output sides are handled.
*/
void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,
bool reset_toggle)
bool reset_ep)
{
int epnum = usb_endpoint_num(&ep->desc);
int is_out = usb_endpoint_dir_out(&ep->desc);
int is_control = usb_endpoint_xfer_control(&ep->desc);
if (is_out || is_control) {
if (reset_toggle)
usb_settoggle(dev, epnum, 1, 0);
if (reset_ep)
usb_hcd_reset_endpoint(dev, ep);
if (is_out || is_control)
dev->ep_out[epnum] = ep;
}
if (!is_out || is_control) {
if (reset_toggle)
usb_settoggle(dev, epnum, 0, 0);
if (!is_out || is_control)
dev->ep_in[epnum] = ep;
}
ep->enabled = 1;
}
......@@ -1183,18 +1201,18 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,
* usb_enable_interface - Enable all the endpoints for an interface
* @dev: the device whose interface is being enabled
* @intf: pointer to the interface descriptor
* @reset_toggles: flag to set the endpoints' toggles back to 0
* @reset_eps: flag to reset the endpoints' state
*
* Enables all the endpoints for the interface's current altsetting.
*/
void usb_enable_interface(struct usb_device *dev,
struct usb_interface *intf, bool reset_toggles)
struct usb_interface *intf, bool reset_eps)
{
struct usb_host_interface *alt = intf->cur_altsetting;
int i;
for (i = 0; i < alt->desc.bNumEndpoints; ++i)
usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles);
usb_enable_endpoint(dev, &alt->endpoint[i], reset_eps);
}
/**
......@@ -1335,7 +1353,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface);
* This issues a standard SET_CONFIGURATION request to the device using
* the current configuration. The effect is to reset most USB-related
* state in the device, including interface altsettings (reset to zero),
* endpoint halts (cleared), and data toggle (only for bulk and interrupt
* endpoint halts (cleared), and endpoint state (only for bulk and interrupt
* endpoints). Other usbcore state is unchanged, including bindings of
* usb device drivers to interfaces.
*
......@@ -1343,7 +1361,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface);
* (multi-interface) devices. Instead, the driver for each interface may
* use usb_set_interface() on the interfaces it claims. Be careful though;
* some devices don't support the SET_INTERFACE request, and others won't
* reset all the interface state (notably data toggles). Resetting the whole
* reset all the interface state (notably endpoint state). Resetting the whole
* configuration would affect other drivers' interfaces.
*
* The caller must own the device lock.
......@@ -1376,8 +1394,6 @@ int usb_reset_configuration(struct usb_device *dev)
if (retval < 0)
return retval;
dev->toggle[0] = dev->toggle[1] = 0;
/* re-init hc/hcd interface/endpoint state */
for (i = 0; i < config->desc.bNumInterfaces; i++) {
struct usb_interface *intf = config->interface[i];
......
......@@ -362,7 +362,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
/* ep0 maxpacket comes later, from device descriptor */
usb_enable_endpoint(dev, &dev->ep0, true);
usb_enable_endpoint(dev, &dev->ep0, false);
dev->can_submit = 1;
/* Save readable and stable topology id, distinguishing devices
......
......@@ -175,12 +175,6 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info);
}
static u32 eth_get_link(struct net_device *net)
{
struct eth_dev *dev = netdev_priv(net);
return dev->gadget->speed != USB_SPEED_UNKNOWN;
}
/* REVISIT can also support:
* - WOL (by tracking suspends and issuing remote wakeup)
* - msglevel (implies updated messaging)
......@@ -189,7 +183,7 @@ static u32 eth_get_link(struct net_device *net)
static struct ethtool_ops ops = {
.get_drvinfo = eth_get_drvinfo,
.get_link = eth_get_link
.get_link = ethtool_op_get_link,
};
static void defer_kevent(struct eth_dev *dev, int flag)
......
......@@ -122,7 +122,8 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
process_inactive_qtd(whc, qset, td);
}
update |= qset_add_qtds(whc, qset);
if (!qset->remove)
update |= qset_add_qtds(whc, qset);
done:
/*
......@@ -254,23 +255,29 @@ int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
spin_lock_irqsave(&whc->lock, flags);
err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
if (err < 0) {
spin_unlock_irqrestore(&whc->lock, flags);
return err;
}
qset = get_qset(whc, urb, GFP_ATOMIC);
if (qset == NULL)
err = -ENOMEM;
else
err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
if (!err) {
usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
if (!qset->in_sw_list)
asl_qset_insert_begin(whc, qset);
}
} else
usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);
spin_unlock_irqrestore(&whc->lock, flags);
if (!err)
queue_work(whc->workqueue, &whc->async_work);
return 0;
return err;
}
/**
......
......@@ -186,6 +186,28 @@ static void whc_endpoint_disable(struct usb_hcd *usb_hcd,
}
}
static void whc_endpoint_reset(struct usb_hcd *usb_hcd,
struct usb_host_endpoint *ep)
{
struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
struct whc *whc = wusbhc_to_whc(wusbhc);
struct whc_qset *qset;
qset = ep->hcpriv;
if (qset) {
qset->remove = 1;
if (usb_endpoint_xfer_bulk(&ep->desc)
|| usb_endpoint_xfer_control(&ep->desc))
queue_work(whc->workqueue, &whc->async_work);
else
queue_work(whc->workqueue, &whc->periodic_work);
qset_reset(whc, qset);
}
}
static struct hc_driver whc_hc_driver = {
.description = "whci-hcd",
.product_desc = "Wireless host controller",
......@@ -200,6 +222,7 @@ static struct hc_driver whc_hc_driver = {
.urb_enqueue = whc_urb_enqueue,
.urb_dequeue = whc_urb_dequeue,
.endpoint_disable = whc_endpoint_disable,
.endpoint_reset = whc_endpoint_reset,
.hub_status_data = wusbhc_rh_status_data,
.hub_control = wusbhc_rh_control,
......
......@@ -128,7 +128,8 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset)
process_inactive_qtd(whc, qset, td);
}
update |= qset_add_qtds(whc, qset);
if (!qset->remove)
update |= qset_add_qtds(whc, qset);
done:
/*
......@@ -282,23 +283,29 @@ int pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
spin_lock_irqsave(&whc->lock, flags);
err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
if (err < 0) {
spin_unlock_irqrestore(&whc->lock, flags);
return err;
}
qset = get_qset(whc, urb, GFP_ATOMIC);
if (qset == NULL)
err = -ENOMEM;
else
err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
if (!err) {
usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
if (!qset->in_sw_list)
qset_insert_in_sw_list(whc, qset);
}
} else
usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);
spin_unlock_irqrestore(&whc->lock, flags);
if (!err)
queue_work(whc->workqueue, &whc->periodic_work);
return 0;
return err;
}
/**
......@@ -353,7 +360,6 @@ void pzl_qset_delete(struct whc *whc, struct whc_qset *qset)
qset_delete(whc, qset);
}
/**
* pzl_init - initialize the periodic zone list
* @whc: the WHCI host controller
......
......@@ -89,11 +89,16 @@ static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
QH_INFO3_TX_RATE_53_3
| QH_INFO3_TX_PWR(0) /* 0 == max power */
);
qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1);
}
/**
* qset_clear - clear fields in a qset so it may be reinserted into a
* schedule
* schedule.
*
* The sequence number and current window are not cleared (see
* qset_reset()).
*/
void qset_clear(struct whc *whc, struct whc_qset *qset)
{
......@@ -101,9 +106,8 @@ void qset_clear(struct whc *whc, struct whc_qset *qset)
qset->remove = 0;
qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T);
qset->qh.status = cpu_to_le16(QH_STATUS_ICUR(qset->td_start));
qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK;
qset->qh.err_count = 0;
qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1);
qset->qh.scratch[0] = 0;
qset->qh.scratch[1] = 0;
qset->qh.scratch[2] = 0;
......@@ -113,6 +117,20 @@ void qset_clear(struct whc *whc, struct whc_qset *qset)
init_completion(&qset->remove_complete);
}
/**
* qset_reset - reset endpoint state in a qset.
*
* Clears the sequence number and current window. This qset must not
* be in the ASL or PZL.
*/
void qset_reset(struct whc *whc, struct whc_qset *qset)
{
wait_for_completion(&qset->remove_complete);
qset->qh.status &= ~QH_STATUS_SEQ_MASK;
qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1);
}
/**
* get_qset - get the qset for an async endpoint
*
......
......@@ -184,6 +184,7 @@ void qset_free(struct whc *whc, struct whc_qset *qset);
struct whc_qset *get_qset(struct whc *whc, struct urb *urb, gfp_t mem_flags);
void qset_delete(struct whc *whc, struct whc_qset *qset);
void qset_clear(struct whc *whc, struct whc_qset *qset);
void qset_reset(struct whc *whc, struct whc_qset *qset);
int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb,
gfp_t mem_flags);
void qset_free_std(struct whc *whc, struct whc_std *std);
......
......@@ -185,6 +185,7 @@ struct whc_qhead {
#define QH_STATUS_FLOW_CTRL (1 << 15)
#define QH_STATUS_ICUR(i) ((i) << 5)
#define QH_STATUS_TO_ICUR(s) (((s) >> 5) & 0x7)
#define QH_STATUS_SEQ_MASK 0x1f
/**
* usb_pipe_to_qh_type - USB core pipe type to QH transfer type
......
......@@ -579,6 +579,7 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx)
* trigger the "send a ZLP?" confusion.
*/
rndis = (maxpacket & 0x3f) == 0
&& length > maxpacket
&& length < 0xffff
&& (length % maxpacket) != 0;
......@@ -1228,27 +1229,7 @@ void cppi_completion(struct musb *musb, u32 rx, u32 tx)
hw_ep = tx_ch->hw_ep;
/* Peripheral role never repurposes the
* endpoint, so immediate completion is
* safe. Host role waits for the fifo
* to empty (TXPKTRDY irq) before going
* to the next queued bulk transfer.
*/
if (is_host_active(cppi->musb)) {
#if 0
/* WORKAROUND because we may
* not always get TXKPTRDY ...
*/
int csr;
csr = musb_readw(hw_ep->regs,
MUSB_TXCSR);
if (csr & MUSB_TXCSR_TXPKTRDY)
#endif
completed = false;
}
if (completed)
musb_dma_completion(musb, index + 1, 1);
musb_dma_completion(musb, index + 1, 1);
} else {
/* Bigger transfer than we could fit in
......
......@@ -2170,26 +2170,22 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
return 0;
}
static int musb_resume(struct platform_device *pdev)
static int musb_resume_early(struct platform_device *pdev)
{
unsigned long flags;
struct musb *musb = dev_to_musb(&pdev->dev);
if (!musb->clock)
return 0;
spin_lock_irqsave(&musb->lock, flags);
if (musb->set_clock)
musb->set_clock(musb->clock, 1);
else
clk_enable(musb->clock);
/* for static cmos like DaVinci, register values were preserved
* unless for some reason the whole soc powered down and we're
* not treating that as a whole-system restart (e.g. swsusp)
* unless for some reason the whole soc powered down or the USB
* module got reset through the PSC (vs just being disabled).
*/
spin_unlock_irqrestore(&musb->lock, flags);
return 0;
}
......@@ -2207,7 +2203,7 @@ static struct platform_driver musb_driver = {
.remove = __devexit_p(musb_remove),
.shutdown = musb_shutdown,
.suspend = musb_suspend,
.resume = musb_resume,
.resume_early = musb_resume_early,
};
/*-------------------------------------------------------------------------*/
......
......@@ -165,9 +165,15 @@ static void nuke(struct musb_ep *ep, const int status)
if (is_dma_capable() && ep->dma) {
struct dma_controller *c = ep->musb->dma_controller;
int value;
if (ep->is_in) {
/*
* The programming guide says that we must not clear
* the DMAMODE bit before DMAENAB, so we only
* clear it in the second write...
*/
musb_writew(epio, MUSB_TXCSR,
0 | MUSB_TXCSR_FLUSHFIFO);
MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO);
musb_writew(epio, MUSB_TXCSR,
0 | MUSB_TXCSR_FLUSHFIFO);
} else {
......@@ -230,7 +236,7 @@ static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep)
| IN token(s) are recd from Host.
| -> DMA interrupt on completion
| calls TxAvail.
| -> stop DMA, ~DmaEenab,
| -> stop DMA, ~DMAENAB,
| -> set TxPktRdy for last short pkt or zlp
| -> Complete Request
| -> Continue next request (call txstate)
......@@ -315,9 +321,17 @@ static void txstate(struct musb *musb, struct musb_request *req)
request->dma, request_size);
if (use_dma) {
if (musb_ep->dma->desired_mode == 0) {
/* ASSERT: DMAENAB is clear */
csr &= ~(MUSB_TXCSR_AUTOSET |
MUSB_TXCSR_DMAMODE);
/*
* We must not clear the DMAMODE bit
* before the DMAENAB bit -- and the
* latter doesn't always get cleared
* before we get here...
*/
csr &= ~(MUSB_TXCSR_AUTOSET
| MUSB_TXCSR_DMAENAB);
musb_writew(epio, MUSB_TXCSR, csr
| MUSB_TXCSR_P_WZC_BITS);
csr &= ~MUSB_TXCSR_DMAMODE;
csr |= (MUSB_TXCSR_DMAENAB |
MUSB_TXCSR_MODE);
/* against programming guide */
......@@ -334,10 +348,7 @@ static void txstate(struct musb *musb, struct musb_request *req)
#elif defined(CONFIG_USB_TI_CPPI_DMA)
/* program endpoint CSR first, then setup DMA */
csr &= ~(MUSB_TXCSR_AUTOSET
| MUSB_TXCSR_DMAMODE
| MUSB_TXCSR_P_UNDERRUN
| MUSB_TXCSR_TXPKTRDY);
csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);
csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB;
musb_writew(epio, MUSB_TXCSR,
(MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN)
......@@ -364,8 +375,8 @@ static void txstate(struct musb *musb, struct musb_request *req)
if (!use_dma) {
c->channel_release(musb_ep->dma);
musb_ep->dma = NULL;
/* ASSERT: DMAENAB clear */
csr &= ~(MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE);
csr &= ~MUSB_TXCSR_DMAENAB;
musb_writew(epio, MUSB_TXCSR, csr);
/* invariant: prequest->buf is non-null */
}
#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
......
This diff is collapsed.
......@@ -195,30 +195,32 @@ static int dma_channel_abort(struct dma_channel *channel)
void __iomem *mbase = musb_channel->controller->base;
u8 bchannel = musb_channel->idx;
int offset;
u16 csr;
if (channel->status == MUSB_DMA_STATUS_BUSY) {
if (musb_channel->transmit) {
csr = musb_readw(mbase,
MUSB_EP_OFFSET(musb_channel->epnum,
MUSB_TXCSR));
csr &= ~(MUSB_TXCSR_AUTOSET |
MUSB_TXCSR_DMAENAB |
MUSB_TXCSR_DMAMODE);
musb_writew(mbase,
MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR),
csr);
offset = MUSB_EP_OFFSET(musb_channel->epnum,
MUSB_TXCSR);
/*
* The programming guide says that we must clear
* the DMAENAB bit before the DMAMODE bit...
*/
csr = musb_readw(mbase, offset);
csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
musb_writew(mbase, offset, csr);
csr &= ~MUSB_TXCSR_DMAMODE;
musb_writew(mbase, offset, csr);
} else {
csr = musb_readw(mbase,
MUSB_EP_OFFSET(musb_channel->epnum,
MUSB_RXCSR));
offset = MUSB_EP_OFFSET(musb_channel->epnum,
MUSB_RXCSR);
csr = musb_readw(mbase, offset);
csr &= ~(MUSB_RXCSR_AUTOCLEAR |
MUSB_RXCSR_DMAENAB |
MUSB_RXCSR_DMAMODE);
musb_writew(mbase,
MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR),
csr);
musb_writew(mbase, offset, csr);
}
musb_writew(mbase,
......@@ -296,20 +298,28 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
&& ((channel->desired_mode == 0)
|| (channel->actual_len &
(musb_channel->max_packet_sz - 1)))
) {
) {
u8 epnum = musb_channel->epnum;
int offset = MUSB_EP_OFFSET(epnum,
MUSB_TXCSR);
u16 txcsr;
/*
* The programming guide says that we
* must clear DMAENAB before DMAMODE.
*/
musb_ep_select(mbase, epnum);
txcsr = musb_readw(mbase, offset);
txcsr &= ~(MUSB_TXCSR_DMAENAB
| MUSB_TXCSR_AUTOSET);
musb_writew(mbase, offset, txcsr);
/* Send out the packet */
musb_ep_select(mbase,
musb_channel->epnum);
musb_writew(mbase, MUSB_EP_OFFSET(
musb_channel->epnum,
MUSB_TXCSR),
MUSB_TXCSR_TXPKTRDY);
} else {
musb_dma_completion(
musb,
musb_channel->epnum,
musb_channel->transmit);
txcsr &= ~MUSB_TXCSR_DMAMODE;
txcsr |= MUSB_TXCSR_TXPKTRDY;
musb_writew(mbase, offset, txcsr);
}
musb_dma_completion(musb, musb_channel->epnum,
musb_channel->transmit);
}
}
}
......
......@@ -668,6 +668,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(DE_VID, WHT_PID) },
{ USB_DEVICE(ADI_VID, ADI_GNICE_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
......
......@@ -912,6 +912,13 @@
#define ADI_VID 0x0456
#define ADI_GNICE_PID 0xF000
/*
* JETI SPECTROMETER SPECBOS 1201
* http://www.jeti.com/products/sys/scb/scb1201.php
*/
#define JETI_VID 0x0c6c
#define JETI_SPC1201_PID 0x04b2
/*
* BmRequestType: 1100 0000b
* bRequest: FTDI_E2_READ
......
......@@ -25,6 +25,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */
{ USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */
{ USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */
{ USB_DEVICE(0x22b8, 0x2c64) }, /* Motorola V950 phone */
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
......
......@@ -300,6 +300,10 @@ static int option_resume(struct usb_serial *serial);
#define BENQ_VENDOR_ID 0x04a5
#define BENQ_PRODUCT_H10 0x4068
#define DLINK_VENDOR_ID 0x1186
#define DLINK_PRODUCT_DWM_652 0x3e04
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
......@@ -516,6 +520,7 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
{ USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
{ } /* Terminating entry */
};
......
......@@ -26,6 +26,27 @@ static struct usb_device_id id_table[] = {
{USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
{USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
{USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */
{USB_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */
{USB_DEVICE(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */
{USB_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */
{USB_DEVICE(0x413c, 0x8171)}, /* Dell Gobi QDL device */
{USB_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */
{USB_DEVICE(0x1410, 0xa008)}, /* Novatel Gobi QDL device */
{USB_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */
{USB_DEVICE(0x0b05, 0x1774)}, /* Asus Gobi QDL device */
{USB_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */
{USB_DEVICE(0x19d2, 0xfff2)}, /* ONDA Gobi QDL device */
{USB_DEVICE(0x1557, 0x0a80)}, /* OQO Gobi QDL device */
{USB_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */
{USB_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */
{USB_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */
{USB_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */
{USB_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */
{USB_DEVICE(0x05c6, 0x9008)}, /* Generic Gobi QDL device */
{USB_DEVICE(0x05c6, 0x9201)}, /* Generic Gobi QDL device */
{USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */
{USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */
{USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);
......
......@@ -17,7 +17,8 @@ usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
ifeq ($(CONFIG_USB_LIBUSUAL),)
usb-storage-objs += usual-tables.o
else
obj-$(CONFIG_USB) += libusual.o usual-tables.o
obj-$(CONFIG_USB) += usb-libusual.o
usb-libusual-objs := libusual.o usual-tables.o
endif
obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o
......
......@@ -247,10 +247,8 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
USB_ENDPOINT_HALT, endp,
NULL, 0, 3*HZ);
/* reset the endpoint toggle */
if (result >= 0)
usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe),
usb_pipeout(pipe), 0);
usb_reset_endpoint(us->pusb_dev, endp);
US_DEBUGP("%s: result = %d\n", __func__, result);
return result;
......
......@@ -975,12 +975,14 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ),
/* Reported by Rauch Wolke <rauchwolke@gmx.net> */
/* Reported by Rauch Wolke <rauchwolke@gmx.net>
* and augmented by binbin <binbinsh@gmail.com> (Bugzilla #12882)
*/
UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff,
"Simple Tech/Datafab",
"CF+SM Reader",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
US_FL_IGNORE_RESIDUE | US_FL_MAX_SECTORS_64 ),
/* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
* to the USB storage specification in two ways:
......@@ -1376,6 +1378,14 @@ UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
0),
/* Reported by Pascal Terjan <pterjan@mandriva.com>
* Ignore driver CD mode and force into modem mode by default.
*/
UNUSUAL_DEV( 0x1186, 0x3e04, 0x0000, 0x0000,
"D-Link",
"USB Mass Storage",
US_SC_DEVICE, US_PR_DEVICE, option_ms_init, 0),
/* Reported by Kevin Lloyd <linux@sierrawireless.com>
* Entry is needed for the initializer function override,
* which instructs the device to load as a modem
......
......@@ -267,6 +267,8 @@ static void wusbhc_devconnect_acked_work(struct work_struct *work)
mutex_lock(&wusbhc->mutex);
wusbhc_devconnect_acked(wusbhc, wusb_dev);
mutex_unlock(&wusbhc->mutex);
wusb_dev_put(wusb_dev);
}
/*
......@@ -396,7 +398,8 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
/* After a device disconnects, change the GTK (see [WUSB]
* section 6.2.11.2). */
wusbhc_gtk_rekey(wusbhc);
if (wusbhc->active)
wusbhc_gtk_rekey(wusbhc);
/* The Wireless USB part has forgotten about the device already; now
* khubd's timer will pick up the disconnection and remove the USB
......@@ -1084,15 +1087,21 @@ int wusbhc_devconnect_start(struct wusbhc *wusbhc)
* wusbhc_devconnect_stop - stop managing connected devices
* @wusbhc: the WUSB HC
*
* Removes the Host Info IE and stops the keep alives.
*
* FIXME: should this disconnect all devices?
* Disconnects any devices still connected, stops the keep alives and
* removes the Host Info IE.
*/
void wusbhc_devconnect_stop(struct wusbhc *wusbhc)
{
cancel_delayed_work_sync(&wusbhc->keep_alive_timer);
WARN_ON(!list_empty(&wusbhc->cack_list));
int i;
mutex_lock(&wusbhc->mutex);
for (i = 0; i < wusbhc->ports_max; i++) {
if (wusbhc->port[i].wusb_dev)
__wusbhc_dev_disconnect(wusbhc, &wusbhc->port[i]);
}
mutex_unlock(&wusbhc->mutex);
cancel_delayed_work_sync(&wusbhc->keep_alive_timer);
wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr);
kfree(wusbhc->wuie_host_info);
wusbhc->wuie_host_info = NULL;
......
......@@ -88,33 +88,31 @@ static DEVICE_ATTR(wusb_trust_timeout, 0644, wusb_trust_timeout_show,
wusb_trust_timeout_store);
/*
* Show & store the current WUSB CHID
* Show the current WUSB CHID.
*/
static ssize_t wusb_chid_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
const struct wusb_ckhdid *chid;
ssize_t result = 0;
if (wusbhc->wuie_host_info != NULL)
result += ckhdid_printf(buf, PAGE_SIZE,
&wusbhc->wuie_host_info->CHID);
chid = &wusbhc->wuie_host_info->CHID;
else
chid = &wusb_ckhdid_zero;
result += ckhdid_printf(buf, PAGE_SIZE, chid);
result += sprintf(buf + result, "\n");
return result;
}
/*
* Store a new CHID
*
* This will (FIXME) trigger many changes.
*
* - Send an all zeros CHID and it will stop the controller
* - Send a non-zero CHID and it will start it
* (unless it was started, it will just change the CHID,
* diconnecting all devices first).
* Store a new CHID.
*
* So first we scan the MMC we are sent and then we act on it. We
* read it in the same format as we print it, an ASCII string of 16
* hex bytes.
* - Write an all zeros CHID and it will stop the controller
* - Write a non-zero CHID and it will start it.
*
* See wusbhc_chid_set() for more info.
*/
......@@ -339,13 +337,15 @@ void wusbhc_giveback_urb(struct wusbhc *wusbhc, struct urb *urb, int status)
{
struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev);
if (status == 0) {
if (status == 0 && wusb_dev) {
wusb_dev->entry_ts = jiffies;
/* wusbhc_devconnect_acked() can't be called from from
/* wusbhc_devconnect_acked() can't be called from
atomic context so defer it to a work queue. */
if (!list_empty(&wusb_dev->cack_node))
queue_work(wusbd, &wusb_dev->devconnect_acked_work);
else
wusb_dev_put(wusb_dev);
}
usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status);
......
......@@ -1387,6 +1387,7 @@ extern int usb_string(struct usb_device *dev, int index,
extern int usb_clear_halt(struct usb_device *dev, int pipe);
extern int usb_reset_configuration(struct usb_device *dev);
extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
extern void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr);
/* this request isn't really synchronous, but it belongs with the others */
extern int usb_driver_set_configuration(struct usb_device *udev, int config);
......@@ -1491,14 +1492,6 @@ void usb_sg_wait(struct usb_sg_request *io);
#define usb_pipecontrol(pipe) (usb_pipetype((pipe)) == PIPE_CONTROL)
#define usb_pipebulk(pipe) (usb_pipetype((pipe)) == PIPE_BULK)
/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep)))
#define usb_settoggle(dev, ep, out, bit) \
((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \
((bit) << (ep)))
static inline unsigned int __create_pipe(struct usb_device *dev,
unsigned int endpoint)
{
......
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