Commit 1163d504 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull USB fixes from Greg KH:
 "Here's a round of USB fixes for 4.0-rc3.

  Nothing major, the usual gadget, xhci and usb-serial fixes and a few
  new device ids as well.

  All have been in linux-next successfully"

* tag 'usb-4.0-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (36 commits)
  xhci: Workaround for PME stuck issues in Intel xhci
  xhci: fix reporting of 0-sized URBs in control endpoint
  usb: ftdi_sio: Add jtag quirk support for Cyber Cortex AV boards
  USB: ch341: set tty baud speed according to tty struct
  USB: serial: cp210x: Adding Seletek device id's
  USB: pl2303: disable break on shutdown
  USB: mxuport: fix null deref when used as a console
  USB: serial: clean up bus probe error handling
  USB: serial: fix port attribute-creation race
  USB: serial: fix tty-device error handling at probe
  USB: serial: fix potential use-after-free after failed probe
  USB: console: add dummy __module_get
  USB: ftdi_sio: add PIDs for Actisense USB devices
  Revert "USB: serial: make bulk_out_size a lower limit"
  cdc-acm: Add support for Denso cradle CU-321
  usb-storage: support for more than 8 LUNs
  uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS539
  USB: usbfs: don't leak kernel data in siginfo
  xhci: Clear the host side toggle manually when endpoint is 'soft reset'
  xhci: Allocate correct amount of scratchpad buffers
  ...
