Commit 3a69c9e5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-5.4-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "The USB sub-maintainers woke up this past week and sent a bunch of
  tiny fixes. Here are a lot of small patches that that resolve a bunch
  of reported issues in the USB core, drivers, serial drivers, gadget
  drivers, and of course, xhci :)

  All of these have been in linux-next with no reported issues"

* tag 'usb-5.4-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (31 commits)
  usb: dwc3: gadget: fix race when disabling ep with cancelled xfers
  usb: cdns3: gadget: Fix g_audio use case when connected to Super-Speed host
  usb: cdns3: gadget: reset EP_CLAIMED flag while unloading
  USB: serial: whiteheat: fix line-speed endianness
  USB: serial: whiteheat: fix potential slab corruption
  USB: gadget: Reject endpoints with 0 maxpacket value
  UAS: Revert commit 3ae62a42 ("UAS: fix alignment of scatter/gather segments")
  usb-storage: Revert commit 747668db ("usb-storage: Set virt_boundary_mask to avoid SG overflows")
  usbip: Fix free of unallocated memory in vhci tx
  usbip: tools: Fix read_usb_vudc_device() error path handling
  usb: xhci: fix __le32/__le64 accessors in debugfs code
  usb: xhci: fix Immediate Data Transfer endianness
  xhci: Fix use-after-free regression in xhci clear hub TT implementation
  USB: ldusb: fix control-message timeout
  USB: ldusb: use unsigned size format specifiers
  USB: ldusb: fix ring-buffer locking
  USB: Skip endpoints with 0 maxpacket length
  usb: cdns3: gadget: Don't manage pullups
  usb: dwc3: remove the call trace of USBx_GFLADJ
  usb: gadget: configfs: fix concurrent issue between composite APIs
  ...
