diff options
Diffstat (limited to 'drivers')
33 files changed, 373 insertions, 107 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e78720b59d67..683617714e7c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1650,6 +1650,8 @@ static int acm_reset_resume(struct usb_interface *intf)  static const struct usb_device_id acm_ids[] = {  	/* quirky and broken devices */ +	{ USB_DEVICE(0x076d, 0x0006), /* Denso Cradle CU-321 */ +	.driver_info = NO_UNION_NORMAL, },/* has no union descriptor */  	{ USB_DEVICE(0x17ef, 0x7000), /* Lenovo USB modem */  	.driver_info = NO_UNION_NORMAL, },/* has no union descriptor */  	{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 66abdbcfbfa5..11635537c052 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -501,6 +501,7 @@ static void async_completed(struct urb *urb)  	as->status = urb->status;  	signr = as->signr;  	if (signr) { +		memset(&sinfo, 0, sizeof(sinfo));  		sinfo.si_signo = as->signr;  		sinfo.si_errno = as->status;  		sinfo.si_code = SI_ASYNCIO; @@ -2382,6 +2383,7 @@ static void usbdev_remove(struct usb_device *udev)  		wake_up_all(&ps->wait);  		list_del_init(&ps->list);  		if (ps->discsignr) { +			memset(&sinfo, 0, sizeof(sinfo));  			sinfo.si_signo = ps->discsignr;  			sinfo.si_errno = EPIPE;  			sinfo.si_code = SI_ASYNCIO; diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 172d64e585b6..52e0c4e5e48e 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -205,6 +205,18 @@ static void dwc3_omap_write_irq0_set(struct dwc3_omap *omap, u32 value)  						omap->irq0_offset, value);  } +static void dwc3_omap_write_irqmisc_clr(struct dwc3_omap *omap, u32 value) +{ +	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_MISC + +						omap->irqmisc_offset, value); +} + +static void dwc3_omap_write_irq0_clr(struct dwc3_omap *omap, u32 value) +{ +	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_0 - +						omap->irq0_offset, value); +} +  static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,  	enum omap_dwc3_vbus_id_status status)  { @@ -345,9 +357,23 @@ static void dwc3_omap_enable_irqs(struct dwc3_omap *omap)  static void dwc3_omap_disable_irqs(struct dwc3_omap *omap)  { +	u32			reg; +  	/* disable all IRQs */ -	dwc3_omap_write_irqmisc_set(omap, 0x00); -	dwc3_omap_write_irq0_set(omap, 0x00); +	reg = USBOTGSS_IRQO_COREIRQ_ST; +	dwc3_omap_write_irq0_clr(omap, reg); + +	reg = (USBOTGSS_IRQMISC_OEVT | +			USBOTGSS_IRQMISC_DRVVBUS_RISE | +			USBOTGSS_IRQMISC_CHRGVBUS_RISE | +			USBOTGSS_IRQMISC_DISCHRGVBUS_RISE | +			USBOTGSS_IRQMISC_IDPULLUP_RISE | +			USBOTGSS_IRQMISC_DRVVBUS_FALL | +			USBOTGSS_IRQMISC_CHRGVBUS_FALL | +			USBOTGSS_IRQMISC_DISCHRGVBUS_FALL | +			USBOTGSS_IRQMISC_IDPULLUP_FALL); + +	dwc3_omap_write_irqmisc_clr(omap, reg);  }  static u64 dwc3_omap_dma_mask = DMA_BIT_MASK(32); diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 75648145dc1b..c42765b3a060 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1161,7 +1161,6 @@ static ssize_t interf_grp_compatible_id_store(struct usb_os_desc *desc,  	if (desc->opts_mutex)  		mutex_lock(desc->opts_mutex);  	memcpy(desc->ext_compat_id, page, l); -	desc->ext_compat_id[l] = '\0';  	if (desc->opts_mutex)  		mutex_unlock(desc->opts_mutex); @@ -1192,7 +1191,6 @@ static ssize_t interf_grp_sub_compatible_id_store(struct usb_os_desc *desc,  	if (desc->opts_mutex)  		mutex_lock(desc->opts_mutex);  	memcpy(desc->ext_compat_id + 8, page, l); -	desc->ext_compat_id[l + 8] = '\0';  	if (desc->opts_mutex)  		mutex_unlock(desc->opts_mutex); diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 426d69a9c018..a2612fb79eff 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -569,7 +569,7 @@ fail:  	return status;  } -const struct file_operations f_hidg_fops = { +static const struct file_operations f_hidg_fops = {  	.owner		= THIS_MODULE,  	.open		= f_hidg_open,  	.release	= f_hidg_release, diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index c89e96cfa3e4..c0c3ef272714 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c @@ -417,7 +417,10 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt)  			return -EINVAL;  		spin_lock(&port->lock); -		__pn_reset(f); + +		if (fp->in_ep->driver_data) +			__pn_reset(f); +  		if (alt == 1) {  			int i; diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index e07c50ced64d..e3dae47baef3 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -344,7 +344,7 @@ static struct usb_endpoint_descriptor ss_int_source_desc = {  	.bInterval =		USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL),  }; -struct usb_ss_ep_comp_descriptor ss_int_source_comp_desc = { +static struct usb_ss_ep_comp_descriptor ss_int_source_comp_desc = {  	.bLength =		USB_DT_SS_EP_COMP_SIZE,  	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, @@ -362,7 +362,7 @@ static struct usb_endpoint_descriptor ss_int_sink_desc = {  	.bInterval =		USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL),  }; -struct usb_ss_ep_comp_descriptor ss_int_sink_comp_desc = { +static struct usb_ss_ep_comp_descriptor ss_int_sink_comp_desc = {  	.bLength =		USB_DT_SS_EP_COMP_SIZE,  	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 33e16658e5cf..6d3eb8b00a48 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -54,7 +54,7 @@  #define UNFLW_CTRL	8  #define OVFLW_CTRL	10 -const char *uac2_name = "snd_uac2"; +static const char *uac2_name = "snd_uac2";  struct uac2_req {  	struct uac2_rtd_params *pp; /* parent param */ @@ -634,7 +634,7 @@ static struct usb_interface_descriptor std_ac_if_desc = {  };  /* Clock source for IN traffic */ -struct uac_clock_source_descriptor in_clk_src_desc = { +static struct uac_clock_source_descriptor in_clk_src_desc = {  	.bLength = sizeof in_clk_src_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE, @@ -646,7 +646,7 @@ struct uac_clock_source_descriptor in_clk_src_desc = {  };  /* Clock source for OUT traffic */ -struct uac_clock_source_descriptor out_clk_src_desc = { +static struct uac_clock_source_descriptor out_clk_src_desc = {  	.bLength = sizeof out_clk_src_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE, @@ -658,7 +658,7 @@ struct uac_clock_source_descriptor out_clk_src_desc = {  };  /* Input Terminal for USB_OUT */ -struct uac2_input_terminal_descriptor usb_out_it_desc = { +static struct uac2_input_terminal_descriptor usb_out_it_desc = {  	.bLength = sizeof usb_out_it_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE, @@ -672,7 +672,7 @@ struct uac2_input_terminal_descriptor usb_out_it_desc = {  };  /* Input Terminal for I/O-In */ -struct uac2_input_terminal_descriptor io_in_it_desc = { +static struct uac2_input_terminal_descriptor io_in_it_desc = {  	.bLength = sizeof io_in_it_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE, @@ -686,7 +686,7 @@ struct uac2_input_terminal_descriptor io_in_it_desc = {  };  /* Ouput Terminal for USB_IN */ -struct uac2_output_terminal_descriptor usb_in_ot_desc = { +static struct uac2_output_terminal_descriptor usb_in_ot_desc = {  	.bLength = sizeof usb_in_ot_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE, @@ -700,7 +700,7 @@ struct uac2_output_terminal_descriptor usb_in_ot_desc = {  };  /* Ouput Terminal for I/O-Out */ -struct uac2_output_terminal_descriptor io_out_ot_desc = { +static struct uac2_output_terminal_descriptor io_out_ot_desc = {  	.bLength = sizeof io_out_ot_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE, @@ -713,7 +713,7 @@ struct uac2_output_terminal_descriptor io_out_ot_desc = {  	.bmControls = (CONTROL_RDWR << COPY_CTRL),  }; -struct uac2_ac_header_descriptor ac_hdr_desc = { +static struct uac2_ac_header_descriptor ac_hdr_desc = {  	.bLength = sizeof ac_hdr_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE, @@ -751,7 +751,7 @@ static struct usb_interface_descriptor std_as_out_if1_desc = {  };  /* Audio Stream OUT Intface Desc */ -struct uac2_as_header_descriptor as_out_hdr_desc = { +static struct uac2_as_header_descriptor as_out_hdr_desc = {  	.bLength = sizeof as_out_hdr_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE, @@ -764,7 +764,7 @@ struct uac2_as_header_descriptor as_out_hdr_desc = {  };  /* Audio USB_OUT Format */ -struct uac2_format_type_i_descriptor as_out_fmt1_desc = { +static struct uac2_format_type_i_descriptor as_out_fmt1_desc = {  	.bLength = sizeof as_out_fmt1_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE,  	.bDescriptorSubtype = UAC_FORMAT_TYPE, @@ -772,7 +772,7 @@ struct uac2_format_type_i_descriptor as_out_fmt1_desc = {  };  /* STD AS ISO OUT Endpoint */ -struct usb_endpoint_descriptor fs_epout_desc = { +static struct usb_endpoint_descriptor fs_epout_desc = {  	.bLength = USB_DT_ENDPOINT_SIZE,  	.bDescriptorType = USB_DT_ENDPOINT, @@ -782,7 +782,7 @@ struct usb_endpoint_descriptor fs_epout_desc = {  	.bInterval = 1,  }; -struct usb_endpoint_descriptor hs_epout_desc = { +static struct usb_endpoint_descriptor hs_epout_desc = {  	.bLength = USB_DT_ENDPOINT_SIZE,  	.bDescriptorType = USB_DT_ENDPOINT, @@ -828,7 +828,7 @@ static struct usb_interface_descriptor std_as_in_if1_desc = {  };  /* Audio Stream IN Intface Desc */ -struct uac2_as_header_descriptor as_in_hdr_desc = { +static struct uac2_as_header_descriptor as_in_hdr_desc = {  	.bLength = sizeof as_in_hdr_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE, @@ -841,7 +841,7 @@ struct uac2_as_header_descriptor as_in_hdr_desc = {  };  /* Audio USB_IN Format */ -struct uac2_format_type_i_descriptor as_in_fmt1_desc = { +static struct uac2_format_type_i_descriptor as_in_fmt1_desc = {  	.bLength = sizeof as_in_fmt1_desc,  	.bDescriptorType = USB_DT_CS_INTERFACE,  	.bDescriptorSubtype = UAC_FORMAT_TYPE, @@ -849,7 +849,7 @@ struct uac2_format_type_i_descriptor as_in_fmt1_desc = {  };  /* STD AS ISO IN Endpoint */ -struct usb_endpoint_descriptor fs_epin_desc = { +static struct usb_endpoint_descriptor fs_epin_desc = {  	.bLength = USB_DT_ENDPOINT_SIZE,  	.bDescriptorType = USB_DT_ENDPOINT, @@ -859,7 +859,7 @@ struct usb_endpoint_descriptor fs_epin_desc = {  	.bInterval = 1,  }; -struct usb_endpoint_descriptor hs_epin_desc = { +static struct usb_endpoint_descriptor hs_epin_desc = {  	.bLength = USB_DT_ENDPOINT_SIZE,  	.bDescriptorType = USB_DT_ENDPOINT, @@ -1563,7 +1563,7 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f)  		agdev->out_ep->driver_data = NULL;  } -struct usb_function *afunc_alloc(struct usb_function_instance *fi) +static struct usb_function *afunc_alloc(struct usb_function_instance *fi)  {  	struct audio_dev *agdev;  	struct f_uac2_opts *opts; diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 5aad7fededa5..8b818fd027b3 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -27,6 +27,7 @@  #include "uvc.h"  #include "uvc_queue.h"  #include "uvc_video.h" +#include "uvc_v4l2.h"  /* --------------------------------------------------------------------------   * Requests handling diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 9cb86bc1a9a5..50a5e637ca35 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -21,6 +21,7 @@  #include "uvc.h"  #include "uvc_queue.h" +#include "uvc_video.h"  /* --------------------------------------------------------------------------   * Video codecs diff --git a/drivers/usb/gadget/legacy/g_ffs.c b/drivers/usb/gadget/legacy/g_ffs.c index 06acfa55864a..b01b88e1b716 100644 --- a/drivers/usb/gadget/legacy/g_ffs.c +++ b/drivers/usb/gadget/legacy/g_ffs.c @@ -133,7 +133,9 @@ struct gfs_configuration {  	struct usb_configuration c;  	int (*eth)(struct usb_configuration *c);  	int num; -} gfs_configurations[] = { +}; + +static struct gfs_configuration gfs_configurations[] = {  #ifdef CONFIG_USB_FUNCTIONFS_RNDIS  	{  		.eth		= bind_rndis_config, @@ -278,7 +280,7 @@ static void *functionfs_acquire_dev(struct ffs_dev *dev)  	if (!try_module_get(THIS_MODULE))  		return ERR_PTR(-ENOENT); -	return 0; +	return NULL;  }  static void functionfs_release_dev(struct ffs_dev *dev) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 7f76c8a12f89..fd53c9ebd662 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -37,6 +37,9 @@  #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI	0x8c31  #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI	0x9c31 +#define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI		0x22b5 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI		0xa12f +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI	0x9d2f  static const char hcd_name[] = "xhci_hcd"; @@ -133,6 +136,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)  		pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {  		xhci->quirks |= XHCI_SPURIOUS_REBOOT;  	} +	if (pdev->vendor == PCI_VENDOR_ID_INTEL && +		(pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || +		 pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || +		 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) { +		xhci->quirks |= XHCI_PME_STUCK_QUIRK; +	}  	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&  			pdev->device == PCI_DEVICE_ID_EJ168) {  		xhci->quirks |= XHCI_RESET_ON_RESUME; @@ -159,6 +168,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)  				"QUIRK: Resetting on resume");  } +/* + * Make sure PME works on some Intel xHCI controllers by writing 1 to clear + * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4 + */ +static void xhci_pme_quirk(struct xhci_hcd *xhci) +{ +	u32 val; +	void __iomem *reg; + +	reg = (void __iomem *) xhci->cap_regs + 0x80a4; +	val = readl(reg); +	writel(val | BIT(28), reg); +	readl(reg); +} +  /* called during probe() after chip reset completes */  static int xhci_pci_setup(struct usb_hcd *hcd)  { @@ -283,6 +307,9 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)  	if (xhci->quirks & XHCI_COMP_MODE_QUIRK)  		pdev->no_d3cold = true; +	if (xhci->quirks & XHCI_PME_STUCK_QUIRK) +		xhci_pme_quirk(xhci); +  	return xhci_suspend(xhci, do_wakeup);  } @@ -313,6 +340,9 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)  	if (pdev->vendor == PCI_VENDOR_ID_INTEL)  		usb_enable_intel_xhci_ports(pdev); +	if (xhci->quirks & XHCI_PME_STUCK_QUIRK) +		xhci_pme_quirk(xhci); +  	retval = xhci_resume(xhci, hibernated);  	return retval;  } diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 08d402b15482..0e11d61408ff 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -83,16 +83,6 @@ static int xhci_plat_probe(struct platform_device *pdev)  	if (irq < 0)  		return -ENODEV; - -	if (of_device_is_compatible(pdev->dev.of_node, -				    "marvell,armada-375-xhci") || -	    of_device_is_compatible(pdev->dev.of_node, -				    "marvell,armada-380-xhci")) { -		ret = xhci_mvebu_mbus_init_quirk(pdev); -		if (ret) -			return ret; -	} -  	/* Initialize dma_mask and coherent_dma_mask to 32-bits */  	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));  	if (ret) @@ -127,6 +117,15 @@ static int xhci_plat_probe(struct platform_device *pdev)  			goto put_hcd;  	} +	if (of_device_is_compatible(pdev->dev.of_node, +				    "marvell,armada-375-xhci") || +	    of_device_is_compatible(pdev->dev.of_node, +				    "marvell,armada-380-xhci")) { +		ret = xhci_mvebu_mbus_init_quirk(pdev); +		if (ret) +			goto disable_clk; +	} +  	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (ret)  		goto disable_clk; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 88da8d629820..5fb66db89e05 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1729,7 +1729,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,  	if (!command)  		return; -	ep->ep_state |= EP_HALTED; +	ep->ep_state |= EP_HALTED | EP_RECENTLY_HALTED;  	ep->stopped_stream = stream_id;  	xhci_queue_reset_ep(xhci, command, slot_id, ep_index); @@ -1946,7 +1946,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,  	if (event_trb != ep_ring->dequeue) {  		/* The event was for the status stage */  		if (event_trb == td->last_trb) { -			if (td->urb->actual_length != 0) { +			if (td->urb_length_set) {  				/* Don't overwrite a previously set error code  				 */  				if ((*status == -EINPROGRESS || *status == 0) && @@ -1960,7 +1960,13 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,  					td->urb->transfer_buffer_length;  			}  		} else { -		/* Maybe the event was for the data stage? */ +			/* +			 * Maybe the event was for the data stage? If so, update +			 * already the actual_length of the URB and flag it as +			 * set, so that it is not overwritten in the event for +			 * the last TRB. +			 */ +			td->urb_length_set = true;  			td->urb->actual_length =  				td->urb->transfer_buffer_length -  				EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ec8ac1674854..b06d1a53652d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1338,6 +1338,12 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)  		goto exit;  	} +	/* Reject urb if endpoint is in soft reset, queue must stay empty */ +	if (xhci->devs[slot_id]->eps[ep_index].ep_state & EP_CONFIG_PENDING) { +		xhci_warn(xhci, "Can't enqueue URB while ep is in soft reset\n"); +		ret = -EINVAL; +	} +  	if (usb_endpoint_xfer_isoc(&urb->ep->desc))  		size = urb->number_of_packets;  	else @@ -2948,23 +2954,36 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,  	}  } -/* Called when clearing halted device. The core should have sent the control +/* Called after clearing a halted device. USB core should have sent the control   * message to clear the device halt condition. The host side of the halt should - * already be cleared with a reset endpoint command issued when the STALL tx - * event was received. - * - * Context: in_interrupt + * already be cleared with a reset endpoint command issued immediately when the + * STALL tx event was received.   */  void xhci_endpoint_reset(struct usb_hcd *hcd,  		struct usb_host_endpoint *ep)  {  	struct xhci_hcd *xhci; +	struct usb_device *udev; +	struct xhci_virt_device *virt_dev; +	struct xhci_virt_ep *virt_ep; +	struct xhci_input_control_ctx *ctrl_ctx; +	struct xhci_command *command; +	unsigned int ep_index, ep_state; +	unsigned long flags; +	u32 ep_flag;  	xhci = hcd_to_xhci(hcd); +	udev = (struct usb_device *) ep->hcpriv; +	if (!ep->hcpriv) +		return; +	virt_dev = xhci->devs[udev->slot_id]; +	ep_index = xhci_get_endpoint_index(&ep->desc); +	virt_ep = &virt_dev->eps[ep_index]; +	ep_state = virt_ep->ep_state;  	/* -	 * We might need to implement the config ep cmd in xhci 4.8.1 note: +	 * Implement the config ep command in xhci 4.6.8 additional note:  	 * The Reset Endpoint Command may only be issued to endpoints in the  	 * Halted state. If software wishes reset the Data Toggle or Sequence  	 * Number of an endpoint that isn't in the Halted state, then software @@ -2972,9 +2991,72 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,  	 * for the target endpoint. that is in the Stopped state.  	 */ -	/* For now just print debug to follow the situation */ -	xhci_dbg(xhci, "Endpoint 0x%x ep reset callback called\n", -		 ep->desc.bEndpointAddress); +	if (ep_state & SET_DEQ_PENDING || ep_state & EP_RECENTLY_HALTED) { +		virt_ep->ep_state &= ~EP_RECENTLY_HALTED; +		xhci_dbg(xhci, "ep recently halted, no toggle reset needed\n"); +		return; +	} + +	/* Only interrupt and bulk ep's use Data toggle, USB2 spec 5.5.4-> */ +	if (usb_endpoint_xfer_control(&ep->desc) || +	    usb_endpoint_xfer_isoc(&ep->desc)) +		return; + +	ep_flag = xhci_get_endpoint_flag(&ep->desc); + +	if (ep_flag == SLOT_FLAG || ep_flag == EP0_FLAG) +		return; + +	command = xhci_alloc_command(xhci, true, true, GFP_NOWAIT); +	if (!command) { +		xhci_err(xhci, "Could not allocate xHCI command structure.\n"); +		return; +	} + +	spin_lock_irqsave(&xhci->lock, flags); + +	/* block ringing ep doorbell */ +	virt_ep->ep_state |= EP_CONFIG_PENDING; + +	/* +	 * Make sure endpoint ring is empty before resetting the toggle/seq. +	 * Driver is required to synchronously cancel all transfer request. +	 * +	 * xhci 4.6.6 says we can issue a configure endpoint command on a +	 * running endpoint ring as long as it's idle (queue empty) +	 */ + +	if (!list_empty(&virt_ep->ring->td_list)) { +		dev_err(&udev->dev, "EP not empty, refuse reset\n"); +		spin_unlock_irqrestore(&xhci->lock, flags); +		goto cleanup; +	} + +	xhci_dbg(xhci, "Reset toggle/seq for slot %d, ep_index: %d\n", +		 udev->slot_id, ep_index); + +	ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); +	if (!ctrl_ctx) { +		xhci_err(xhci, "Could not get input context, bad type. virt_dev: %p, in_ctx %p\n", +			 virt_dev, virt_dev->in_ctx); +		spin_unlock_irqrestore(&xhci->lock, flags); +		goto cleanup; +	} +	xhci_setup_input_ctx_for_config_ep(xhci, command->in_ctx, +					   virt_dev->out_ctx, ctrl_ctx, +					   ep_flag, ep_flag); +	xhci_endpoint_copy(xhci, command->in_ctx, virt_dev->out_ctx, ep_index); + +	xhci_queue_configure_endpoint(xhci, command, command->in_ctx->dma, +				     udev->slot_id, false); +	xhci_ring_cmd_db(xhci); +	spin_unlock_irqrestore(&xhci->lock, flags); + +	wait_for_completion(command->completion); + +cleanup: +	virt_ep->ep_state &= ~EP_CONFIG_PENDING; +	xhci_free_command(xhci, command);  }  static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 974514762a14..265ab1771d24 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1,3 +1,4 @@ +  /*   * xHCI host controller driver   * @@ -88,9 +89,10 @@ struct xhci_cap_regs {  #define HCS_IST(p)		(((p) >> 0) & 0xf)  /* bits 4:7, max number of Event Ring segments */  #define HCS_ERST_MAX(p)		(((p) >> 4) & 0xf) +/* bits 21:25 Hi 5 bits of Scratchpad buffers SW must allocate for the HW */  /* bit 26 Scratchpad restore - for save/restore HW state - not used yet */ -/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */ -#define HCS_MAX_SCRATCHPAD(p)   (((p) >> 27) & 0x1f) +/* bits 27:31 Lo 5 bits of Scratchpad buffers SW must allocate for the HW */ +#define HCS_MAX_SCRATCHPAD(p)   ((((p) >> 16) & 0x3e0) | (((p) >> 27) & 0x1f))  /* HCSPARAMS3 - hcs_params3 - bitmasks */  /* bits 0:7, Max U1 to U0 latency for the roothub ports */ @@ -863,6 +865,8 @@ struct xhci_virt_ep {  #define EP_HAS_STREAMS		(1 << 4)  /* Transitioning the endpoint to not using streams, don't enqueue URBs */  #define EP_GETTING_NO_STREAMS	(1 << 5) +#define EP_RECENTLY_HALTED	(1 << 6) +#define EP_CONFIG_PENDING	(1 << 7)  	/* ----  Related to URB cancellation ---- */  	struct list_head	cancelled_td_list;  	struct xhci_td		*stopped_td; @@ -1288,6 +1292,8 @@ struct xhci_td {  	struct xhci_segment	*start_seg;  	union xhci_trb		*first_trb;  	union xhci_trb		*last_trb; +	/* actual_length of the URB has already been set */ +	bool			urb_length_set;  };  /* xHCI command default timeout value */ @@ -1560,6 +1566,7 @@ struct xhci_hcd {  #define XHCI_SPURIOUS_WAKEUP	(1 << 18)  /* For controllers with a broken beyond repair streams implementation */  #define XHCI_BROKEN_STREAMS	(1 << 19) +#define XHCI_PME_STUCK_QUIRK	(1 << 20)  	unsigned int		num_active_eps;  	unsigned int		limit_active_eps;  	/* There are two roothubs to keep track of bus suspend info for */ diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c index eba9b82e2d70..3cb98b1d5d29 100644 --- a/drivers/usb/isp1760/isp1760-hcd.c +++ b/drivers/usb/isp1760/isp1760-hcd.c @@ -1274,7 +1274,7 @@ static void errata2_function(unsigned long data)  	for (slot = 0; slot < 32; slot++)  		if (priv->atl_slots[slot].qh && time_after(jiffies,  					priv->atl_slots[slot].timestamp + -					SLOT_TIMEOUT * HZ / 1000)) { +					msecs_to_jiffies(SLOT_TIMEOUT))) {  			ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd);  			if (!FROM_DW0_VALID(ptd.dw0) &&  					!FROM_DW3_ACTIVE(ptd.dw3)) @@ -1286,7 +1286,7 @@ static void errata2_function(unsigned long data)  	spin_unlock_irqrestore(&priv->lock, spinflags); -	errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; +	errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD);  	add_timer(&errata2_timer);  } @@ -1336,7 +1336,7 @@ static int isp1760_run(struct usb_hcd *hcd)  		return retval;  	setup_timer(&errata2_timer, errata2_function, (unsigned long)hcd); -	errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; +	errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD);  	add_timer(&errata2_timer);  	chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG); diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index e6f4cbfeed97..067920f2d570 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1969,10 +1969,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)  		goto fail0;  	} -	pm_runtime_use_autosuspend(musb->controller); -	pm_runtime_set_autosuspend_delay(musb->controller, 200); -	pm_runtime_enable(musb->controller); -  	spin_lock_init(&musb->lock);  	musb->board_set_power = plat->set_power;  	musb->min_power = plat->min_power; @@ -1991,6 +1987,12 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)  	musb_readl = musb_default_readl;  	musb_writel = musb_default_writel; +	/* We need musb_read/write functions initialized for PM */ +	pm_runtime_use_autosuspend(musb->controller); +	pm_runtime_set_autosuspend_delay(musb->controller, 200); +	pm_runtime_irq_safe(musb->controller); +	pm_runtime_enable(musb->controller); +  	/* The musb_platform_init() call:  	 *   - adjusts musb->mregs  	 *   - sets the musb->isr diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 53bd0e71d19f..a900c9877195 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -457,12 +457,27 @@ static int dsps_musb_init(struct musb *musb)  	if (IS_ERR(musb->xceiv))  		return PTR_ERR(musb->xceiv); +	musb->phy = devm_phy_get(dev->parent, "usb2-phy"); +  	/* Returns zero if e.g. not clocked */  	rev = dsps_readl(reg_base, wrp->revision);  	if (!rev)  		return -ENODEV;  	usb_phy_init(musb->xceiv); +	if (IS_ERR(musb->phy))  { +		musb->phy = NULL; +	} else { +		ret = phy_init(musb->phy); +		if (ret < 0) +			return ret; +		ret = phy_power_on(musb->phy); +		if (ret) { +			phy_exit(musb->phy); +			return ret; +		} +	} +  	setup_timer(&glue->timer, otg_timer, (unsigned long) musb);  	/* Reset the musb */ @@ -502,6 +517,8 @@ static int dsps_musb_exit(struct musb *musb)  	del_timer_sync(&glue->timer);  	usb_phy_shutdown(musb->xceiv); +	phy_power_off(musb->phy); +	phy_exit(musb->phy);  	debugfs_remove_recursive(glue->dbgfs_root);  	return 0; @@ -610,7 +627,7 @@ static int dsps_musb_reset(struct musb *musb)  	struct device *dev = musb->controller;  	struct dsps_glue *glue = dev_get_drvdata(dev->parent);  	const struct dsps_musb_wrapper *wrp = glue->wrp; -	int session_restart = 0; +	int session_restart = 0, error;  	if (glue->sw_babble_enabled)  		session_restart = sw_babble_control(musb); @@ -624,8 +641,14 @@ static int dsps_musb_reset(struct musb *musb)  		dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset));  		usleep_range(100, 200);  		usb_phy_shutdown(musb->xceiv); +		error = phy_power_off(musb->phy); +		if (error) +			dev_err(dev, "phy shutdown failed: %i\n", error);  		usleep_range(100, 200);  		usb_phy_init(musb->xceiv); +		error = phy_power_on(musb->phy); +		if (error) +			dev_err(dev, "phy powerup failed: %i\n", error);  		session_restart = 1;  	} @@ -687,7 +710,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,  	struct musb_hdrc_config	*config;  	struct platform_device *musb;  	struct device_node *dn = parent->dev.of_node; -	int ret; +	int ret, val;  	memset(resources, 0, sizeof(resources));  	res = platform_get_resource_byname(parent, IORESOURCE_MEM, "mc"); @@ -739,7 +762,10 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,  	pdata.mode = get_musb_port_mode(dev);  	/* DT keeps this entry in mA, musb expects it as per USB spec */  	pdata.power = get_int_prop(dn, "mentor,power") / 2; -	config->multipoint = of_property_read_bool(dn, "mentor,multipoint"); + +	ret = of_property_read_u32(dn, "mentor,multipoint", &val); +	if (!ret && val) +		config->multipoint = true;  	ret = platform_device_add_data(musb, &pdata, sizeof(pdata));  	if (ret) { diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 883a9adfdfff..c3d5fc9dfb5b 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2613,7 +2613,7 @@ static const struct hc_driver musb_hc_driver = {  	.description		= "musb-hcd",  	.product_desc		= "MUSB HDRC host driver",  	.hcd_priv_size		= sizeof(struct musb *), -	.flags			= HCD_USB2 | HCD_MEMORY, +	.flags			= HCD_USB2 | HCD_MEMORY | HCD_BH,  	/* not using irq handler or reset hooks from usbcore, since  	 * those must be shared with peripheral code for OTG configs diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 763649eb4987..cc752d8c7773 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -516,7 +516,7 @@ static int omap2430_probe(struct platform_device *pdev)  	struct omap2430_glue		*glue;  	struct device_node		*np = pdev->dev.of_node;  	struct musb_hdrc_config		*config; -	int				ret = -ENOMEM; +	int				ret = -ENOMEM, val;  	glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);  	if (!glue) @@ -559,7 +559,10 @@ static int omap2430_probe(struct platform_device *pdev)  		of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);  		of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);  		of_property_read_u32(np, "power", (u32 *)&pdata->power); -		config->multipoint = of_property_read_bool(np, "multipoint"); + +		ret = of_property_read_u32(np, "multipoint", &val); +		if (!ret && val) +			config->multipoint = true;  		pdata->board_data	= data;  		pdata->config		= config; diff --git a/drivers/usb/renesas_usbhs/Kconfig b/drivers/usb/renesas_usbhs/Kconfig index de83b9d0cd5c..ebc99ee076ce 100644 --- a/drivers/usb/renesas_usbhs/Kconfig +++ b/drivers/usb/renesas_usbhs/Kconfig @@ -6,6 +6,7 @@ config USB_RENESAS_USBHS  	tristate 'Renesas USBHS controller'  	depends on USB_GADGET  	depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST +	depends on EXTCON || !EXTCON # if EXTCON=m, USBHS cannot be built-in  	default n  	help  	  Renesas USBHS is a discrete USB host and peripheral controller chip diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 9374bd2aba20..8936a83c96cd 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -38,56 +38,51 @@ static int usb_serial_device_match(struct device *dev,  	return 0;  } -static ssize_t port_number_show(struct device *dev, -				struct device_attribute *attr, char *buf) -{ -	struct usb_serial_port *port = to_usb_serial_port(dev); - -	return sprintf(buf, "%d\n", port->port_number); -} -static DEVICE_ATTR_RO(port_number); -  static int usb_serial_device_probe(struct device *dev)  {  	struct usb_serial_driver *driver;  	struct usb_serial_port *port; +	struct device *tty_dev;  	int retval = 0;  	int minor;  	port = to_usb_serial_port(dev); -	if (!port) { -		retval = -ENODEV; -		goto exit; -	} +	if (!port) +		return -ENODEV;  	/* make sure suspend/resume doesn't race against port_probe */  	retval = usb_autopm_get_interface(port->serial->interface);  	if (retval) -		goto exit; +		return retval;  	driver = port->serial->type;  	if (driver->port_probe) {  		retval = driver->port_probe(port);  		if (retval) -			goto exit_with_autopm; +			goto err_autopm_put;  	} -	retval = device_create_file(dev, &dev_attr_port_number); -	if (retval) { -		if (driver->port_remove) -			retval = driver->port_remove(port); -		goto exit_with_autopm; +	minor = port->minor; +	tty_dev = tty_register_device(usb_serial_tty_driver, minor, dev); +	if (IS_ERR(tty_dev)) { +		retval = PTR_ERR(tty_dev); +		goto err_port_remove;  	} -	minor = port->minor; -	tty_register_device(usb_serial_tty_driver, minor, dev); +	usb_autopm_put_interface(port->serial->interface); +  	dev_info(&port->serial->dev->dev,  		 "%s converter now attached to ttyUSB%d\n",  		 driver->description, minor); -exit_with_autopm: +	return 0; + +err_port_remove: +	if (driver->port_remove) +		driver->port_remove(port); +err_autopm_put:  	usb_autopm_put_interface(port->serial->interface); -exit: +  	return retval;  } @@ -114,8 +109,6 @@ static int usb_serial_device_remove(struct device *dev)  	minor = port->minor;  	tty_unregister_device(usb_serial_tty_driver, minor); -	device_remove_file(&port->dev, &dev_attr_port_number); -  	driver = port->serial->type;  	if (driver->port_remove)  		retval = driver->port_remove(port); diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 2d72aa3564a3..ede4f5fcfadd 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -84,6 +84,10 @@ struct ch341_private {  	u8 line_status; /* active status of modem control inputs */  }; +static void ch341_set_termios(struct tty_struct *tty, +			      struct usb_serial_port *port, +			      struct ktermios *old_termios); +  static int ch341_control_out(struct usb_device *dev, u8 request,  			     u16 value, u16 index)  { @@ -309,19 +313,12 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)  	struct ch341_private *priv = usb_get_serial_port_data(port);  	int r; -	priv->baud_rate = DEFAULT_BAUD_RATE; -  	r = ch341_configure(serial->dev, priv);  	if (r)  		goto out; -	r = ch341_set_handshake(serial->dev, priv->line_control); -	if (r) -		goto out; - -	r = ch341_set_baudrate(serial->dev, priv); -	if (r) -		goto out; +	if (tty) +		ch341_set_termios(tty, port, NULL);  	dev_dbg(&port->dev, "%s - submitting interrupt urb\n", __func__);  	r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 29fa1c3d0089..3806e7014199 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -14,6 +14,7 @@  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt  #include <linux/kernel.h> +#include <linux/module.h>  #include <linux/slab.h>  #include <linux/tty.h>  #include <linux/console.h> @@ -144,6 +145,7 @@ static int usb_console_setup(struct console *co, char *options)  			init_ldsem(&tty->ldisc_sem);  			INIT_LIST_HEAD(&tty->tty_files);  			kref_get(&tty->driver->kref); +			__module_get(tty->driver->owner);  			tty->ops = &usb_console_fake_tty_ops;  			if (tty_init_termios(tty)) {  				retval = -ENOMEM; diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index f40c856ff758..84ce2d74894c 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -147,6 +147,8 @@ static const struct usb_device_id id_table[] = {  	{ USB_DEVICE(0x166A, 0x0305) }, /* Clipsal C-5000CT2 C-Bus Spectrum Colour Touchscreen */  	{ USB_DEVICE(0x166A, 0x0401) }, /* Clipsal L51xx C-Bus Architectural Dimmer */  	{ USB_DEVICE(0x166A, 0x0101) }, /* Clipsal 5560884 C-Bus Multi-room Audio Matrix Switcher */ +	{ USB_DEVICE(0x16C0, 0x09B0) }, /* Lunatico Seletek */ +	{ USB_DEVICE(0x16C0, 0x09B1) }, /* Lunatico Seletek */  	{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */  	{ USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */  	{ USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1ebb351b9e9a..3086dec0ef53 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -799,6 +799,8 @@ static const struct usb_device_id id_table_combined[] = {  	{ USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) }, +	{ USB_DEVICE(FTDI_VID, CYBER_CORTEX_AV_PID), +		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },  	{ USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),  		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },  	{ USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID), @@ -978,6 +980,23 @@ static const struct usb_device_id id_table_combined[] = {  	{ USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) },  	/* GE Healthcare devices */  	{ USB_DEVICE(GE_HEALTHCARE_VID, GE_HEALTHCARE_NEMO_TRACKER_PID) }, +	/* Active Research (Actisense) devices */ +	{ USB_DEVICE(FTDI_VID, ACTISENSE_NDC_PID) }, +	{ USB_DEVICE(FTDI_VID, ACTISENSE_USG_PID) }, +	{ USB_DEVICE(FTDI_VID, ACTISENSE_NGT_PID) }, +	{ USB_DEVICE(FTDI_VID, ACTISENSE_NGW_PID) }, +	{ USB_DEVICE(FTDI_VID, ACTISENSE_D9AC_PID) }, +	{ USB_DEVICE(FTDI_VID, ACTISENSE_D9AD_PID) }, +	{ USB_DEVICE(FTDI_VID, ACTISENSE_D9AE_PID) }, +	{ USB_DEVICE(FTDI_VID, ACTISENSE_D9AF_PID) }, +	{ USB_DEVICE(FTDI_VID, CHETCO_SEAGAUGE_PID) }, +	{ USB_DEVICE(FTDI_VID, CHETCO_SEASWITCH_PID) }, +	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_NMEA2000_PID) }, +	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ETHERNET_PID) }, +	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_WIFI_PID) }, +	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_DISPLAY_PID) }, +	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_LITE_PID) }, +	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ANALOG_PID) },  	{ }					/* Terminating entry */  }; diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index e52409c9be99..56b1b55c4751 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -38,6 +38,9 @@  #define FTDI_LUMEL_PD12_PID	0x6002 +/* Cyber Cortex AV by Fabulous Silicon (http://fabuloussilicon.com) */ +#define CYBER_CORTEX_AV_PID	0x8698 +  /*   * Marvell OpenRD Base, Client   * http://www.open-rd.org @@ -1438,3 +1441,23 @@   */  #define GE_HEALTHCARE_VID		0x1901  #define GE_HEALTHCARE_NEMO_TRACKER_PID	0x0015 + +/* + * Active Research (Actisense) devices + */ +#define ACTISENSE_NDC_PID		0xD9A8 /* NDC USB Serial Adapter */ +#define ACTISENSE_USG_PID		0xD9A9 /* USG USB Serial Adapter */ +#define ACTISENSE_NGT_PID		0xD9AA /* NGT NMEA2000 Interface */ +#define ACTISENSE_NGW_PID		0xD9AB /* NGW NMEA2000 Gateway */ +#define ACTISENSE_D9AC_PID		0xD9AC /* Actisense Reserved */ +#define ACTISENSE_D9AD_PID		0xD9AD /* Actisense Reserved */ +#define ACTISENSE_D9AE_PID		0xD9AE /* Actisense Reserved */ +#define ACTISENSE_D9AF_PID		0xD9AF /* Actisense Reserved */ +#define CHETCO_SEAGAUGE_PID		0xA548 /* SeaGauge USB Adapter */ +#define CHETCO_SEASWITCH_PID		0xA549 /* SeaSwitch USB Adapter */ +#define CHETCO_SEASMART_NMEA2000_PID	0xA54A /* SeaSmart NMEA2000 Gateway */ +#define CHETCO_SEASMART_ETHERNET_PID	0xA54B /* SeaSmart Ethernet Gateway */ +#define CHETCO_SEASMART_WIFI_PID	0xA5AC /* SeaSmart Wifi Gateway */ +#define CHETCO_SEASMART_DISPLAY_PID	0xA5AD /* SeaSmart NMEA2000 Display */ +#define CHETCO_SEASMART_LITE_PID	0xA5AE /* SeaSmart Lite USB Adapter */ +#define CHETCO_SEASMART_ANALOG_PID	0xA5AF /* SeaSmart Analog Adapter */ diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c index ab1d690274ae..460a40669967 100644 --- a/drivers/usb/serial/mxuport.c +++ b/drivers/usb/serial/mxuport.c @@ -1284,7 +1284,8 @@ static int mxuport_open(struct tty_struct *tty, struct usb_serial_port *port)  	}  	/* Initial port termios */ -	mxuport_set_termios(tty, port, NULL); +	if (tty) +		mxuport_set_termios(tty, port, NULL);  	/*  	 * TODO: use RQ_VENDOR_GET_MSR, once we know what it diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 0f872e6b2c87..829604d11f3f 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -132,6 +132,7 @@ MODULE_DEVICE_TABLE(usb, id_table);  #define UART_OVERRUN_ERROR		0x40  #define UART_CTS			0x80 +static void pl2303_set_break(struct usb_serial_port *port, bool enable);  enum pl2303_type {  	TYPE_01,	/* Type 0 and 1 (difference unknown) */ @@ -615,6 +616,7 @@ static void pl2303_close(struct usb_serial_port *port)  {  	usb_serial_generic_close(port);  	usb_kill_urb(port->interrupt_in_urb); +	pl2303_set_break(port, false);  }  static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) @@ -741,17 +743,16 @@ static int pl2303_ioctl(struct tty_struct *tty,  	return -ENOIOCTLCMD;  } -static void pl2303_break_ctl(struct tty_struct *tty, int break_state) +static void pl2303_set_break(struct usb_serial_port *port, bool enable)  { -	struct usb_serial_port *port = tty->driver_data;  	struct usb_serial *serial = port->serial;  	u16 state;  	int result; -	if (break_state == 0) -		state = BREAK_OFF; -	else +	if (enable)  		state = BREAK_ON; +	else +		state = BREAK_OFF;  	dev_dbg(&port->dev, "%s - turning break %s\n", __func__,  			state == BREAK_OFF ? "off" : "on"); @@ -763,6 +764,13 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state)  		dev_err(&port->dev, "error sending break = %d\n", result);  } +static void pl2303_break_ctl(struct tty_struct *tty, int state) +{ +	struct usb_serial_port *port = tty->driver_data; + +	pl2303_set_break(port, state); +} +  static void pl2303_update_line_status(struct usb_serial_port *port,  				      unsigned char *data,  				      unsigned int actual_length) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 475723c006f9..529066bbc7e8 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -687,6 +687,21 @@ static void serial_port_dtr_rts(struct tty_port *port, int on)  		drv->dtr_rts(p, on);  } +static ssize_t port_number_show(struct device *dev, +				struct device_attribute *attr, char *buf) +{ +	struct usb_serial_port *port = to_usb_serial_port(dev); + +	return sprintf(buf, "%u\n", port->port_number); +} +static DEVICE_ATTR_RO(port_number); + +static struct attribute *usb_serial_port_attrs[] = { +	&dev_attr_port_number.attr, +	NULL +}; +ATTRIBUTE_GROUPS(usb_serial_port); +  static const struct tty_port_operations serial_port_ops = {  	.carrier_raised		= serial_port_carrier_raised,  	.dtr_rts		= serial_port_dtr_rts, @@ -902,6 +917,7 @@ static int usb_serial_probe(struct usb_interface *interface,  		port->dev.driver = NULL;  		port->dev.bus = &usb_serial_bus_type;  		port->dev.release = &usb_serial_port_release; +		port->dev.groups = usb_serial_port_groups;  		device_initialize(&port->dev);  	} @@ -940,8 +956,9 @@ static int usb_serial_probe(struct usb_interface *interface,  		port = serial->port[i];  		if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL))  			goto probe_error; -		buffer_size = max_t(int, serial->type->bulk_out_size, -						usb_endpoint_maxp(endpoint)); +		buffer_size = serial->type->bulk_out_size; +		if (!buffer_size) +			buffer_size = usb_endpoint_maxp(endpoint);  		port->bulk_out_size = buffer_size;  		port->bulk_out_endpointAddress = endpoint->bEndpointAddress; diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index dbc00e56c7f5..82570425fdfe 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -113,6 +113,13 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999,  		USB_SC_DEVICE, USB_PR_DEVICE, NULL,  		US_FL_NO_ATA_1X), +/* Reported-by: Tom Arild Naess <tanaess@gmail.com> */ +UNUSUAL_DEV(0x152d, 0x0539, 0x0000, 0x9999, +		"JMicron", +		"JMS539", +		USB_SC_DEVICE, USB_PR_DEVICE, NULL, +		US_FL_NO_REPORT_OPCODES), +  /* Reported-by: Claudio Bizzarri <claudio.bizzarri@gmail.com> */  UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999,  		"JMicron", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index d468d02179f4..5600c33fcadb 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -889,6 +889,12 @@ static void usb_stor_scan_dwork(struct work_struct *work)  	    !(us->fflags & US_FL_SCM_MULT_TARG)) {  		mutex_lock(&us->dev_mutex);  		us->max_lun = usb_stor_Bulk_max_lun(us); +		/* +		 * Allow proper scanning of devices that present more than 8 LUNs +		 * While not affecting other devices that may need the previous behavior +		 */ +		if (us->max_lun >= 8) +			us_to_host(us)->max_lun = us->max_lun+1;  		mutex_unlock(&us->dev_mutex);  	}  	scsi_scan_host(us_to_host(us));  | 