parents bbbce516 b8cb91e0
...@@ -1650,6 +1650,8 @@ static int acm_reset_resume(struct usb_interface *intf) ...@@ -1650,6 +1650,8 @@ static int acm_reset_resume(struct usb_interface *intf)
static const struct usb_device_id acm_ids[] = { static const struct usb_device_id acm_ids[] = {
/* quirky and broken devices */ /* 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 */ { USB_DEVICE(0x17ef, 0x7000), /* Lenovo USB modem */
.driver_info = NO_UNION_NORMAL, },/* has no union descriptor */ .driver_info = NO_UNION_NORMAL, },/* has no union descriptor */
{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
......
...@@ -501,6 +501,7 @@ static void async_completed(struct urb *urb) ...@@ -501,6 +501,7 @@ static void async_completed(struct urb *urb)
as->status = urb->status; as->status = urb->status;
signr = as->signr; signr = as->signr;
if (signr) { if (signr) {
memset(&sinfo, 0, sizeof(sinfo));
sinfo.si_signo = as->signr; sinfo.si_signo = as->signr;
sinfo.si_errno = as->status; sinfo.si_errno = as->status;
sinfo.si_code = SI_ASYNCIO; sinfo.si_code = SI_ASYNCIO;
...@@ -2382,6 +2383,7 @@ static void usbdev_remove(struct usb_device *udev) ...@@ -2382,6 +2383,7 @@ static void usbdev_remove(struct usb_device *udev)
wake_up_all(&ps->wait); wake_up_all(&ps->wait);
list_del_init(&ps->list); list_del_init(&ps->list);
if (ps->discsignr) { if (ps->discsignr) {
memset(&sinfo, 0, sizeof(sinfo));
sinfo.si_signo = ps->discsignr; sinfo.si_signo = ps->discsignr;
sinfo.si_errno = EPIPE; sinfo.si_errno = EPIPE;
sinfo.si_code = SI_ASYNCIO; sinfo.si_code = SI_ASYNCIO;
......
...@@ -205,6 +205,18 @@ static void dwc3_omap_write_irq0_set(struct dwc3_omap *omap, u32 value) ...@@ -205,6 +205,18 @@ static void dwc3_omap_write_irq0_set(struct dwc3_omap *omap, u32 value)
omap->irq0_offset, 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, static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
enum omap_dwc3_vbus_id_status status) enum omap_dwc3_vbus_id_status status)
{ {
...@@ -345,9 +357,23 @@ static void dwc3_omap_enable_irqs(struct dwc3_omap *omap) ...@@ -345,9 +357,23 @@ static void dwc3_omap_enable_irqs(struct dwc3_omap *omap)
static void dwc3_omap_disable_irqs(struct dwc3_omap *omap) static void dwc3_omap_disable_irqs(struct dwc3_omap *omap)
{ {
u32 reg;
/* disable all IRQs */ /* disable all IRQs */
dwc3_omap_write_irqmisc_set(omap, 0x00); reg = USBOTGSS_IRQO_COREIRQ_ST;
dwc3_omap_write_irq0_set(omap, 0x00); 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); static u64 dwc3_omap_dma_mask = DMA_BIT_MASK(32);
......
...@@ -1161,7 +1161,6 @@ static ssize_t interf_grp_compatible_id_store(struct usb_os_desc *desc, ...@@ -1161,7 +1161,6 @@ static ssize_t interf_grp_compatible_id_store(struct usb_os_desc *desc,
if (desc->opts_mutex) if (desc->opts_mutex)
mutex_lock(desc->opts_mutex); mutex_lock(desc->opts_mutex);
memcpy(desc->ext_compat_id, page, l); memcpy(desc->ext_compat_id, page, l);
desc->ext_compat_id[l] = '\0';
if (desc->opts_mutex) if (desc->opts_mutex)
mutex_unlock(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, ...@@ -1192,7 +1191,6 @@ static ssize_t interf_grp_sub_compatible_id_store(struct usb_os_desc *desc,
if (desc->opts_mutex) if (desc->opts_mutex)
mutex_lock(desc->opts_mutex); mutex_lock(desc->opts_mutex);
memcpy(desc->ext_compat_id + 8, page, l); memcpy(desc->ext_compat_id + 8, page, l);
desc->ext_compat_id[l + 8] = '\0';
if (desc->opts_mutex) if (desc->opts_mutex)
mutex_unlock(desc->opts_mutex); mutex_unlock(desc->opts_mutex);
......
...@@ -569,7 +569,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) ...@@ -569,7 +569,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
return status; return status;
} }
const struct file_operations f_hidg_fops = { static const struct file_operations f_hidg_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = f_hidg_open, .open = f_hidg_open,
.release = f_hidg_release, .release = f_hidg_release,
......
...@@ -417,7 +417,10 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) ...@@ -417,7 +417,10 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
return -EINVAL; return -EINVAL;
spin_lock(&port->lock); spin_lock(&port->lock);
__pn_reset(f);
if (fp->in_ep->driver_data)
__pn_reset(f);
if (alt == 1) { if (alt == 1) {
int i; int i;
......
...@@ -344,7 +344,7 @@ static struct usb_endpoint_descriptor ss_int_source_desc = { ...@@ -344,7 +344,7 @@ static struct usb_endpoint_descriptor ss_int_source_desc = {
.bInterval = USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL), .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, .bLength = USB_DT_SS_EP_COMP_SIZE,
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP, .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
...@@ -362,7 +362,7 @@ static struct usb_endpoint_descriptor ss_int_sink_desc = { ...@@ -362,7 +362,7 @@ static struct usb_endpoint_descriptor ss_int_sink_desc = {
.bInterval = USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL), .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, .bLength = USB_DT_SS_EP_COMP_SIZE,
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP, .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
#define UNFLW_CTRL 8 #define UNFLW_CTRL 8
#define OVFLW_CTRL 10 #define OVFLW_CTRL 10
const char *uac2_name = "snd_uac2"; static const char *uac2_name = "snd_uac2";
struct uac2_req { struct uac2_req {
struct uac2_rtd_params *pp; /* parent param */ struct uac2_rtd_params *pp; /* parent param */
...@@ -634,7 +634,7 @@ static struct usb_interface_descriptor std_ac_if_desc = { ...@@ -634,7 +634,7 @@ static struct usb_interface_descriptor std_ac_if_desc = {
}; };
/* Clock source for IN traffic */ /* 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, .bLength = sizeof in_clk_src_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
...@@ -646,7 +646,7 @@ struct uac_clock_source_descriptor in_clk_src_desc = { ...@@ -646,7 +646,7 @@ struct uac_clock_source_descriptor in_clk_src_desc = {
}; };
/* Clock source for OUT traffic */ /* 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, .bLength = sizeof out_clk_src_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
...@@ -658,7 +658,7 @@ struct uac_clock_source_descriptor out_clk_src_desc = { ...@@ -658,7 +658,7 @@ struct uac_clock_source_descriptor out_clk_src_desc = {
}; };
/* Input Terminal for USB_OUT */ /* 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, .bLength = sizeof usb_out_it_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
...@@ -672,7 +672,7 @@ struct uac2_input_terminal_descriptor usb_out_it_desc = { ...@@ -672,7 +672,7 @@ struct uac2_input_terminal_descriptor usb_out_it_desc = {
}; };
/* Input Terminal for I/O-In */ /* 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, .bLength = sizeof io_in_it_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
...@@ -686,7 +686,7 @@ struct uac2_input_terminal_descriptor io_in_it_desc = { ...@@ -686,7 +686,7 @@ struct uac2_input_terminal_descriptor io_in_it_desc = {
}; };
/* Ouput Terminal for USB_IN */ /* 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, .bLength = sizeof usb_in_ot_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
...@@ -700,7 +700,7 @@ struct uac2_output_terminal_descriptor usb_in_ot_desc = { ...@@ -700,7 +700,7 @@ struct uac2_output_terminal_descriptor usb_in_ot_desc = {
}; };
/* Ouput Terminal for I/O-Out */ /* 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, .bLength = sizeof io_out_ot_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
...@@ -713,7 +713,7 @@ struct uac2_output_terminal_descriptor io_out_ot_desc = { ...@@ -713,7 +713,7 @@ struct uac2_output_terminal_descriptor io_out_ot_desc = {
.bmControls = (CONTROL_RDWR << COPY_CTRL), .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, .bLength = sizeof ac_hdr_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
...@@ -751,7 +751,7 @@ static struct usb_interface_descriptor std_as_out_if1_desc = { ...@@ -751,7 +751,7 @@ static struct usb_interface_descriptor std_as_out_if1_desc = {
}; };
/* Audio Stream OUT Intface 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, .bLength = sizeof as_out_hdr_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
...@@ -764,7 +764,7 @@ struct uac2_as_header_descriptor as_out_hdr_desc = { ...@@ -764,7 +764,7 @@ struct uac2_as_header_descriptor as_out_hdr_desc = {
}; };
/* Audio USB_OUT Format */ /* 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, .bLength = sizeof as_out_fmt1_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_FORMAT_TYPE, .bDescriptorSubtype = UAC_FORMAT_TYPE,
...@@ -772,7 +772,7 @@ struct uac2_format_type_i_descriptor as_out_fmt1_desc = { ...@@ -772,7 +772,7 @@ struct uac2_format_type_i_descriptor as_out_fmt1_desc = {
}; };
/* STD AS ISO OUT Endpoint */ /* 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, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
...@@ -782,7 +782,7 @@ struct usb_endpoint_descriptor fs_epout_desc = { ...@@ -782,7 +782,7 @@ struct usb_endpoint_descriptor fs_epout_desc = {
.bInterval = 1, .bInterval = 1,
}; };
struct usb_endpoint_descriptor hs_epout_desc = { static struct usb_endpoint_descriptor hs_epout_desc = {
.bLength = USB_DT_ENDPOINT_SIZE, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
...@@ -828,7 +828,7 @@ static struct usb_interface_descriptor std_as_in_if1_desc = { ...@@ -828,7 +828,7 @@ static struct usb_interface_descriptor std_as_in_if1_desc = {
}; };
/* Audio Stream IN Intface 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, .bLength = sizeof as_in_hdr_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
...@@ -841,7 +841,7 @@ struct uac2_as_header_descriptor as_in_hdr_desc = { ...@@ -841,7 +841,7 @@ struct uac2_as_header_descriptor as_in_hdr_desc = {
}; };
/* Audio USB_IN Format */ /* 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, .bLength = sizeof as_in_fmt1_desc,
.bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_FORMAT_TYPE, .bDescriptorSubtype = UAC_FORMAT_TYPE,
...@@ -849,7 +849,7 @@ struct uac2_format_type_i_descriptor as_in_fmt1_desc = { ...@@ -849,7 +849,7 @@ struct uac2_format_type_i_descriptor as_in_fmt1_desc = {
}; };
/* STD AS ISO IN Endpoint */ /* 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, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
...@@ -859,7 +859,7 @@ struct usb_endpoint_descriptor fs_epin_desc = { ...@@ -859,7 +859,7 @@ struct usb_endpoint_descriptor fs_epin_desc = {
.bInterval = 1, .bInterval = 1,
}; };
struct usb_endpoint_descriptor hs_epin_desc = { static struct usb_endpoint_descriptor hs_epin_desc = {
.bLength = USB_DT_ENDPOINT_SIZE, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
...@@ -1563,7 +1563,7 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f) ...@@ -1563,7 +1563,7 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f)
agdev->out_ep->driver_data = NULL; 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 audio_dev *agdev;
struct f_uac2_opts *opts; struct f_uac2_opts *opts;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "uvc.h" #include "uvc.h"
#include "uvc_queue.h" #include "uvc_queue.h"
#include "uvc_video.h" #include "uvc_video.h"
#include "uvc_v4l2.h"
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* Requests handling * Requests handling
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "uvc.h" #include "uvc.h"
#include "uvc_queue.h" #include "uvc_queue.h"
#include "uvc_video.h"
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* Video codecs * Video codecs
......
...@@ -133,7 +133,9 @@ struct gfs_configuration { ...@@ -133,7 +133,9 @@ struct gfs_configuration {
struct usb_configuration c; struct usb_configuration c;
int (*eth)(struct usb_configuration *c); int (*eth)(struct usb_configuration *c);
int num; int num;
} gfs_configurations[] = { };
static struct gfs_configuration gfs_configurations[] = {
#ifdef CONFIG_USB_FUNCTIONFS_RNDIS #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
{ {
.eth = bind_rndis_config, .eth = bind_rndis_config,
...@@ -278,7 +280,7 @@ static void *functionfs_acquire_dev(struct ffs_dev *dev) ...@@ -278,7 +280,7 @@ static void *functionfs_acquire_dev(struct ffs_dev *dev)
if (!try_module_get(THIS_MODULE)) if (!try_module_get(THIS_MODULE))
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
return 0; return NULL;
} }
static void functionfs_release_dev(struct ffs_dev *dev) static void functionfs_release_dev(struct ffs_dev *dev)
......
...@@ -37,6 +37,9 @@ ...@@ -37,6 +37,9 @@
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 #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"; static const char hcd_name[] = "xhci_hcd";
...@@ -133,6 +136,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) ...@@ -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) { pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
xhci->quirks |= XHCI_SPURIOUS_REBOOT; 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 && if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
pdev->device == PCI_DEVICE_ID_EJ168) { pdev->device == PCI_DEVICE_ID_EJ168) {
xhci->quirks |= XHCI_RESET_ON_RESUME; xhci->quirks |= XHCI_RESET_ON_RESUME;
...@@ -159,6 +168,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) ...@@ -159,6 +168,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
"QUIRK: Resetting on resume"); "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 */ /* called during probe() after chip reset completes */
static int xhci_pci_setup(struct usb_hcd *hcd) 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) ...@@ -283,6 +307,9 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
if (xhci->quirks & XHCI_COMP_MODE_QUIRK) if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
pdev->no_d3cold = true; pdev->no_d3cold = true;
if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
xhci_pme_quirk(xhci);
return xhci_suspend(xhci, do_wakeup); return xhci_suspend(xhci, do_wakeup);
} }
...@@ -313,6 +340,9 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) ...@@ -313,6 +340,9 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
if (pdev->vendor == PCI_VENDOR_ID_INTEL) if (pdev->vendor == PCI_VENDOR_ID_INTEL)
usb_enable_intel_xhci_ports(pdev); usb_enable_intel_xhci_ports(pdev);
if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
xhci_pme_quirk(xhci);
retval = xhci_resume(xhci, hibernated); retval = xhci_resume(xhci, hibernated);
return retval; return retval;
} }
......
...@@ -83,16 +83,6 @@ static int xhci_plat_probe(struct platform_device *pdev) ...@@ -83,16 +83,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (irq < 0) if (irq < 0)
return -ENODEV; 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 */ /* Initialize dma_mask and coherent_dma_mask to 32-bits */
ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (ret) if (ret)
...@@ -127,6 +117,15 @@ static int xhci_plat_probe(struct platform_device *pdev) ...@@ -127,6 +117,15 @@ static int xhci_plat_probe(struct platform_device *pdev)
goto put_hcd; 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); ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (ret) if (ret)
goto disable_clk; goto disable_clk;
......
...@@ -1729,7 +1729,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, ...@@ -1729,7 +1729,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
if (!command) if (!command)
return; return;
ep->ep_state |= EP_HALTED; ep->ep_state |= EP_HALTED | EP_RECENTLY_HALTED;
ep->stopped_stream = stream_id; ep->stopped_stream = stream_id;
xhci_queue_reset_ep(xhci, command, slot_id, ep_index); 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, ...@@ -1946,7 +1946,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
if (event_trb != ep_ring->dequeue) { if (event_trb != ep_ring->dequeue) {
/* The event was for the status stage */ /* The event was for the status stage */
if (event_trb == td->last_trb) { 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 /* Don't overwrite a previously set error code
*/ */
if ((*status == -EINPROGRESS || *status == 0) && if ((*status == -EINPROGRESS || *status == 0) &&
...@@ -1960,7 +1960,13 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, ...@@ -1960,7 +1960,13 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
td->urb->transfer_buffer_length; td->urb->transfer_buffer_length;
} }
} else { } 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->actual_length =
td->urb->transfer_buffer_length - td->urb->transfer_buffer_length -
EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
......
...@@ -1338,6 +1338,12 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -1338,6 +1338,12 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
goto exit; 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)) if (usb_endpoint_xfer_isoc(&urb->ep->desc))
size = urb->number_of_packets; size = urb->number_of_packets;
else else
...@@ -2948,23 +2954,36 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, ...@@ -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 * 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 * already be cleared with a reset endpoint command issued immediately when the
* event was received. * STALL tx event was received.
*
* Context: in_interrupt
*/ */
void xhci_endpoint_reset(struct usb_hcd *hcd, void xhci_endpoint_reset(struct usb_hcd *hcd,
struct usb_host_endpoint *ep) struct usb_host_endpoint *ep)
{ {
struct xhci_hcd *xhci; 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); 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 * The Reset Endpoint Command may only be issued to endpoints in the
* Halted state. If software wishes reset the Data Toggle or Sequence * Halted state. If software wishes reset the Data Toggle or Sequence
* Number of an endpoint that isn't in the Halted state, then software * 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, ...@@ -2972,9 +2991,72 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
* for the target endpoint. that is in the Stopped state. * for the target endpoint. that is in the Stopped state.
*/ */
/* For now just print debug to follow the situation */ if (ep_state & SET_DEQ_PENDING || ep_state & EP_RECENTLY_HALTED) {
xhci_dbg(xhci, "Endpoint 0x%x ep reset callback called\n", virt_ep->ep_state &= ~EP_RECENTLY_HALTED;
ep->desc.bEndpointAddress); 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, static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,
......
/* /*
* xHCI host controller driver * xHCI host controller driver
* *
...@@ -88,9 +89,10 @@ struct xhci_cap_regs { ...@@ -88,9 +89,10 @@ struct xhci_cap_regs {
#define HCS_IST(p) (((p) >> 0) & 0xf) #define HCS_IST(p) (((p) >> 0) & 0xf)
/* bits 4:7, max number of Event Ring segments */ /* bits 4:7, max number of Event Ring segments */
#define HCS_ERST_MAX(p) (((p) >> 4) & 0xf) #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 */ /* 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 */ /* bits 27:31 Lo 5 bits of Scratchpad buffers SW must allocate for the HW */
#define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f) #define HCS_MAX_SCRATCHPAD(p) ((((p) >> 16) & 0x3e0) | (((p) >> 27) & 0x1f))
/* HCSPARAMS3 - hcs_params3 - bitmasks */ /* HCSPARAMS3 - hcs_params3 - bitmasks */
/* bits 0:7, Max U1 to U0 latency for the roothub ports */ /* bits 0:7, Max U1 to U0 latency for the roothub ports */
...@@ -863,6 +865,8 @@ struct xhci_virt_ep { ...@@ -863,6 +865,8 @@ struct xhci_virt_ep {
#define EP_HAS_STREAMS (1 << 4) #define EP_HAS_STREAMS (1 << 4)
/* Transitioning the endpoint to not using streams, don't enqueue URBs */ /* Transitioning the endpoint to not using streams, don't enqueue URBs */
#define EP_GETTING_NO_STREAMS (1 << 5) #define EP_GETTING_NO_STREAMS (1 << 5)
#define EP_RECENTLY_HALTED (1 << 6)
#define EP_CONFIG_PENDING (1 << 7)
/* ---- Related to URB cancellation ---- */ /* ---- Related to URB cancellation ---- */
struct list_head cancelled_td_list; struct list_head cancelled_td_list;
struct xhci_td *stopped_td; struct xhci_td *stopped_td;
...@@ -1288,6 +1292,8 @@ struct xhci_td { ...@@ -1288,6 +1292,8 @@ struct xhci_td {
struct xhci_segment *start_seg; struct xhci_segment *start_seg;
union xhci_trb *first_trb; union xhci_trb *first_trb;
union xhci_trb *last_trb; union xhci_trb *last_trb;
/* actual_length of the URB has already been set */
bool urb_length_set;
}; };
/* xHCI command default timeout value */ /* xHCI command default timeout value */
...@@ -1560,6 +1566,7 @@ struct xhci_hcd { ...@@ -1560,6 +1566,7 @@ struct xhci_hcd {
#define XHCI_SPURIOUS_WAKEUP (1 << 18) #define XHCI_SPURIOUS_WAKEUP (1 << 18)
/* For controllers with a broken beyond repair streams implementation */ /* For controllers with a broken beyond repair streams implementation */
#define XHCI_BROKEN_STREAMS (1 << 19) #define XHCI_BROKEN_STREAMS (1 << 19)
#define XHCI_PME_STUCK_QUIRK (1 << 20)
unsigned int num_active_eps; unsigned int num_active_eps;
unsigned int limit_active_eps; unsigned int limit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */ /* There are two roothubs to keep track of bus suspend info for */
......
...@@ -1274,7 +1274,7 @@ static void errata2_function(unsigned long data) ...@@ -1274,7 +1274,7 @@ static void errata2_function(unsigned long data)
for (slot = 0; slot < 32; slot++) for (slot = 0; slot < 32; slot++)
if (priv->atl_slots[slot].qh && time_after(jiffies, if (priv->atl_slots[slot].qh && time_after(jiffies,
priv->atl_slots[slot].timestamp + priv->atl_slots[slot].timestamp +
SLOT_TIMEOUT * HZ / 1000)) { msecs_to_jiffies(SLOT_TIMEOUT))) {
ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd);
if (!FROM_DW0_VALID(ptd.dw0) && if (!FROM_DW0_VALID(ptd.dw0) &&
!FROM_DW3_ACTIVE(ptd.dw3)) !FROM_DW3_ACTIVE(ptd.dw3))
...@@ -1286,7 +1286,7 @@ static void errata2_function(unsigned long data) ...@@ -1286,7 +1286,7 @@ static void errata2_function(unsigned long data)
spin_unlock_irqrestore(&priv->lock, spinflags); 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); add_timer(&errata2_timer);
} }
...@@ -1336,7 +1336,7 @@ static int isp1760_run(struct usb_hcd *hcd) ...@@ -1336,7 +1336,7 @@ static int isp1760_run(struct usb_hcd *hcd)
return retval; return retval;
setup_timer(&errata2_timer, errata2_function, (unsigned long)hcd); 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); add_timer(&errata2_timer);
chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG); chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG);
......
...@@ -1969,10 +1969,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -1969,10 +1969,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
goto fail0; 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); spin_lock_init(&musb->lock);
musb->board_set_power = plat->set_power; musb->board_set_power = plat->set_power;
musb->min_power = plat->min_power; musb->min_power = plat->min_power;
...@@ -1991,6 +1987,12 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -1991,6 +1987,12 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
musb_readl = musb_default_readl; musb_readl = musb_default_readl;
musb_writel = musb_default_writel; 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: /* The musb_platform_init() call:
* - adjusts musb->mregs * - adjusts musb->mregs
* - sets the musb->isr * - sets the musb->isr
......
...@@ -457,12 +457,27 @@ static int dsps_musb_init(struct musb *musb) ...@@ -457,12 +457,27 @@ static int dsps_musb_init(struct musb *musb)
if (IS_ERR(musb->xceiv)) if (IS_ERR(musb->xceiv))
return PTR_ERR(musb->xceiv); return PTR_ERR(musb->xceiv);
musb->phy = devm_phy_get(dev->parent, "usb2-phy");
/* Returns zero if e.g. not clocked */ /* Returns zero if e.g. not clocked */
rev = dsps_readl(reg_base, wrp->revision); rev = dsps_readl(reg_base, wrp->revision);
if (!rev) if (!rev)
return -ENODEV; return -ENODEV;
usb_phy_init(musb->xceiv); 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); setup_timer(&glue->timer, otg_timer, (unsigned long) musb);
/* Reset the musb */ /* Reset the musb */
...@@ -502,6 +517,8 @@ static int dsps_musb_exit(struct musb *musb) ...@@ -502,6 +517,8 @@ static int dsps_musb_exit(struct musb *musb)
del_timer_sync(&glue->timer); del_timer_sync(&glue->timer);
usb_phy_shutdown(musb->xceiv); usb_phy_shutdown(musb->xceiv);
phy_power_off(musb->phy);
phy_exit(musb->phy);
debugfs_remove_recursive(glue->dbgfs_root); debugfs_remove_recursive(glue->dbgfs_root);
return 0; return 0;
...@@ -610,7 +627,7 @@ static int dsps_musb_reset(struct musb *musb) ...@@ -610,7 +627,7 @@ static int dsps_musb_reset(struct musb *musb)
struct device *dev = musb->controller; struct device *dev = musb->controller;
struct dsps_glue *glue = dev_get_drvdata(dev->parent); struct dsps_glue *glue = dev_get_drvdata(dev->parent);
const struct dsps_musb_wrapper *wrp = glue->wrp; const struct dsps_musb_wrapper *wrp = glue->wrp;
int session_restart = 0; int session_restart = 0, error;
if (glue->sw_babble_enabled) if (glue->sw_babble_enabled)
session_restart = sw_babble_control(musb); session_restart = sw_babble_control(musb);
...@@ -624,8 +641,14 @@ static int dsps_musb_reset(struct musb *musb) ...@@ -624,8 +641,14 @@ static int dsps_musb_reset(struct musb *musb)
dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset));
usleep_range(100, 200); usleep_range(100, 200);
usb_phy_shutdown(musb->xceiv); 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); usleep_range(100, 200);
usb_phy_init(musb->xceiv); 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; session_restart = 1;
} }
...@@ -687,7 +710,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, ...@@ -687,7 +710,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
struct musb_hdrc_config *config; struct musb_hdrc_config *config;
struct platform_device *musb; struct platform_device *musb;
struct device_node *dn = parent->dev.of_node; struct device_node *dn = parent->dev.of_node;
int ret; int ret, val;
memset(resources, 0, sizeof(resources)); memset(resources, 0, sizeof(resources));
res = platform_get_resource_byname(parent, IORESOURCE_MEM, "mc"); res = platform_get_resource_byname(parent, IORESOURCE_MEM, "mc");
...@@ -739,7 +762,10 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, ...@@ -739,7 +762,10 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
pdata.mode = get_musb_port_mode(dev); pdata.mode = get_musb_port_mode(dev);
/* DT keeps this entry in mA, musb expects it as per USB spec */ /* DT keeps this entry in mA, musb expects it as per USB spec */
pdata.power = get_int_prop(dn, "mentor,power") / 2; 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)); ret = platform_device_add_data(musb, &pdata, sizeof(pdata));
if (ret) { if (ret) {
......
...@@ -2613,7 +2613,7 @@ static const struct hc_driver musb_hc_driver = { ...@@ -2613,7 +2613,7 @@ static const struct hc_driver musb_hc_driver = {
.description = "musb-hcd", .description = "musb-hcd",
.product_desc = "MUSB HDRC host driver", .product_desc = "MUSB HDRC host driver",
.hcd_priv_size = sizeof(struct musb *), .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 /* not using irq handler or reset hooks from usbcore, since
* those must be shared with peripheral code for OTG configs * those must be shared with peripheral code for OTG configs
......
...@@ -516,7 +516,7 @@ static int omap2430_probe(struct platform_device *pdev) ...@@ -516,7 +516,7 @@ static int omap2430_probe(struct platform_device *pdev)
struct omap2430_glue *glue; struct omap2430_glue *glue;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct musb_hdrc_config *config; struct musb_hdrc_config *config;
int ret = -ENOMEM; int ret = -ENOMEM, val;
glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
if (!glue) if (!glue)
...@@ -559,7 +559,10 @@ static int omap2430_probe(struct platform_device *pdev) ...@@ -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, "num-eps", (u32 *)&config->num_eps);
of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits); of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
of_property_read_u32(np, "power", (u32 *)&pdata->power); 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->board_data = data;
pdata->config = config; pdata->config = config;
......
...@@ -6,6 +6,7 @@ config USB_RENESAS_USBHS ...@@ -6,6 +6,7 @@ config USB_RENESAS_USBHS
tristate 'Renesas USBHS controller' tristate 'Renesas USBHS controller'
depends on USB_GADGET depends on USB_GADGET
depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST
depends on EXTCON || !EXTCON # if EXTCON=m, USBHS cannot be built-in
default n default n
help help
Renesas USBHS is a discrete USB host and peripheral controller chip Renesas USBHS is a discrete USB host and peripheral controller chip
......
...@@ -38,56 +38,51 @@ static int usb_serial_device_match(struct device *dev, ...@@ -38,56 +38,51 @@ static int usb_serial_device_match(struct device *dev,
return 0; 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) static int usb_serial_device_probe(struct device *dev)
{ {
struct usb_serial_driver *driver; struct usb_serial_driver *driver;
struct usb_serial_port *port; struct usb_serial_port *port;
struct device *tty_dev;
int retval = 0; int retval = 0;
int minor; int minor;
port = to_usb_serial_port(dev); port = to_usb_serial_port(dev);
if (!port) { if (!port)
retval = -ENODEV; return -ENODEV;
goto exit;
}
/* make sure suspend/resume doesn't race against port_probe */ /* make sure suspend/resume doesn't race against port_probe */
retval = usb_autopm_get_interface(port->serial->interface); retval = usb_autopm_get_interface(port->serial->interface);
if (retval) if (retval)
goto exit; return retval;
driver = port->serial->type; driver = port->serial->type;
if (driver->port_probe) { if (driver->port_probe) {
retval = driver->port_probe(port); retval = driver->port_probe(port);
if (retval) if (retval)
goto exit_with_autopm; goto err_autopm_put;
} }
retval = device_create_file(dev, &dev_attr_port_number); minor = port->minor;
if (retval) { tty_dev = tty_register_device(usb_serial_tty_driver, minor, dev);
if (driver->port_remove) if (IS_ERR(tty_dev)) {
retval = driver->port_remove(port); retval = PTR_ERR(tty_dev);
goto exit_with_autopm; goto err_port_remove;
} }
minor = port->minor; usb_autopm_put_interface(port->serial->interface);
tty_register_device(usb_serial_tty_driver, minor, dev);
dev_info(&port->serial->dev->dev, dev_info(&port->serial->dev->dev,
"%s converter now attached to ttyUSB%d\n", "%s converter now attached to ttyUSB%d\n",
driver->description, minor); 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); usb_autopm_put_interface(port->serial->interface);
exit:
return retval; return retval;
} }
...@@ -114,8 +109,6 @@ static int usb_serial_device_remove(struct device *dev) ...@@ -114,8 +109,6 @@ static int usb_serial_device_remove(struct device *dev)
minor = port->minor; minor = port->minor;
tty_unregister_device(usb_serial_tty_driver, minor); tty_unregister_device(usb_serial_tty_driver, minor);
device_remove_file(&port->dev, &dev_attr_port_number);
driver = port->serial->type; driver = port->serial->type;
if (driver->port_remove) if (driver->port_remove)
retval = driver->port_remove(port); retval = driver->port_remove(port);
......
...@@ -84,6 +84,10 @@ struct ch341_private { ...@@ -84,6 +84,10 @@ struct ch341_private {
u8 line_status; /* active status of modem control inputs */ 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, static int ch341_control_out(struct usb_device *dev, u8 request,
u16 value, u16 index) u16 value, u16 index)
{ {
...@@ -309,19 +313,12 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -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); struct ch341_private *priv = usb_get_serial_port_data(port);
int r; int r;
priv->baud_rate = DEFAULT_BAUD_RATE;
r = ch341_configure(serial->dev, priv); r = ch341_configure(serial->dev, priv);
if (r) if (r)
goto out; goto out;
r = ch341_set_handshake(serial->dev, priv->line_control); if (tty)
if (r) ch341_set_termios(tty, port, NULL);
goto out;
r = ch341_set_baudrate(serial->dev, priv);
if (r)
goto out;
dev_dbg(&port->dev, "%s - submitting interrupt urb\n", __func__); dev_dbg(&port->dev, "%s - submitting interrupt urb\n", __func__);
r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/console.h> #include <linux/console.h>
...@@ -144,6 +145,7 @@ static int usb_console_setup(struct console *co, char *options) ...@@ -144,6 +145,7 @@ static int usb_console_setup(struct console *co, char *options)
init_ldsem(&tty->ldisc_sem); init_ldsem(&tty->ldisc_sem);
INIT_LIST_HEAD(&tty->tty_files); INIT_LIST_HEAD(&tty->tty_files);
kref_get(&tty->driver->kref); kref_get(&tty->driver->kref);
__module_get(tty->driver->owner);
tty->ops = &usb_console_fake_tty_ops; tty->ops = &usb_console_fake_tty_ops;
if (tty_init_termios(tty)) { if (tty_init_termios(tty)) {
retval = -ENOMEM; retval = -ENOMEM;
......
...@@ -147,6 +147,8 @@ static const struct usb_device_id id_table[] = { ...@@ -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, 0x0305) }, /* Clipsal C-5000CT2 C-Bus Spectrum Colour Touchscreen */
{ USB_DEVICE(0x166A, 0x0401) }, /* Clipsal L51xx C-Bus Architectural Dimmer */ { 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(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(0x16D6, 0x0001) }, /* Jablotron serial interface */
{ USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ { 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 */ { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */
......
...@@ -799,6 +799,8 @@ static const struct usb_device_id id_table_combined[] = { ...@@ -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_ELSTER_UNICOM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_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), { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID), { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID),
...@@ -978,6 +980,23 @@ static const struct usb_device_id id_table_combined[] = { ...@@ -978,6 +980,23 @@ static const struct usb_device_id id_table_combined[] = {
{ USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) }, { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) },
/* GE Healthcare devices */ /* GE Healthcare devices */
{ USB_DEVICE(GE_HEALTHCARE_VID, GE_HEALTHCARE_NEMO_TRACKER_PID) }, { 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 */ { } /* Terminating entry */
}; };
......
...@@ -38,6 +38,9 @@ ...@@ -38,6 +38,9 @@
#define FTDI_LUMEL_PD12_PID 0x6002 #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 * Marvell OpenRD Base, Client
* http://www.open-rd.org * http://www.open-rd.org
...@@ -1438,3 +1441,23 @@ ...@@ -1438,3 +1441,23 @@
*/ */
#define GE_HEALTHCARE_VID 0x1901 #define GE_HEALTHCARE_VID 0x1901
#define GE_HEALTHCARE_NEMO_TRACKER_PID 0x0015 #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 */
...@@ -1284,7 +1284,8 @@ static int mxuport_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -1284,7 +1284,8 @@ static int mxuport_open(struct tty_struct *tty, struct usb_serial_port *port)
} }
/* Initial port termios */ /* 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 * TODO: use RQ_VENDOR_GET_MSR, once we know what it
......
...@@ -132,6 +132,7 @@ MODULE_DEVICE_TABLE(usb, id_table); ...@@ -132,6 +132,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
#define UART_OVERRUN_ERROR 0x40 #define UART_OVERRUN_ERROR 0x40
#define UART_CTS 0x80 #define UART_CTS 0x80
static void pl2303_set_break(struct usb_serial_port *port, bool enable);
enum pl2303_type { enum pl2303_type {
TYPE_01, /* Type 0 and 1 (difference unknown) */ TYPE_01, /* Type 0 and 1 (difference unknown) */
...@@ -615,6 +616,7 @@ static void pl2303_close(struct usb_serial_port *port) ...@@ -615,6 +616,7 @@ static void pl2303_close(struct usb_serial_port *port)
{ {
usb_serial_generic_close(port); usb_serial_generic_close(port);
usb_kill_urb(port->interrupt_in_urb); 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) 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, ...@@ -741,17 +743,16 @@ static int pl2303_ioctl(struct tty_struct *tty,
return -ENOIOCTLCMD; 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; struct usb_serial *serial = port->serial;
u16 state; u16 state;
int result; int result;
if (break_state == 0) if (enable)
state = BREAK_OFF;
else
state = BREAK_ON; state = BREAK_ON;
else
state = BREAK_OFF;
dev_dbg(&port->dev, "%s - turning break %s\n", __func__, dev_dbg(&port->dev, "%s - turning break %s\n", __func__,
state == BREAK_OFF ? "off" : "on"); state == BREAK_OFF ? "off" : "on");
...@@ -763,6 +764,13 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state) ...@@ -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); 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, static void pl2303_update_line_status(struct usb_serial_port *port,
unsigned char *data, unsigned char *data,
unsigned int actual_length) unsigned int actual_length)
......
...@@ -687,6 +687,21 @@ static void serial_port_dtr_rts(struct tty_port *port, int on) ...@@ -687,6 +687,21 @@ static void serial_port_dtr_rts(struct tty_port *port, int on)
drv->dtr_rts(p, 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 = { static const struct tty_port_operations serial_port_ops = {
.carrier_raised = serial_port_carrier_raised, .carrier_raised = serial_port_carrier_raised,
.dtr_rts = serial_port_dtr_rts, .dtr_rts = serial_port_dtr_rts,
...@@ -902,6 +917,7 @@ static int usb_serial_probe(struct usb_interface *interface, ...@@ -902,6 +917,7 @@ static int usb_serial_probe(struct usb_interface *interface,
port->dev.driver = NULL; port->dev.driver = NULL;
port->dev.bus = &usb_serial_bus_type; port->dev.bus = &usb_serial_bus_type;
port->dev.release = &usb_serial_port_release; port->dev.release = &usb_serial_port_release;
port->dev.groups = usb_serial_port_groups;
device_initialize(&port->dev); device_initialize(&port->dev);
} }
...@@ -940,8 +956,9 @@ static int usb_serial_probe(struct usb_interface *interface, ...@@ -940,8 +956,9 @@ static int usb_serial_probe(struct usb_interface *interface,
port = serial->port[i]; port = serial->port[i];
if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL))
goto probe_error; goto probe_error;
buffer_size = max_t(int, serial->type->bulk_out_size, buffer_size = serial->type->bulk_out_size;
usb_endpoint_maxp(endpoint)); if (!buffer_size)
buffer_size = usb_endpoint_maxp(endpoint);
port->bulk_out_size = buffer_size; port->bulk_out_size = buffer_size;
port->bulk_out_endpointAddress = endpoint->bEndpointAddress; port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
......
...@@ -113,6 +113,13 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999, ...@@ -113,6 +113,13 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999,
USB_SC_DEVICE, USB_PR_DEVICE, NULL, USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_ATA_1X), 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> */ /* Reported-by: Claudio Bizzarri <claudio.bizzarri@gmail.com> */
UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999, UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999,
"JMicron", "JMicron",
......
...@@ -889,6 +889,12 @@ static void usb_stor_scan_dwork(struct work_struct *work) ...@@ -889,6 +889,12 @@ static void usb_stor_scan_dwork(struct work_struct *work)
!(us->fflags & US_FL_SCM_MULT_TARG)) { !(us->fflags & US_FL_SCM_MULT_TARG)) {
mutex_lock(&us->dev_mutex); mutex_lock(&us->dev_mutex);
us->max_lun = usb_stor_Bulk_max_lun(us); 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); mutex_unlock(&us->dev_mutex);
} }
scsi_scan_host(us_to_host(us)); scsi_scan_host(us_to_host(us));
......
...@@ -190,8 +190,7 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data) ...@@ -190,8 +190,7 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data)
* @num_ports: the number of different ports this device will have. * @num_ports: the number of different ports this device will have.
* @bulk_in_size: minimum number of bytes to allocate for bulk-in buffer * @bulk_in_size: minimum number of bytes to allocate for bulk-in buffer
* (0 = end-point size) * (0 = end-point size)
* @bulk_out_size: minimum number of bytes to allocate for bulk-out buffer * @bulk_out_size: bytes to allocate for bulk-out buffer (0 = end-point size)
* (0 = end-point size)
* @calc_num_ports: pointer to a function to determine how many ports this * @calc_num_ports: pointer to a function to determine how many ports this
* device has dynamically. It will be called after the probe() * device has dynamically. It will be called after the probe()
* callback is called, but before attach() * callback is called, but before attach()
......
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