parents 56cfd250 d8eca64e
...@@ -2329,8 +2329,6 @@ static void cdns3_gadget_config(struct cdns3_device *priv_dev) ...@@ -2329,8 +2329,6 @@ static void cdns3_gadget_config(struct cdns3_device *priv_dev)
writel(USB_CONF_CLK2OFFDS | USB_CONF_L1DS, &regs->usb_conf); writel(USB_CONF_CLK2OFFDS | USB_CONF_L1DS, &regs->usb_conf);
cdns3_configure_dmult(priv_dev, NULL); cdns3_configure_dmult(priv_dev, NULL);
cdns3_gadget_pullup(&priv_dev->gadget, 1);
} }
/** /**
...@@ -2345,9 +2343,35 @@ static int cdns3_gadget_udc_start(struct usb_gadget *gadget, ...@@ -2345,9 +2343,35 @@ static int cdns3_gadget_udc_start(struct usb_gadget *gadget,
{ {
struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget);
unsigned long flags; unsigned long flags;
enum usb_device_speed max_speed = driver->max_speed;
spin_lock_irqsave(&priv_dev->lock, flags); spin_lock_irqsave(&priv_dev->lock, flags);
priv_dev->gadget_driver = driver; priv_dev->gadget_driver = driver;
/* limit speed if necessary */
max_speed = min(driver->max_speed, gadget->max_speed);
switch (max_speed) {
case USB_SPEED_FULL:
writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf);
writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf);
break;
case USB_SPEED_HIGH:
writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf);
break;
case USB_SPEED_SUPER:
break;
default:
dev_err(priv_dev->dev,
"invalid maximum_speed parameter %d\n",
max_speed);
/* fall through */
case USB_SPEED_UNKNOWN:
/* default to superspeed */
max_speed = USB_SPEED_SUPER;
break;
}
cdns3_gadget_config(priv_dev); cdns3_gadget_config(priv_dev);
spin_unlock_irqrestore(&priv_dev->lock, flags); spin_unlock_irqrestore(&priv_dev->lock, flags);
return 0; return 0;
...@@ -2381,6 +2405,8 @@ static int cdns3_gadget_udc_stop(struct usb_gadget *gadget) ...@@ -2381,6 +2405,8 @@ static int cdns3_gadget_udc_stop(struct usb_gadget *gadget)
writel(EP_CMD_EPRST, &priv_dev->regs->ep_cmd); writel(EP_CMD_EPRST, &priv_dev->regs->ep_cmd);
readl_poll_timeout_atomic(&priv_dev->regs->ep_cmd, val, readl_poll_timeout_atomic(&priv_dev->regs->ep_cmd, val,
!(val & EP_CMD_EPRST), 1, 100); !(val & EP_CMD_EPRST), 1, 100);
priv_ep->flags &= ~EP_CLAIMED;
} }
/* disable interrupt for device */ /* disable interrupt for device */
...@@ -2575,12 +2601,7 @@ static int cdns3_gadget_start(struct cdns3 *cdns) ...@@ -2575,12 +2601,7 @@ static int cdns3_gadget_start(struct cdns3 *cdns)
/* Check the maximum_speed parameter */ /* Check the maximum_speed parameter */
switch (max_speed) { switch (max_speed) {
case USB_SPEED_FULL: case USB_SPEED_FULL:
writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf);
writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf);
break;
case USB_SPEED_HIGH: case USB_SPEED_HIGH:
writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf);
break;
case USB_SPEED_SUPER: case USB_SPEED_SUPER:
break; break;
default: default:
...@@ -2713,8 +2734,6 @@ static int cdns3_gadget_suspend(struct cdns3 *cdns, bool do_wakeup) ...@@ -2713,8 +2734,6 @@ static int cdns3_gadget_suspend(struct cdns3 *cdns, bool do_wakeup)
/* disable interrupt for device */ /* disable interrupt for device */
writel(0, &priv_dev->regs->usb_ien); writel(0, &priv_dev->regs->usb_ien);
cdns3_gadget_pullup(&priv_dev->gadget, 0);
return 0; return 0;
} }
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#ifdef CONFIG_USB_CDNS3_HOST #ifdef CONFIG_USB_CDNS3_HOST
int cdns3_host_init(struct cdns3 *cdns); int cdns3_host_init(struct cdns3 *cdns);
void cdns3_host_exit(struct cdns3 *cdns);
#else #else
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include "core.h" #include "core.h"
#include "drd.h" #include "drd.h"
#include "host-export.h"
static int __cdns3_host_init(struct cdns3 *cdns) static int __cdns3_host_init(struct cdns3 *cdns)
{ {
......
...@@ -348,6 +348,11 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, ...@@ -348,6 +348,11 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
/* Validate the wMaxPacketSize field */ /* Validate the wMaxPacketSize field */
maxp = usb_endpoint_maxp(&endpoint->desc); maxp = usb_endpoint_maxp(&endpoint->desc);
if (maxp == 0) {
dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has wMaxPacketSize 0, skipping\n",
cfgno, inum, asnum, d->bEndpointAddress);
goto skip_to_next_endpoint_or_interface_descriptor;
}
/* Find the highest legal maxpacket size for this endpoint */ /* Find the highest legal maxpacket size for this endpoint */
i = 0; /* additional transactions per microframe */ i = 0; /* additional transactions per microframe */
......
...@@ -102,6 +102,7 @@ config USB_DWC3_MESON_G12A ...@@ -102,6 +102,7 @@ config USB_DWC3_MESON_G12A
depends on ARCH_MESON || COMPILE_TEST depends on ARCH_MESON || COMPILE_TEST
default USB_DWC3 default USB_DWC3
select USB_ROLE_SWITCH select USB_ROLE_SWITCH
select REGMAP_MMIO
help help
Support USB2/3 functionality in Amlogic G12A platforms. Support USB2/3 functionality in Amlogic G12A platforms.
Say 'Y' or 'M' if you have one such device. Say 'Y' or 'M' if you have one such device.
......
...@@ -312,8 +312,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc) ...@@ -312,8 +312,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
dft = reg & DWC3_GFLADJ_30MHZ_MASK; dft = reg & DWC3_GFLADJ_30MHZ_MASK;
if (!dev_WARN_ONCE(dwc->dev, dft == dwc->fladj, if (dft != dwc->fladj) {
"request value same as default, ignoring\n")) {
reg &= ~DWC3_GFLADJ_30MHZ_MASK; reg &= ~DWC3_GFLADJ_30MHZ_MASK;
reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj; reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
......
...@@ -258,7 +258,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) ...@@ -258,7 +258,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
ret = platform_device_add_properties(dwc->dwc3, p); ret = platform_device_add_properties(dwc->dwc3, p);
if (ret < 0) if (ret < 0)
return ret; goto err;
ret = dwc3_pci_quirks(dwc); ret = dwc3_pci_quirks(dwc);
if (ret) if (ret)
......
...@@ -707,6 +707,12 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) ...@@ -707,6 +707,12 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
dwc3_gadget_giveback(dep, req, -ESHUTDOWN); dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
} }
while (!list_empty(&dep->cancelled_list)) {
req = next_request(&dep->cancelled_list);
dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
}
} }
/** /**
......
...@@ -2170,14 +2170,18 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) ...@@ -2170,14 +2170,18 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev)
usb_ep_dequeue(cdev->gadget->ep0, cdev->os_desc_req); usb_ep_dequeue(cdev->gadget->ep0, cdev->os_desc_req);
kfree(cdev->os_desc_req->buf); kfree(cdev->os_desc_req->buf);
cdev->os_desc_req->buf = NULL;
usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req); usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req);
cdev->os_desc_req = NULL;
} }
if (cdev->req) { if (cdev->req) {
if (cdev->setup_pending) if (cdev->setup_pending)
usb_ep_dequeue(cdev->gadget->ep0, cdev->req); usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
kfree(cdev->req->buf); kfree(cdev->req->buf);
cdev->req->buf = NULL;
usb_ep_free_request(cdev->gadget->ep0, cdev->req); usb_ep_free_request(cdev->gadget->ep0, cdev->req);
cdev->req = NULL;
} }
cdev->next_string_id = 0; cdev->next_string_id = 0;
device_remove_file(&cdev->gadget->dev, &dev_attr_suspended); device_remove_file(&cdev->gadget->dev, &dev_attr_suspended);
......
...@@ -61,6 +61,8 @@ struct gadget_info { ...@@ -61,6 +61,8 @@ struct gadget_info {
bool use_os_desc; bool use_os_desc;
char b_vendor_code; char b_vendor_code;
char qw_sign[OS_STRING_QW_SIGN_LEN]; char qw_sign[OS_STRING_QW_SIGN_LEN];
spinlock_t spinlock;
bool unbind;
}; };
static inline struct gadget_info *to_gadget_info(struct config_item *item) static inline struct gadget_info *to_gadget_info(struct config_item *item)
...@@ -1244,6 +1246,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget, ...@@ -1244,6 +1246,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
int ret; int ret;
/* the gi->lock is hold by the caller */ /* the gi->lock is hold by the caller */
gi->unbind = 0;
cdev->gadget = gadget; cdev->gadget = gadget;
set_gadget_data(gadget, cdev); set_gadget_data(gadget, cdev);
ret = composite_dev_prepare(composite, cdev); ret = composite_dev_prepare(composite, cdev);
...@@ -1376,31 +1379,128 @@ static void configfs_composite_unbind(struct usb_gadget *gadget) ...@@ -1376,31 +1379,128 @@ static void configfs_composite_unbind(struct usb_gadget *gadget)
{ {
struct usb_composite_dev *cdev; struct usb_composite_dev *cdev;
struct gadget_info *gi; struct gadget_info *gi;
unsigned long flags;
/* the gi->lock is hold by the caller */ /* the gi->lock is hold by the caller */
cdev = get_gadget_data(gadget); cdev = get_gadget_data(gadget);
gi = container_of(cdev, struct gadget_info, cdev); gi = container_of(cdev, struct gadget_info, cdev);
spin_lock_irqsave(&gi->spinlock, flags);
gi->unbind = 1;
spin_unlock_irqrestore(&gi->spinlock, flags);
kfree(otg_desc[0]); kfree(otg_desc[0]);
otg_desc[0] = NULL; otg_desc[0] = NULL;
purge_configs_funcs(gi); purge_configs_funcs(gi);
composite_dev_cleanup(cdev); composite_dev_cleanup(cdev);
usb_ep_autoconfig_reset(cdev->gadget); usb_ep_autoconfig_reset(cdev->gadget);
spin_lock_irqsave(&gi->spinlock, flags);
cdev->gadget = NULL; cdev->gadget = NULL;
set_gadget_data(gadget, NULL); set_gadget_data(gadget, NULL);
spin_unlock_irqrestore(&gi->spinlock, flags);
}
static int configfs_composite_setup(struct usb_gadget *gadget,
const struct usb_ctrlrequest *ctrl)
{
struct usb_composite_dev *cdev;
struct gadget_info *gi;
unsigned long flags;
int ret;
cdev = get_gadget_data(gadget);
if (!cdev)
return 0;
gi = container_of(cdev, struct gadget_info, cdev);
spin_lock_irqsave(&gi->spinlock, flags);
cdev = get_gadget_data(gadget);
if (!cdev || gi->unbind) {
spin_unlock_irqrestore(&gi->spinlock, flags);
return 0;
}
ret = composite_setup(gadget, ctrl);
spin_unlock_irqrestore(&gi->spinlock, flags);
return ret;
}
static void configfs_composite_disconnect(struct usb_gadget *gadget)
{
struct usb_composite_dev *cdev;
struct gadget_info *gi;
unsigned long flags;
cdev = get_gadget_data(gadget);
if (!cdev)
return;
gi = container_of(cdev, struct gadget_info, cdev);
spin_lock_irqsave(&gi->spinlock, flags);
cdev = get_gadget_data(gadget);
if (!cdev || gi->unbind) {
spin_unlock_irqrestore(&gi->spinlock, flags);
return;
}
composite_disconnect(gadget);
spin_unlock_irqrestore(&gi->spinlock, flags);
}
static void configfs_composite_suspend(struct usb_gadget *gadget)
{
struct usb_composite_dev *cdev;
struct gadget_info *gi;
unsigned long flags;
cdev = get_gadget_data(gadget);
if (!cdev)
return;
gi = container_of(cdev, struct gadget_info, cdev);
spin_lock_irqsave(&gi->spinlock, flags);
cdev = get_gadget_data(gadget);
if (!cdev || gi->unbind) {
spin_unlock_irqrestore(&gi->spinlock, flags);
return;
}
composite_suspend(gadget);
spin_unlock_irqrestore(&gi->spinlock, flags);
}
static void configfs_composite_resume(struct usb_gadget *gadget)
{
struct usb_composite_dev *cdev;
struct gadget_info *gi;
unsigned long flags;
cdev = get_gadget_data(gadget);
if (!cdev)
return;
gi = container_of(cdev, struct gadget_info, cdev);
spin_lock_irqsave(&gi->spinlock, flags);
cdev = get_gadget_data(gadget);
if (!cdev || gi->unbind) {
spin_unlock_irqrestore(&gi->spinlock, flags);
return;
}
composite_resume(gadget);
spin_unlock_irqrestore(&gi->spinlock, flags);
} }
static const struct usb_gadget_driver configfs_driver_template = { static const struct usb_gadget_driver configfs_driver_template = {
.bind = configfs_composite_bind, .bind = configfs_composite_bind,
.unbind = configfs_composite_unbind, .unbind = configfs_composite_unbind,
.setup = composite_setup, .setup = configfs_composite_setup,
.reset = composite_disconnect, .reset = configfs_composite_disconnect,
.disconnect = composite_disconnect, .disconnect = configfs_composite_disconnect,
.suspend = composite_suspend, .suspend = configfs_composite_suspend,
.resume = composite_resume, .resume = configfs_composite_resume,
.max_speed = USB_SPEED_SUPER, .max_speed = USB_SPEED_SUPER,
.driver = { .driver = {
......
...@@ -449,9 +449,11 @@ static void submit_request(struct usba_ep *ep, struct usba_request *req) ...@@ -449,9 +449,11 @@ static void submit_request(struct usba_ep *ep, struct usba_request *req)
next_fifo_transaction(ep, req); next_fifo_transaction(ep, req);
if (req->last_transaction) { if (req->last_transaction) {
usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY); usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY);
usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); if (ep_is_control(ep))
usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
} else { } else {
usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); if (ep_is_control(ep))
usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY); usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY);
} }
} }
......
...@@ -98,6 +98,17 @@ int usb_ep_enable(struct usb_ep *ep) ...@@ -98,6 +98,17 @@ int usb_ep_enable(struct usb_ep *ep)
if (ep->enabled) if (ep->enabled)
goto out; goto out;
/* UDC drivers can't handle endpoints with maxpacket size 0 */
if (usb_endpoint_maxp(ep->desc) == 0) {
/*
* We should log an error message here, but we can't call
* dev_err() because there's no way to find the gadget
* given only ep.
*/
ret = -EINVAL;
goto out;
}
ret = ep->ops->enable(ep, ep->desc); ret = ep->ops->enable(ep, ep->desc);
if (ret) if (ret)
goto out; goto out;
......
...@@ -2576,7 +2576,7 @@ static int fsl_udc_remove(struct platform_device *pdev) ...@@ -2576,7 +2576,7 @@ static int fsl_udc_remove(struct platform_device *pdev)
dma_pool_destroy(udc_controller->td_pool); dma_pool_destroy(udc_controller->td_pool);
free_irq(udc_controller->irq, udc_controller); free_irq(udc_controller->irq, udc_controller);
iounmap(dr_regs); iounmap(dr_regs);
if (pdata->operating_mode == FSL_USB2_DR_DEVICE) if (res && (pdata->operating_mode == FSL_USB2_DR_DEVICE))
release_mem_region(res->start, resource_size(res)); release_mem_region(res->start, resource_size(res));
/* free udc --wait for the release() finished */ /* free udc --wait for the release() finished */
......
...@@ -1544,10 +1544,10 @@ static void usb3_set_device_address(struct renesas_usb3 *usb3, u16 addr) ...@@ -1544,10 +1544,10 @@ static void usb3_set_device_address(struct renesas_usb3 *usb3, u16 addr)
static bool usb3_std_req_set_address(struct renesas_usb3 *usb3, static bool usb3_std_req_set_address(struct renesas_usb3 *usb3,
struct usb_ctrlrequest *ctrl) struct usb_ctrlrequest *ctrl)
{ {
if (ctrl->wValue >= 128) if (le16_to_cpu(ctrl->wValue) >= 128)
return true; /* stall */ return true; /* stall */
usb3_set_device_address(usb3, ctrl->wValue); usb3_set_device_address(usb3, le16_to_cpu(ctrl->wValue));
usb3_set_p0_con_for_no_data(usb3); usb3_set_p0_con_for_no_data(usb3);
return false; return false;
...@@ -1582,6 +1582,7 @@ static bool usb3_std_req_get_status(struct renesas_usb3 *usb3, ...@@ -1582,6 +1582,7 @@ static bool usb3_std_req_get_status(struct renesas_usb3 *usb3,
struct renesas_usb3_ep *usb3_ep; struct renesas_usb3_ep *usb3_ep;
int num; int num;
u16 status = 0; u16 status = 0;
__le16 tx_data;
switch (ctrl->bRequestType & USB_RECIP_MASK) { switch (ctrl->bRequestType & USB_RECIP_MASK) {
case USB_RECIP_DEVICE: case USB_RECIP_DEVICE:
...@@ -1604,10 +1605,10 @@ static bool usb3_std_req_get_status(struct renesas_usb3 *usb3, ...@@ -1604,10 +1605,10 @@ static bool usb3_std_req_get_status(struct renesas_usb3 *usb3,
} }
if (!stall) { if (!stall) {
status = cpu_to_le16(status); tx_data = cpu_to_le16(status);
dev_dbg(usb3_to_dev(usb3), "get_status: req = %p\n", dev_dbg(usb3_to_dev(usb3), "get_status: req = %p\n",
usb_req_to_usb3_req(usb3->ep0_req)); usb_req_to_usb3_req(usb3->ep0_req));
usb3_pipe0_internal_xfer(usb3, &status, sizeof(status), usb3_pipe0_internal_xfer(usb3, &tx_data, sizeof(tx_data),
usb3_pipe0_get_status_completion); usb3_pipe0_get_status_completion);
} }
...@@ -1772,7 +1773,7 @@ static bool usb3_std_req_set_sel(struct renesas_usb3 *usb3, ...@@ -1772,7 +1773,7 @@ static bool usb3_std_req_set_sel(struct renesas_usb3 *usb3,
static bool usb3_std_req_set_configuration(struct renesas_usb3 *usb3, static bool usb3_std_req_set_configuration(struct renesas_usb3 *usb3,
struct usb_ctrlrequest *ctrl) struct usb_ctrlrequest *ctrl)
{ {
if (ctrl->wValue > 0) if (le16_to_cpu(ctrl->wValue) > 0)
usb3_set_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON); usb3_set_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON);
else else
usb3_clear_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON); usb3_clear_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON);
......
...@@ -202,10 +202,10 @@ static void xhci_ring_dump_segment(struct seq_file *s, ...@@ -202,10 +202,10 @@ static void xhci_ring_dump_segment(struct seq_file *s,
trb = &seg->trbs[i]; trb = &seg->trbs[i];
dma = seg->dma + i * sizeof(*trb); dma = seg->dma + i * sizeof(*trb);
seq_printf(s, "%pad: %s\n", &dma, seq_printf(s, "%pad: %s\n", &dma,
xhci_decode_trb(trb->generic.field[0], xhci_decode_trb(le32_to_cpu(trb->generic.field[0]),
trb->generic.field[1], le32_to_cpu(trb->generic.field[1]),
trb->generic.field[2], le32_to_cpu(trb->generic.field[2]),
trb->generic.field[3])); le32_to_cpu(trb->generic.field[3])));
} }
} }
...@@ -263,10 +263,10 @@ static int xhci_slot_context_show(struct seq_file *s, void *unused) ...@@ -263,10 +263,10 @@ static int xhci_slot_context_show(struct seq_file *s, void *unused)
xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus)); xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus));
slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx); slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma, seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma,
xhci_decode_slot_context(slot_ctx->dev_info, xhci_decode_slot_context(le32_to_cpu(slot_ctx->dev_info),
slot_ctx->dev_info2, le32_to_cpu(slot_ctx->dev_info2),
slot_ctx->tt_info, le32_to_cpu(slot_ctx->tt_info),
slot_ctx->dev_state)); le32_to_cpu(slot_ctx->dev_state)));
return 0; return 0;
} }
...@@ -286,10 +286,10 @@ static int xhci_endpoint_context_show(struct seq_file *s, void *unused) ...@@ -286,10 +286,10 @@ static int xhci_endpoint_context_show(struct seq_file *s, void *unused)
ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, dci); ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, dci);
dma = dev->out_ctx->dma + dci * CTX_SIZE(xhci->hcc_params); dma = dev->out_ctx->dma + dci * CTX_SIZE(xhci->hcc_params);
seq_printf(s, "%pad: %s\n", &dma, seq_printf(s, "%pad: %s\n", &dma,
xhci_decode_ep_context(ep_ctx->ep_info, xhci_decode_ep_context(le32_to_cpu(ep_ctx->ep_info),
ep_ctx->ep_info2, le32_to_cpu(ep_ctx->ep_info2),
ep_ctx->deq, le64_to_cpu(ep_ctx->deq),
ep_ctx->tx_info)); le32_to_cpu(ep_ctx->tx_info)));
} }
return 0; return 0;
......
...@@ -3330,6 +3330,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3330,6 +3330,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
if (xhci_urb_suitable_for_idt(urb)) { if (xhci_urb_suitable_for_idt(urb)) {
memcpy(&send_addr, urb->transfer_buffer, memcpy(&send_addr, urb->transfer_buffer,
trb_buff_len); trb_buff_len);
le64_to_cpus(&send_addr);
field |= TRB_IDT; field |= TRB_IDT;
} }
} }
...@@ -3475,6 +3476,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3475,6 +3476,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
if (xhci_urb_suitable_for_idt(urb)) { if (xhci_urb_suitable_for_idt(urb)) {
memcpy(&addr, urb->transfer_buffer, memcpy(&addr, urb->transfer_buffer,
urb->transfer_buffer_length); urb->transfer_buffer_length);
le64_to_cpus(&addr);
field |= TRB_IDT; field |= TRB_IDT;
} else { } else {
addr = (u64) urb->transfer_dma; addr = (u64) urb->transfer_dma;
......
...@@ -3071,6 +3071,48 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index, ...@@ -3071,6 +3071,48 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index,
} }
} }
static void xhci_endpoint_disable(struct usb_hcd *hcd,
struct usb_host_endpoint *host_ep)
{
struct xhci_hcd *xhci;
struct xhci_virt_device *vdev;
struct xhci_virt_ep *ep;
struct usb_device *udev;
unsigned long flags;
unsigned int ep_index;
xhci = hcd_to_xhci(hcd);
rescan:
spin_lock_irqsave(&xhci->lock, flags);
udev = (struct usb_device *)host_ep->hcpriv;
if (!udev || !udev->slot_id)
goto done;
vdev = xhci->devs[udev->slot_id];
if (!vdev)
goto done;
ep_index = xhci_get_endpoint_index(&host_ep->desc);
ep = &vdev->eps[ep_index];
if (!ep)
goto done;
/* wait for hub_tt_work to finish clearing hub TT */
if (ep->ep_state & EP_CLEARING_TT) {
spin_unlock_irqrestore(&xhci->lock, flags);
schedule_timeout_uninterruptible(1);
goto rescan;
}
if (ep->ep_state)
xhci_dbg(xhci, "endpoint disable with ep_state 0x%x\n",
ep->ep_state);
done:
host_ep->hcpriv = NULL;
spin_unlock_irqrestore(&xhci->lock, flags);
}
/* /*
* Called after usb core issues a clear halt control message. * Called after usb core issues a clear halt control message.
* The host side of the halt should already be cleared by a reset endpoint * The host side of the halt should already be cleared by a reset endpoint
...@@ -5238,20 +5280,13 @@ static void xhci_clear_tt_buffer_complete(struct usb_hcd *hcd, ...@@ -5238,20 +5280,13 @@ static void xhci_clear_tt_buffer_complete(struct usb_hcd *hcd,
unsigned int ep_index; unsigned int ep_index;
unsigned long flags; unsigned long flags;
/*
* udev might be NULL if tt buffer is cleared during a failed device
* enumeration due to a halted control endpoint. Usb core might
* have allocated a new udev for the next enumeration attempt.
*/
xhci = hcd_to_xhci(hcd); xhci = hcd_to_xhci(hcd);
spin_lock_irqsave(&xhci->lock, flags);
udev = (struct usb_device *)ep->hcpriv; udev = (struct usb_device *)ep->hcpriv;
if (!udev)
return;
slot_id = udev->slot_id; slot_id = udev->slot_id;
ep_index = xhci_get_endpoint_index(&ep->desc); ep_index = xhci_get_endpoint_index(&ep->desc);
spin_lock_irqsave(&xhci->lock, flags);
xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_CLEARING_TT; xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_CLEARING_TT;
xhci_ring_doorbell_for_active_rings(xhci, slot_id, ep_index); xhci_ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
spin_unlock_irqrestore(&xhci->lock, flags); spin_unlock_irqrestore(&xhci->lock, flags);
...@@ -5288,6 +5323,7 @@ static const struct hc_driver xhci_hc_driver = { ...@@ -5288,6 +5323,7 @@ static const struct hc_driver xhci_hc_driver = {
.free_streams = xhci_free_streams, .free_streams = xhci_free_streams,
.add_endpoint = xhci_add_endpoint, .add_endpoint = xhci_add_endpoint,
.drop_endpoint = xhci_drop_endpoint, .drop_endpoint = xhci_drop_endpoint,
.endpoint_disable = xhci_endpoint_disable,
.endpoint_reset = xhci_endpoint_reset, .endpoint_reset = xhci_endpoint_reset,
.check_bandwidth = xhci_check_bandwidth, .check_bandwidth = xhci_check_bandwidth,
.reset_bandwidth = xhci_reset_bandwidth, .reset_bandwidth = xhci_reset_bandwidth,
......
...@@ -487,7 +487,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, ...@@ -487,7 +487,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
} }
bytes_to_read = min(count, *actual_buffer); bytes_to_read = min(count, *actual_buffer);
if (bytes_to_read < *actual_buffer) if (bytes_to_read < *actual_buffer)
dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n", dev_warn(&dev->intf->dev, "Read buffer overflow, %zu bytes dropped\n",
*actual_buffer-bytes_to_read); *actual_buffer-bytes_to_read);
/* copy one interrupt_in_buffer from ring_buffer into userspace */ /* copy one interrupt_in_buffer from ring_buffer into userspace */
...@@ -495,11 +495,11 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, ...@@ -495,11 +495,11 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
retval = -EFAULT; retval = -EFAULT;
goto unlock_exit; goto unlock_exit;
} }
dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
retval = bytes_to_read; retval = bytes_to_read;
spin_lock_irq(&dev->rbsl); spin_lock_irq(&dev->rbsl);
dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
if (dev->buffer_overflow) { if (dev->buffer_overflow) {
dev->buffer_overflow = 0; dev->buffer_overflow = 0;
spin_unlock_irq(&dev->rbsl); spin_unlock_irq(&dev->rbsl);
...@@ -562,8 +562,9 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, ...@@ -562,8 +562,9 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
/* write the data into interrupt_out_buffer from userspace */ /* write the data into interrupt_out_buffer from userspace */
bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size); bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
if (bytes_to_write < count) if (bytes_to_write < count)
dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n", count-bytes_to_write); dev_warn(&dev->intf->dev, "Write buffer overflow, %zu bytes dropped\n",
dev_dbg(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", count - bytes_to_write);
dev_dbg(&dev->intf->dev, "%s: count = %zu, bytes_to_write = %zu\n",
__func__, count, bytes_to_write); __func__, count, bytes_to_write);
if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
...@@ -580,7 +581,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, ...@@ -580,7 +581,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
1 << 8, 0, 1 << 8, 0,
dev->interrupt_out_buffer, dev->interrupt_out_buffer,
bytes_to_write, bytes_to_write,
USB_CTRL_SET_TIMEOUT * HZ); USB_CTRL_SET_TIMEOUT);
if (retval < 0) if (retval < 0)
dev_err(&dev->intf->dev, dev_err(&dev->intf->dev,
"Couldn't submit HID_REQ_SET_REPORT %d\n", "Couldn't submit HID_REQ_SET_REPORT %d\n",
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include "mtu3.h" #include "mtu3.h"
#include "mtu3_dr.h"
#include "mtu3_debug.h" #include "mtu3_debug.h"
#include "mtu3_trace.h" #include "mtu3_trace.h"
......
...@@ -162,17 +162,17 @@ void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req) ...@@ -162,17 +162,17 @@ void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
req->bRequest = (val >> 8) & 0xFF; req->bRequest = (val >> 8) & 0xFF;
req->bRequestType = (val >> 0) & 0xFF; req->bRequestType = (val >> 0) & 0xFF;
req->wValue = usbhs_read(priv, USBVAL); req->wValue = cpu_to_le16(usbhs_read(priv, USBVAL));
req->wIndex = usbhs_read(priv, USBINDX); req->wIndex = cpu_to_le16(usbhs_read(priv, USBINDX));
req->wLength = usbhs_read(priv, USBLENG); req->wLength = cpu_to_le16(usbhs_read(priv, USBLENG));
} }
void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req) void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
{ {
usbhs_write(priv, USBREQ, (req->bRequest << 8) | req->bRequestType); usbhs_write(priv, USBREQ, (req->bRequest << 8) | req->bRequestType);
usbhs_write(priv, USBVAL, req->wValue); usbhs_write(priv, USBVAL, le16_to_cpu(req->wValue));
usbhs_write(priv, USBINDX, req->wIndex); usbhs_write(priv, USBINDX, le16_to_cpu(req->wIndex));
usbhs_write(priv, USBLENG, req->wLength); usbhs_write(priv, USBLENG, le16_to_cpu(req->wLength));
usbhs_bset(priv, DCPCTR, SUREQ, SUREQ); usbhs_bset(priv, DCPCTR, SUREQ, SUREQ);
} }
......
...@@ -265,7 +265,7 @@ static int usbhsg_recip_handler_std_set_device(struct usbhs_priv *priv, ...@@ -265,7 +265,7 @@ static int usbhsg_recip_handler_std_set_device(struct usbhs_priv *priv,
case USB_DEVICE_TEST_MODE: case USB_DEVICE_TEST_MODE:
usbhsg_recip_handler_std_control_done(priv, uep, ctrl); usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
udelay(100); udelay(100);
usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex >> 8)); usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex) >> 8);
break; break;
default: default:
usbhsg_recip_handler_std_control_done(priv, uep, ctrl); usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
...@@ -315,7 +315,7 @@ static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv, ...@@ -315,7 +315,7 @@ static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv,
struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp);
struct device *dev = usbhsg_gpriv_to_dev(gpriv); struct device *dev = usbhsg_gpriv_to_dev(gpriv);
struct usb_request *req; struct usb_request *req;
unsigned short *buf; __le16 *buf;
/* alloc new usb_request for recip */ /* alloc new usb_request for recip */
req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC); req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC);
......
...@@ -559,6 +559,10 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, ...@@ -559,6 +559,10 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command,
command_port = port->serial->port[COMMAND_PORT]; command_port = port->serial->port[COMMAND_PORT];
command_info = usb_get_serial_port_data(command_port); command_info = usb_get_serial_port_data(command_port);
if (command_port->bulk_out_size < datasize + 1)
return -EIO;
mutex_lock(&command_info->mutex); mutex_lock(&command_info->mutex);
command_info->command_finished = false; command_info->command_finished = false;
...@@ -632,6 +636,7 @@ static void firm_setup_port(struct tty_struct *tty) ...@@ -632,6 +636,7 @@ static void firm_setup_port(struct tty_struct *tty)
struct device *dev = &port->dev; struct device *dev = &port->dev;
struct whiteheat_port_settings port_settings; struct whiteheat_port_settings port_settings;
unsigned int cflag = tty->termios.c_cflag; unsigned int cflag = tty->termios.c_cflag;
speed_t baud;
port_settings.port = port->port_number + 1; port_settings.port = port->port_number + 1;
...@@ -692,11 +697,13 @@ static void firm_setup_port(struct tty_struct *tty) ...@@ -692,11 +697,13 @@ static void firm_setup_port(struct tty_struct *tty)
dev_dbg(dev, "%s - XON = %2x, XOFF = %2x\n", __func__, port_settings.xon, port_settings.xoff); dev_dbg(dev, "%s - XON = %2x, XOFF = %2x\n", __func__, port_settings.xon, port_settings.xoff);
/* get the baud rate wanted */ /* get the baud rate wanted */
port_settings.baud = tty_get_baud_rate(tty); baud = tty_get_baud_rate(tty);
dev_dbg(dev, "%s - baud rate = %d\n", __func__, port_settings.baud); port_settings.baud = cpu_to_le32(baud);
dev_dbg(dev, "%s - baud rate = %u\n", __func__, baud);
/* fixme: should set validated settings */ /* fixme: should set validated settings */
tty_encode_baud_rate(tty, port_settings.baud, port_settings.baud); tty_encode_baud_rate(tty, baud, baud);
/* handle any settings that aren't specified in the tty structure */ /* handle any settings that aren't specified in the tty structure */
port_settings.lloop = 0; port_settings.lloop = 0;
......
...@@ -87,7 +87,7 @@ struct whiteheat_simple { ...@@ -87,7 +87,7 @@ struct whiteheat_simple {
struct whiteheat_port_settings { struct whiteheat_port_settings {
__u8 port; /* port number (1 to N) */ __u8 port; /* port number (1 to N) */
__u32 baud; /* any value 7 - 460800, firmware calculates __le32 baud; /* any value 7 - 460800, firmware calculates
best fit; arrives little endian */ best fit; arrives little endian */
__u8 bits; /* 5, 6, 7, or 8 */ __u8 bits; /* 5, 6, 7, or 8 */
__u8 stop; /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */ __u8 stop; /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */
......
...@@ -68,7 +68,6 @@ static const char* host_info(struct Scsi_Host *host) ...@@ -68,7 +68,6 @@ static const char* host_info(struct Scsi_Host *host)
static int slave_alloc (struct scsi_device *sdev) static int slave_alloc (struct scsi_device *sdev)
{ {
struct us_data *us = host_to_us(sdev->host); struct us_data *us = host_to_us(sdev->host);
int maxp;
/* /*
* Set the INQUIRY transfer length to 36. We don't use any of * Set the INQUIRY transfer length to 36. We don't use any of
...@@ -77,15 +76,6 @@ static int slave_alloc (struct scsi_device *sdev) ...@@ -77,15 +76,6 @@ static int slave_alloc (struct scsi_device *sdev)
*/ */
sdev->inquiry_len = 36; sdev->inquiry_len = 36;
/*
* USB has unusual scatter-gather requirements: the length of each
* scatterlist element except the last must be divisible by the
* Bulk maxpacket value. Fortunately this value is always a
* power of 2. Inform the block layer about this requirement.
*/
maxp = usb_maxpacket(us->pusb_dev, us->recv_bulk_pipe, 0);
blk_queue_virt_boundary(sdev->request_queue, maxp - 1);
/* /*
* Some host controllers may have alignment requirements. * Some host controllers may have alignment requirements.
* We'll play it safe by requiring 512-byte alignment always. * We'll play it safe by requiring 512-byte alignment always.
......
...@@ -789,29 +789,9 @@ static int uas_slave_alloc(struct scsi_device *sdev) ...@@ -789,29 +789,9 @@ static int uas_slave_alloc(struct scsi_device *sdev)
{ {
struct uas_dev_info *devinfo = struct uas_dev_info *devinfo =
(struct uas_dev_info *)sdev->host->hostdata; (struct uas_dev_info *)sdev->host->hostdata;
int maxp;
sdev->hostdata = devinfo; sdev->hostdata = devinfo;
/*
* We have two requirements here. We must satisfy the requirements
* of the physical HC and the demands of the protocol, as we
* definitely want no additional memory allocation in this path
* ruling out using bounce buffers.
*
* For a transmission on USB to continue we must never send
* a package that is smaller than maxpacket. Hence the length of each
* scatterlist element except the last must be divisible by the
* Bulk maxpacket value.
* If the HC does not ensure that through SG,
* the upper layer must do that. We must assume nothing
* about the capabilities off the HC, so we use the most
* pessimistic requirement.
*/
maxp = usb_maxpacket(devinfo->udev, devinfo->data_in_pipe, 0);
blk_queue_virt_boundary(sdev->request_queue, maxp - 1);
/* /*
* The protocol has no requirements on alignment in the strict sense. * The protocol has no requirements on alignment in the strict sense.
* Controllers may or may not have alignment restrictions. * Controllers may or may not have alignment restrictions.
......
...@@ -147,7 +147,10 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev) ...@@ -147,7 +147,10 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
} }
kfree(iov); kfree(iov);
/* This is only for isochronous case */
kfree(iso_buffer); kfree(iso_buffer);
iso_buffer = NULL;
usbip_dbg_vhci_tx("send txdata\n"); usbip_dbg_vhci_tx("send txdata\n");
total_size += txsize; total_size += txsize;
......
...@@ -69,7 +69,7 @@ int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev) ...@@ -69,7 +69,7 @@ int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev)
FILE *fd = NULL; FILE *fd = NULL;
struct udev_device *plat; struct udev_device *plat;
const char *speed; const char *speed;
int ret = 0; size_t ret;
plat = udev_device_get_parent(sdev); plat = udev_device_get_parent(sdev);
path = udev_device_get_syspath(plat); path = udev_device_get_syspath(plat);
...@@ -79,8 +79,10 @@ int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev) ...@@ -79,8 +79,10 @@ int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev)
if (!fd) if (!fd)
return -1; return -1;
ret = fread((char *) &descr, sizeof(descr), 1, fd); ret = fread((char *) &descr, sizeof(descr), 1, fd);
if (ret < 0) if (ret != 1) {
err("Cannot read vudc device descr file: %s", strerror(errno));
goto err; goto err;
}
fclose(fd); fclose(fd);
copy_descr_attr(dev, &descr, bDeviceClass); copy_descr_attr(dev, &descr, bDeviceClass);
......
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