USB fixes for 4.11-rc2
Here is a number of different USB fixes for 4.11-rc2. Seems like there were a lot of unresolved issues that people have been finding for this subsystem, and a bunch of good security auditing happening as well from Johan Hovold. There's the usual batch of gadget driver fixes and xhci issues resolved as well. All of these have been in linux-next with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWMOkLA8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ymiCACeIL3h4bNEc6+XLiB+sfmQx4wV2MUAnRMD1gB0 GxkBXY1Iny94vhZC8x5r =dlkm -----END PGP SIGNATURE----- Merge tag 'usb-4.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB fixes from Greg KH: "Here is a number of different USB fixes for 4.11-rc2. Seems like there were a lot of unresolved issues that people have been finding for this subsystem, and a bunch of good security auditing happening as well from Johan Hovold. There's the usual batch of gadget driver fixes and xhci issues resolved as well. All of these have been in linux-next with no reported issues" * tag 'usb-4.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (35 commits) usb: host: xhci-plat: Fix timeout on removal of hot pluggable xhci controllers usb: host: xhci-dbg: HCIVERSION should be a binary number usb: xhci: remove dummy extra_priv_size for size of xhci_hcd struct usb: xhci-mtk: check hcc_params after adding primary hcd USB: serial: digi_acceleport: fix OOB-event processing MAINTAINERS: usb251xb: remove reference inexistent file doc: dt-bindings: usb251xb: mark reg as required usb: usb251xb: dt: add unit suffix to oc-delay and power-on-time usb: usb251xb: remove max_{power,current}_{sp,bp} properties usb-storage: Add ignore-residue quirk for Initio INIC-3619 USB: iowarrior: fix NULL-deref in write USB: iowarrior: fix NULL-deref at probe usb: phy: isp1301: Add OF device ID table usb: ohci-at91: Do not drop unhandled USB suspend control requests USB: serial: safe_serial: fix information leak in completion handler USB: serial: io_ti: fix information leak in completion handler USB: serial: omninet: drop open callback USB: serial: omninet: fix reference leaks at open USB: serial: io_ti: fix NULL-deref in interrupt callback usb: dwc3: gadget: make to increment req->remaining in all cases ...
This commit is contained in:
Коммит
46552bf433
|
@ -7,18 +7,18 @@ Required properties :
|
|||
- compatible : Should be "microchip,usb251xb" or one of the specific types:
|
||||
"microchip,usb2512b", "microchip,usb2512bi", "microchip,usb2513b",
|
||||
"microchip,usb2513bi", "microchip,usb2514b", "microchip,usb2514bi"
|
||||
- hub-reset-gpios : Should specify the gpio for hub reset
|
||||
- reset-gpios : Should specify the gpio for hub reset
|
||||
- reg : I2C address on the selected bus (default is <0x2C>)
|
||||
|
||||
Optional properties :
|
||||
- reg : I2C address on the selected bus (default is <0x2C>)
|
||||
- skip-config : Skip Hub configuration, but only send the USB-Attach command
|
||||
- vendor-id : USB Vendor ID of the hub (16 bit, default is 0x0424)
|
||||
- product-id : USB Product ID of the hub (16 bit, default depends on type)
|
||||
- device-id : USB Device ID of the hub (16 bit, default is 0x0bb3)
|
||||
- language-id : USB Language ID (16 bit, default is 0x0000)
|
||||
- manufacturer : USB Manufacturer string (max 31 characters long)
|
||||
- product : USB Product string (max 31 characters long)
|
||||
- serial : USB Serial string (max 31 characters long)
|
||||
- vendor-id : Set USB Vendor ID of the hub (16 bit, default is 0x0424)
|
||||
- product-id : Set USB Product ID of the hub (16 bit, default depends on type)
|
||||
- device-id : Set USB Device ID of the hub (16 bit, default is 0x0bb3)
|
||||
- language-id : Set USB Language ID (16 bit, default is 0x0000)
|
||||
- manufacturer : Set USB Manufacturer string (max 31 characters long)
|
||||
- product : Set USB Product string (max 31 characters long)
|
||||
- serial : Set USB Serial string (max 31 characters long)
|
||||
- {bus,self}-powered : selects between self- and bus-powered operation (default
|
||||
is self-powered)
|
||||
- disable-hi-speed : disable USB Hi-Speed support
|
||||
|
@ -31,8 +31,10 @@ Optional properties :
|
|||
(default is individual)
|
||||
- dynamic-power-switching : enable auto-switching from self- to bus-powered
|
||||
operation if the local power source is removed or unavailable
|
||||
- oc-delay-{100us,4ms,8ms,16ms} : set over current timer delay (default is 8ms)
|
||||
- compound-device : indicated the hub is part of a compound device
|
||||
- oc-delay-us : Delay time (in microseconds) for filtering the over-current
|
||||
sense inputs. Valid values are 100, 4000, 8000 (default) and 16000. If
|
||||
an invalid value is given, the default is used instead.
|
||||
- compound-device : indicate the hub is part of a compound device
|
||||
- port-mapping-mode : enable port mapping mode
|
||||
- string-support : enable string descriptor support (required for manufacturer,
|
||||
product and serial string configuration)
|
||||
|
@ -40,34 +42,15 @@ Optional properties :
|
|||
device connected.
|
||||
- sp-disabled-ports : Specifies the ports which will be self-power disabled
|
||||
- bp-disabled-ports : Specifies the ports which will be bus-power disabled
|
||||
- max-sp-power : Specifies the maximum current the hub consumes from an
|
||||
upstream port when operating as self-powered hub including the power
|
||||
consumption of a permanently attached peripheral if the hub is
|
||||
configured as a compound device. The value is given in mA in a 0 - 500
|
||||
range (default is 2).
|
||||
- max-bp-power : Specifies the maximum current the hub consumes from an
|
||||
upstream port when operating as bus-powered hub including the power
|
||||
consumption of a permanently attached peripheral if the hub is
|
||||
configured as a compound device. The value is given in mA in a 0 - 500
|
||||
range (default is 100).
|
||||
- max-sp-current : Specifies the maximum current the hub consumes from an
|
||||
upstream port when operating as self-powered hub EXCLUDING the power
|
||||
consumption of a permanently attached peripheral if the hub is
|
||||
configured as a compound device. The value is given in mA in a 0 - 500
|
||||
range (default is 2).
|
||||
- max-bp-current : Specifies the maximum current the hub consumes from an
|
||||
upstream port when operating as bus-powered hub EXCLUDING the power
|
||||
consumption of a permanently attached peripheral if the hub is
|
||||
configured as a compound device. The value is given in mA in a 0 - 500
|
||||
range (default is 100).
|
||||
- power-on-time : Specifies the time it takes from the time the host initiates
|
||||
the power-on sequence to a port until the port has adequate power. The
|
||||
value is given in ms in a 0 - 510 range (default is 100ms).
|
||||
- power-on-time-ms : Specifies the time it takes from the time the host
|
||||
initiates the power-on sequence to a port until the port has adequate
|
||||
power. The value is given in ms in a 0 - 510 range (default is 100ms).
|
||||
|
||||
Examples:
|
||||
usb2512b@2c {
|
||||
compatible = "microchip,usb2512b";
|
||||
hub-reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
|
||||
reg = <0x2c>;
|
||||
reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
usb2514b@2c {
|
||||
|
|
|
@ -8307,7 +8307,6 @@ M: Richard Leitner <richard.leitner@skidata.com>
|
|||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/usb/misc/usb251xb.c
|
||||
F: include/linux/platform_data/usb251xb.h
|
||||
F: Documentation/devicetree/bindings/usb/usb251xb.txt
|
||||
|
||||
MICROSOFT SURFACE PRO 3 BUTTON DRIVER
|
||||
|
|
|
@ -250,6 +250,7 @@ static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
|
|||
val = dwc3_omap_read_utmi_ctrl(omap);
|
||||
val |= USBOTGSS_UTMI_OTG_CTRL_IDDIG;
|
||||
dwc3_omap_write_utmi_ctrl(omap, val);
|
||||
break;
|
||||
|
||||
case OMAP_DWC3_VBUS_OFF:
|
||||
val = dwc3_omap_read_utmi_ctrl(omap);
|
||||
|
@ -392,7 +393,7 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
|
|||
{
|
||||
u32 reg;
|
||||
struct device_node *node = omap->dev->of_node;
|
||||
int utmi_mode = 0;
|
||||
u32 utmi_mode = 0;
|
||||
|
||||
reg = dwc3_omap_read_utmi_ctrl(omap);
|
||||
|
||||
|
|
|
@ -1342,6 +1342,68 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
|
|||
if (r == req) {
|
||||
/* wait until it is processed */
|
||||
dwc3_stop_active_transfer(dwc, dep->number, true);
|
||||
|
||||
/*
|
||||
* If request was already started, this means we had to
|
||||
* stop the transfer. With that we also need to ignore
|
||||
* all TRBs used by the request, however TRBs can only
|
||||
* be modified after completion of END_TRANSFER
|
||||
* command. So what we do here is that we wait for
|
||||
* END_TRANSFER completion and only after that, we jump
|
||||
* over TRBs by clearing HWO and incrementing dequeue
|
||||
* pointer.
|
||||
*
|
||||
* Note that we have 2 possible types of transfers here:
|
||||
*
|
||||
* i) Linear buffer request
|
||||
* ii) SG-list based request
|
||||
*
|
||||
* SG-list based requests will have r->num_pending_sgs
|
||||
* set to a valid number (> 0). Linear requests,
|
||||
* normally use a single TRB.
|
||||
*
|
||||
* For each of these two cases, if r->unaligned flag is
|
||||
* set, one extra TRB has been used to align transfer
|
||||
* size to wMaxPacketSize.
|
||||
*
|
||||
* All of these cases need to be taken into
|
||||
* consideration so we don't mess up our TRB ring
|
||||
* pointers.
|
||||
*/
|
||||
wait_event_lock_irq(dep->wait_end_transfer,
|
||||
!(dep->flags & DWC3_EP_END_TRANSFER_PENDING),
|
||||
dwc->lock);
|
||||
|
||||
if (!r->trb)
|
||||
goto out1;
|
||||
|
||||
if (r->num_pending_sgs) {
|
||||
struct dwc3_trb *trb;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < r->num_pending_sgs; i++) {
|
||||
trb = r->trb + i;
|
||||
trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
|
||||
dwc3_ep_inc_deq(dep);
|
||||
}
|
||||
|
||||
if (r->unaligned) {
|
||||
trb = r->trb + r->num_pending_sgs + 1;
|
||||
trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
|
||||
dwc3_ep_inc_deq(dep);
|
||||
}
|
||||
} else {
|
||||
struct dwc3_trb *trb = r->trb;
|
||||
|
||||
trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
|
||||
dwc3_ep_inc_deq(dep);
|
||||
|
||||
if (r->unaligned) {
|
||||
trb = r->trb + 1;
|
||||
trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
|
||||
dwc3_ep_inc_deq(dep);
|
||||
}
|
||||
}
|
||||
goto out1;
|
||||
}
|
||||
dev_err(dwc->dev, "request %p was not queued to %s\n",
|
||||
|
@ -1352,6 +1414,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
|
|||
|
||||
out1:
|
||||
/* giveback the request */
|
||||
dep->queued_requests--;
|
||||
dwc3_gadget_giveback(dep, req, -ECONNRESET);
|
||||
|
||||
out0:
|
||||
|
@ -2126,12 +2189,12 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep,
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN)
|
||||
return 1;
|
||||
|
||||
count = trb->size & DWC3_TRB_SIZE_MASK;
|
||||
req->remaining += count;
|
||||
|
||||
if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN)
|
||||
return 1;
|
||||
|
||||
if (dep->direction) {
|
||||
if (count) {
|
||||
trb_status = DWC3_TRB_SIZE_TRBSTS(trb->size);
|
||||
|
@ -3228,15 +3291,10 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
|
|||
|
||||
int dwc3_gadget_suspend(struct dwc3 *dwc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!dwc->gadget_driver)
|
||||
return 0;
|
||||
|
||||
ret = dwc3_gadget_run_stop(dwc, false, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dwc3_gadget_run_stop(dwc, false, false);
|
||||
dwc3_disconnect_gadget(dwc);
|
||||
__dwc3_gadget_stop(dwc);
|
||||
|
||||
|
|
|
@ -28,23 +28,23 @@ struct dwc3;
|
|||
#define gadget_to_dwc(g) (container_of(g, struct dwc3, gadget))
|
||||
|
||||
/* DEPCFG parameter 1 */
|
||||
#define DWC3_DEPCFG_INT_NUM(n) ((n) << 0)
|
||||
#define DWC3_DEPCFG_INT_NUM(n) (((n) & 0x1f) << 0)
|
||||
#define DWC3_DEPCFG_XFER_COMPLETE_EN (1 << 8)
|
||||
#define DWC3_DEPCFG_XFER_IN_PROGRESS_EN (1 << 9)
|
||||
#define DWC3_DEPCFG_XFER_NOT_READY_EN (1 << 10)
|
||||
#define DWC3_DEPCFG_FIFO_ERROR_EN (1 << 11)
|
||||
#define DWC3_DEPCFG_STREAM_EVENT_EN (1 << 13)
|
||||
#define DWC3_DEPCFG_BINTERVAL_M1(n) ((n) << 16)
|
||||
#define DWC3_DEPCFG_BINTERVAL_M1(n) (((n) & 0xff) << 16)
|
||||
#define DWC3_DEPCFG_STREAM_CAPABLE (1 << 24)
|
||||
#define DWC3_DEPCFG_EP_NUMBER(n) ((n) << 25)
|
||||
#define DWC3_DEPCFG_EP_NUMBER(n) (((n) & 0x1f) << 25)
|
||||
#define DWC3_DEPCFG_BULK_BASED (1 << 30)
|
||||
#define DWC3_DEPCFG_FIFO_BASED (1 << 31)
|
||||
|
||||
/* DEPCFG parameter 0 */
|
||||
#define DWC3_DEPCFG_EP_TYPE(n) ((n) << 1)
|
||||
#define DWC3_DEPCFG_MAX_PACKET_SIZE(n) ((n) << 3)
|
||||
#define DWC3_DEPCFG_FIFO_NUMBER(n) ((n) << 17)
|
||||
#define DWC3_DEPCFG_BURST_SIZE(n) ((n) << 22)
|
||||
#define DWC3_DEPCFG_EP_TYPE(n) (((n) & 0x3) << 1)
|
||||
#define DWC3_DEPCFG_MAX_PACKET_SIZE(n) (((n) & 0x7ff) << 3)
|
||||
#define DWC3_DEPCFG_FIFO_NUMBER(n) (((n) & 0x1f) << 17)
|
||||
#define DWC3_DEPCFG_BURST_SIZE(n) (((n) & 0xf) << 22)
|
||||
#define DWC3_DEPCFG_DATA_SEQ_NUM(n) ((n) << 26)
|
||||
/* This applies for core versions earlier than 1.94a */
|
||||
#define DWC3_DEPCFG_IGN_SEQ_NUM (1 << 31)
|
||||
|
|
|
@ -269,6 +269,7 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
|
|||
ret = unregister_gadget(gi);
|
||||
if (ret)
|
||||
goto err;
|
||||
kfree(name);
|
||||
} else {
|
||||
if (gi->composite.gadget_driver.udc_name) {
|
||||
ret = -EBUSY;
|
||||
|
|
|
@ -1834,11 +1834,14 @@ static int ffs_func_eps_enable(struct ffs_function *func)
|
|||
spin_lock_irqsave(&func->ffs->eps_lock, flags);
|
||||
while(count--) {
|
||||
struct usb_endpoint_descriptor *ds;
|
||||
struct usb_ss_ep_comp_descriptor *comp_desc = NULL;
|
||||
int needs_comp_desc = false;
|
||||
int desc_idx;
|
||||
|
||||
if (ffs->gadget->speed == USB_SPEED_SUPER)
|
||||
if (ffs->gadget->speed == USB_SPEED_SUPER) {
|
||||
desc_idx = 2;
|
||||
else if (ffs->gadget->speed == USB_SPEED_HIGH)
|
||||
needs_comp_desc = true;
|
||||
} else if (ffs->gadget->speed == USB_SPEED_HIGH)
|
||||
desc_idx = 1;
|
||||
else
|
||||
desc_idx = 0;
|
||||
|
@ -1855,6 +1858,14 @@ static int ffs_func_eps_enable(struct ffs_function *func)
|
|||
|
||||
ep->ep->driver_data = ep;
|
||||
ep->ep->desc = ds;
|
||||
|
||||
comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
|
||||
USB_DT_ENDPOINT_SIZE);
|
||||
ep->ep->maxburst = comp_desc->bMaxBurst + 1;
|
||||
|
||||
if (needs_comp_desc)
|
||||
ep->ep->comp_desc = comp_desc;
|
||||
|
||||
ret = usb_ep_enable(ep->ep);
|
||||
if (likely(!ret)) {
|
||||
epfile->ep = ep;
|
||||
|
@ -2253,7 +2264,7 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,
|
|||
|
||||
if (len < sizeof(*d) ||
|
||||
d->bFirstInterfaceNumber >= ffs->interfaces_count ||
|
||||
d->Reserved1)
|
||||
!d->Reserved1)
|
||||
return -EINVAL;
|
||||
for (i = 0; i < ARRAY_SIZE(d->Reserved2); ++i)
|
||||
if (d->Reserved2[i])
|
||||
|
|
|
@ -258,13 +258,6 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
|
|||
memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req));
|
||||
v4l2_event_queue(&uvc->vdev, &v4l2_event);
|
||||
|
||||
/* Pass additional setup data to userspace */
|
||||
if (uvc->event_setup_out && uvc->event_length) {
|
||||
uvc->control_req->length = uvc->event_length;
|
||||
return usb_ep_queue(uvc->func.config->cdev->gadget->ep0,
|
||||
uvc->control_req, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1781,8 +1781,10 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
|||
|
||||
spin_lock_irq (&dev->lock);
|
||||
value = -EINVAL;
|
||||
if (dev->buf)
|
||||
if (dev->buf) {
|
||||
kfree(kbuf);
|
||||
goto fail;
|
||||
}
|
||||
dev->buf = kbuf;
|
||||
|
||||
/* full or low speed config */
|
||||
|
|
|
@ -610,7 +610,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
|||
{
|
||||
struct usba_ep *ep = to_usba_ep(_ep);
|
||||
struct usba_udc *udc = ep->udc;
|
||||
unsigned long flags, ept_cfg, maxpacket;
|
||||
unsigned long flags, maxpacket;
|
||||
unsigned int nr_trans;
|
||||
|
||||
DBG(DBG_GADGET, "%s: ep_enable: desc=%p\n", ep->ep.name, desc);
|
||||
|
@ -630,7 +630,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
|||
ep->is_in = 0;
|
||||
|
||||
DBG(DBG_ERR, "%s: EPT_CFG = 0x%lx (maxpacket = %lu)\n",
|
||||
ep->ep.name, ept_cfg, maxpacket);
|
||||
ep->ep.name, ep->ept_cfg, maxpacket);
|
||||
|
||||
if (usb_endpoint_dir_in(desc)) {
|
||||
ep->is_in = 1;
|
||||
|
|
|
@ -1031,6 +1031,8 @@ static int dummy_udc_probe(struct platform_device *pdev)
|
|||
int rc;
|
||||
|
||||
dum = *((void **)dev_get_platdata(&pdev->dev));
|
||||
/* Clear usb_gadget region for new registration to udc-core */
|
||||
memzero_explicit(&dum->gadget, sizeof(struct usb_gadget));
|
||||
dum->gadget.name = gadget_name;
|
||||
dum->gadget.ops = &dummy_ops;
|
||||
dum->gadget.max_speed = USB_SPEED_SUPER;
|
||||
|
|
|
@ -1146,15 +1146,15 @@ static int scan_dma_completions(struct net2280_ep *ep)
|
|||
*/
|
||||
while (!list_empty(&ep->queue)) {
|
||||
struct net2280_request *req;
|
||||
u32 tmp;
|
||||
u32 req_dma_count;
|
||||
|
||||
req = list_entry(ep->queue.next,
|
||||
struct net2280_request, queue);
|
||||
if (!req->valid)
|
||||
break;
|
||||
rmb();
|
||||
tmp = le32_to_cpup(&req->td->dmacount);
|
||||
if ((tmp & BIT(VALID_BIT)) != 0)
|
||||
req_dma_count = le32_to_cpup(&req->td->dmacount);
|
||||
if ((req_dma_count & BIT(VALID_BIT)) != 0)
|
||||
break;
|
||||
|
||||
/* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short"
|
||||
|
@ -1163,40 +1163,41 @@ static int scan_dma_completions(struct net2280_ep *ep)
|
|||
*/
|
||||
if (unlikely(req->td->dmadesc == 0)) {
|
||||
/* paranoia */
|
||||
tmp = readl(&ep->dma->dmacount);
|
||||
if (tmp & DMA_BYTE_COUNT_MASK)
|
||||
u32 const ep_dmacount = readl(&ep->dma->dmacount);
|
||||
|
||||
if (ep_dmacount & DMA_BYTE_COUNT_MASK)
|
||||
break;
|
||||
/* single transfer mode */
|
||||
dma_done(ep, req, tmp, 0);
|
||||
dma_done(ep, req, req_dma_count, 0);
|
||||
num_completed++;
|
||||
break;
|
||||
} else if (!ep->is_in &&
|
||||
(req->req.length % ep->ep.maxpacket) &&
|
||||
!(ep->dev->quirks & PLX_PCIE)) {
|
||||
|
||||
tmp = readl(&ep->regs->ep_stat);
|
||||
u32 const ep_stat = readl(&ep->regs->ep_stat);
|
||||
/* AVOID TROUBLE HERE by not issuing short reads from
|
||||
* your gadget driver. That helps avoids errata 0121,
|
||||
* 0122, and 0124; not all cases trigger the warning.
|
||||
*/
|
||||
if ((tmp & BIT(NAK_OUT_PACKETS)) == 0) {
|
||||
if ((ep_stat & BIT(NAK_OUT_PACKETS)) == 0) {
|
||||
ep_warn(ep->dev, "%s lost packet sync!\n",
|
||||
ep->ep.name);
|
||||
req->req.status = -EOVERFLOW;
|
||||
} else {
|
||||
tmp = readl(&ep->regs->ep_avail);
|
||||
if (tmp) {
|
||||
u32 const ep_avail = readl(&ep->regs->ep_avail);
|
||||
if (ep_avail) {
|
||||
/* fifo gets flushed later */
|
||||
ep->out_overflow = 1;
|
||||
ep_dbg(ep->dev,
|
||||
"%s dma, discard %d len %d\n",
|
||||
ep->ep.name, tmp,
|
||||
ep->ep.name, ep_avail,
|
||||
req->req.length);
|
||||
req->req.status = -EOVERFLOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
dma_done(ep, req, tmp, 0);
|
||||
dma_done(ep, req, req_dma_count, 0);
|
||||
num_completed++;
|
||||
}
|
||||
|
||||
|
|
|
@ -2534,9 +2534,10 @@ static int pxa_udc_remove(struct platform_device *_dev)
|
|||
usb_del_gadget_udc(&udc->gadget);
|
||||
pxa_cleanup_debugfs(udc);
|
||||
|
||||
if (!IS_ERR_OR_NULL(udc->transceiver))
|
||||
if (!IS_ERR_OR_NULL(udc->transceiver)) {
|
||||
usb_unregister_notifier(udc->transceiver, &pxa27x_udc_phy);
|
||||
usb_put_phy(udc->transceiver);
|
||||
usb_put_phy(udc->transceiver);
|
||||
}
|
||||
|
||||
udc->transceiver = NULL;
|
||||
the_controller = NULL;
|
||||
|
|
|
@ -350,7 +350,7 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|||
|
||||
case USB_PORT_FEAT_SUSPEND:
|
||||
dev_dbg(hcd->self.controller, "SetPortFeat: SUSPEND\n");
|
||||
if (valid_port(wIndex)) {
|
||||
if (valid_port(wIndex) && ohci_at91->sfr_regmap) {
|
||||
ohci_at91_port_suspend(ohci_at91->sfr_regmap,
|
||||
1);
|
||||
return 0;
|
||||
|
@ -393,7 +393,7 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|||
|
||||
case USB_PORT_FEAT_SUSPEND:
|
||||
dev_dbg(hcd->self.controller, "ClearPortFeature: SUSPEND\n");
|
||||
if (valid_port(wIndex)) {
|
||||
if (valid_port(wIndex) && ohci_at91->sfr_regmap) {
|
||||
ohci_at91_port_suspend(ohci_at91->sfr_regmap,
|
||||
0);
|
||||
return 0;
|
||||
|
|
|
@ -109,7 +109,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
|
|||
xhci_dbg(xhci, "RTSOFF 0x%x:\n", temp & RTSOFF_MASK);
|
||||
|
||||
/* xhci 1.1 controllers have the HCCPARAMS2 register */
|
||||
if (hci_version > 100) {
|
||||
if (hci_version > 0x100) {
|
||||
temp = readl(&xhci->cap_regs->hcc_params2);
|
||||
xhci_dbg(xhci, "HCC PARAMS2 0x%x:\n", (unsigned int) temp);
|
||||
xhci_dbg(xhci, " HC %s Force save context capability",
|
||||
|
|
|
@ -382,7 +382,6 @@ static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk,
|
|||
|
||||
static int xhci_mtk_setup(struct usb_hcd *hcd);
|
||||
static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = {
|
||||
.extra_priv_size = sizeof(struct xhci_hcd),
|
||||
.reset = xhci_mtk_setup,
|
||||
};
|
||||
|
||||
|
@ -678,13 +677,13 @@ static int xhci_mtk_probe(struct platform_device *pdev)
|
|||
goto power_off_phys;
|
||||
}
|
||||
|
||||
if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
|
||||
xhci->shared_hcd->can_do_streams = 1;
|
||||
|
||||
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
||||
if (ret)
|
||||
goto put_usb3_hcd;
|
||||
|
||||
if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
|
||||
xhci->shared_hcd->can_do_streams = 1;
|
||||
|
||||
ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
|
||||
if (ret)
|
||||
goto dealloc_usb2_hcd;
|
||||
|
|
|
@ -286,6 +286,8 @@ static int xhci_plat_remove(struct platform_device *dev)
|
|||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct clk *clk = xhci->clk;
|
||||
|
||||
xhci->xhc_state |= XHCI_STATE_REMOVING;
|
||||
|
||||
usb_remove_hcd(xhci->shared_hcd);
|
||||
usb_phy_shutdown(hcd->usb_phy);
|
||||
|
||||
|
|
|
@ -1308,7 +1308,6 @@ static int tegra_xhci_setup(struct usb_hcd *hcd)
|
|||
}
|
||||
|
||||
static const struct xhci_driver_overrides tegra_xhci_overrides __initconst = {
|
||||
.extra_priv_size = sizeof(struct xhci_hcd),
|
||||
.reset = tegra_xhci_setup,
|
||||
};
|
||||
|
||||
|
|
|
@ -781,12 +781,6 @@ static int iowarrior_probe(struct usb_interface *interface,
|
|||
iface_desc = interface->cur_altsetting;
|
||||
dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
|
||||
|
||||
if (iface_desc->desc.bNumEndpoints < 1) {
|
||||
dev_err(&interface->dev, "Invalid number of endpoints\n");
|
||||
retval = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* set up the endpoint information */
|
||||
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
|
||||
endpoint = &iface_desc->endpoint[i].desc;
|
||||
|
@ -797,6 +791,21 @@ static int iowarrior_probe(struct usb_interface *interface,
|
|||
/* this one will match for the IOWarrior56 only */
|
||||
dev->int_out_endpoint = endpoint;
|
||||
}
|
||||
|
||||
if (!dev->int_in_endpoint) {
|
||||
dev_err(&interface->dev, "no interrupt-in endpoint found\n");
|
||||
retval = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56) {
|
||||
if (!dev->int_out_endpoint) {
|
||||
dev_err(&interface->dev, "no interrupt-out endpoint found\n");
|
||||
retval = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* we have to check the report_size often, so remember it in the endianness suitable for our machine */
|
||||
dev->report_size = usb_endpoint_maxp(dev->int_in_endpoint);
|
||||
if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) &&
|
||||
|
|
|
@ -375,18 +375,24 @@ static int usb251xb_get_ofdata(struct usb251xb *hub,
|
|||
if (of_get_property(np, "dynamic-power-switching", NULL))
|
||||
hub->conf_data2 |= BIT(7);
|
||||
|
||||
if (of_get_property(np, "oc-delay-100us", NULL)) {
|
||||
hub->conf_data2 &= ~BIT(5);
|
||||
hub->conf_data2 &= ~BIT(4);
|
||||
} else if (of_get_property(np, "oc-delay-4ms", NULL)) {
|
||||
hub->conf_data2 &= ~BIT(5);
|
||||
hub->conf_data2 |= BIT(4);
|
||||
} else if (of_get_property(np, "oc-delay-8ms", NULL)) {
|
||||
hub->conf_data2 |= BIT(5);
|
||||
hub->conf_data2 &= ~BIT(4);
|
||||
} else if (of_get_property(np, "oc-delay-16ms", NULL)) {
|
||||
hub->conf_data2 |= BIT(5);
|
||||
hub->conf_data2 |= BIT(4);
|
||||
if (!of_property_read_u32(np, "oc-delay-us", property_u32)) {
|
||||
if (*property_u32 == 100) {
|
||||
/* 100 us*/
|
||||
hub->conf_data2 &= ~BIT(5);
|
||||
hub->conf_data2 &= ~BIT(4);
|
||||
} else if (*property_u32 == 4000) {
|
||||
/* 4 ms */
|
||||
hub->conf_data2 &= ~BIT(5);
|
||||
hub->conf_data2 |= BIT(4);
|
||||
} else if (*property_u32 == 16000) {
|
||||
/* 16 ms */
|
||||
hub->conf_data2 |= BIT(5);
|
||||
hub->conf_data2 |= BIT(4);
|
||||
} else {
|
||||
/* 8 ms (DEFAULT) */
|
||||
hub->conf_data2 |= BIT(5);
|
||||
hub->conf_data2 &= ~BIT(4);
|
||||
}
|
||||
}
|
||||
|
||||
if (of_get_property(np, "compound-device", NULL))
|
||||
|
@ -432,30 +438,9 @@ static int usb251xb_get_ofdata(struct usb251xb *hub,
|
|||
}
|
||||
}
|
||||
|
||||
hub->max_power_sp = USB251XB_DEF_MAX_POWER_SELF;
|
||||
if (!of_property_read_u32(np, "max-sp-power", property_u32))
|
||||
hub->max_power_sp = min_t(u8, be32_to_cpu(*property_u32) / 2,
|
||||
250);
|
||||
|
||||
hub->max_power_bp = USB251XB_DEF_MAX_POWER_BUS;
|
||||
if (!of_property_read_u32(np, "max-bp-power", property_u32))
|
||||
hub->max_power_bp = min_t(u8, be32_to_cpu(*property_u32) / 2,
|
||||
250);
|
||||
|
||||
hub->max_current_sp = USB251XB_DEF_MAX_CURRENT_SELF;
|
||||
if (!of_property_read_u32(np, "max-sp-current", property_u32))
|
||||
hub->max_current_sp = min_t(u8, be32_to_cpu(*property_u32) / 2,
|
||||
250);
|
||||
|
||||
hub->max_current_bp = USB251XB_DEF_MAX_CURRENT_BUS;
|
||||
if (!of_property_read_u32(np, "max-bp-current", property_u32))
|
||||
hub->max_current_bp = min_t(u8, be32_to_cpu(*property_u32) / 2,
|
||||
250);
|
||||
|
||||
hub->power_on_time = USB251XB_DEF_POWER_ON_TIME;
|
||||
if (!of_property_read_u32(np, "power-on-time", property_u32))
|
||||
hub->power_on_time = min_t(u8, be32_to_cpu(*property_u32) / 2,
|
||||
255);
|
||||
if (!of_property_read_u32(np, "power-on-time-ms", property_u32))
|
||||
hub->power_on_time = min_t(u8, *property_u32 / 2, 255);
|
||||
|
||||
if (of_property_read_u16_array(np, "language-id", &hub->lang_id, 1))
|
||||
hub->lang_id = USB251XB_DEF_LANGUAGE_ID;
|
||||
|
@ -492,6 +477,10 @@ static int usb251xb_get_ofdata(struct usb251xb *hub,
|
|||
/* The following parameters are currently not exposed to devicetree, but
|
||||
* may be as soon as needed.
|
||||
*/
|
||||
hub->max_power_sp = USB251XB_DEF_MAX_POWER_SELF;
|
||||
hub->max_power_bp = USB251XB_DEF_MAX_POWER_BUS;
|
||||
hub->max_current_sp = USB251XB_DEF_MAX_CURRENT_SELF;
|
||||
hub->max_current_bp = USB251XB_DEF_MAX_CURRENT_BUS;
|
||||
hub->bat_charge_en = USB251XB_DEF_BATTERY_CHARGING_ENABLE;
|
||||
hub->boost_up = USB251XB_DEF_BOOST_UP;
|
||||
hub->boost_x = USB251XB_DEF_BOOST_X;
|
||||
|
|
|
@ -33,6 +33,12 @@ static const struct i2c_device_id isp1301_id[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(i2c, isp1301_id);
|
||||
|
||||
static const struct of_device_id isp1301_of_match[] = {
|
||||
{.compatible = "nxp,isp1301" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, isp1301_of_match);
|
||||
|
||||
static struct i2c_client *isp1301_i2c_client;
|
||||
|
||||
static int __isp1301_write(struct isp1301 *isp, u8 reg, u8 value, u8 clear)
|
||||
|
@ -130,6 +136,7 @@ static int isp1301_remove(struct i2c_client *client)
|
|||
static struct i2c_driver isp1301_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = of_match_ptr(isp1301_of_match),
|
||||
},
|
||||
.probe = isp1301_probe,
|
||||
.remove = isp1301_remove,
|
||||
|
|
|
@ -1500,7 +1500,7 @@ static int digi_read_oob_callback(struct urb *urb)
|
|||
return -1;
|
||||
|
||||
/* handle each oob command */
|
||||
for (i = 0; i < urb->actual_length - 4; i += 4) {
|
||||
for (i = 0; i < urb->actual_length - 3; i += 4) {
|
||||
opcode = buf[i];
|
||||
line = buf[i + 1];
|
||||
status = buf[i + 2];
|
||||
|
|
|
@ -1674,6 +1674,12 @@ static void edge_interrupt_callback(struct urb *urb)
|
|||
function = TIUMP_GET_FUNC_FROM_CODE(data[0]);
|
||||
dev_dbg(dev, "%s - port_number %d, function %d, info 0x%x\n", __func__,
|
||||
port_number, function, data[1]);
|
||||
|
||||
if (port_number >= edge_serial->serial->num_ports) {
|
||||
dev_err(dev, "bad port number %d\n", port_number);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
port = edge_serial->serial->port[port_number];
|
||||
edge_port = usb_get_serial_port_data(port);
|
||||
if (!edge_port) {
|
||||
|
@ -1755,7 +1761,7 @@ static void edge_bulk_in_callback(struct urb *urb)
|
|||
|
||||
port_number = edge_port->port->port_number;
|
||||
|
||||
if (edge_port->lsr_event) {
|
||||
if (urb->actual_length > 0 && edge_port->lsr_event) {
|
||||
edge_port->lsr_event = 0;
|
||||
dev_dbg(dev, "%s ===== Port %u LSR Status = %02x, Data = %02x ======\n",
|
||||
__func__, port_number, edge_port->lsr_mask, *data);
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#define BT_IGNITIONPRO_ID 0x2000
|
||||
|
||||
/* function prototypes */
|
||||
static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port);
|
||||
static void omninet_process_read_urb(struct urb *urb);
|
||||
static void omninet_write_bulk_callback(struct urb *urb);
|
||||
static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
|
@ -60,7 +59,6 @@ static struct usb_serial_driver zyxel_omninet_device = {
|
|||
.attach = omninet_attach,
|
||||
.port_probe = omninet_port_probe,
|
||||
.port_remove = omninet_port_remove,
|
||||
.open = omninet_open,
|
||||
.write = omninet_write,
|
||||
.write_room = omninet_write_room,
|
||||
.write_bulk_callback = omninet_write_bulk_callback,
|
||||
|
@ -140,17 +138,6 @@ static int omninet_port_remove(struct usb_serial_port *port)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct usb_serial_port *wport;
|
||||
|
||||
wport = serial->port[1];
|
||||
tty_port_tty_set(&wport->port, tty);
|
||||
|
||||
return usb_serial_generic_open(tty, port);
|
||||
}
|
||||
|
||||
#define OMNINET_HEADERLEN 4
|
||||
#define OMNINET_BULKOUTSIZE 64
|
||||
#define OMNINET_PAYLOADSIZE (OMNINET_BULKOUTSIZE - OMNINET_HEADERLEN)
|
||||
|
|
|
@ -200,6 +200,11 @@ static void safe_process_read_urb(struct urb *urb)
|
|||
if (!safe)
|
||||
goto out;
|
||||
|
||||
if (length < 2) {
|
||||
dev_err(&port->dev, "malformed packet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fcs = fcs_compute10(data, length, CRC10_INITFCS);
|
||||
if (fcs) {
|
||||
dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs);
|
||||
|
|
|
@ -2071,6 +2071,20 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110,
|
|||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_IGNORE_RESIDUE ),
|
||||
|
||||
/*
|
||||
* Reported by Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
|
||||
* The INIC-3619 bridge is used in the StarTech SLSODDU33B
|
||||
* SATA-USB enclosure for slimline optical drives.
|
||||
*
|
||||
* The quirk enables MakeMKV to properly exchange keys with
|
||||
* an installed BD drive.
|
||||
*/
|
||||
UNUSUAL_DEV( 0x13fd, 0x3609, 0x0209, 0x0209,
|
||||
"Initio Corporation",
|
||||
"INIC-3619",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_IGNORE_RESIDUE ),
|
||||
|
||||
/* Reported by Qinglin Ye <yestyle@gmail.com> */
|
||||
UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100,
|
||||
"Kingston",
|
||||
|
|
Загрузка…
Ссылка в новой задаче