summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/class/cdc-wdm.c25
-rw-r--r--drivers/usb/core/driver.c10
-rw-r--r--drivers/usb/core/file.c2
-rw-r--r--drivers/usb/core/message.c5
-rw-r--r--drivers/usb/core/sysfs.c5
-rw-r--r--drivers/usb/early/ehci-dbgp.c2
-rw-r--r--drivers/usb/host/Kconfig4
-rw-r--r--drivers/usb/host/ehci-fsl.c21
-rw-r--r--drivers/usb/host/ehci-hub.c2
-rw-r--r--drivers/usb/host/ehci.h4
-rw-r--r--drivers/usb/host/ohci-nxp.c88
-rw-r--r--drivers/usb/host/ohci-omap.c27
-rw-r--r--drivers/usb/host/ohci.h5
-rw-r--r--drivers/usb/serial/keyspan.c5
-rw-r--r--drivers/usb/serial/option.c88
-rw-r--r--drivers/usb/serial/quatech2.c4
-rw-r--r--drivers/usb/storage/protocol.c6
-rw-r--r--include/linux/mod_devicetable.h10
-rw-r--r--include/linux/usb.h16
-rw-r--r--include/linux/usb/hcd.h6
-rw-r--r--include/linux/usb/renesas_usbhs.h8
-rw-r--r--scripts/mod/file2alias.c5
-rw-r--r--tools/usb/testusb.c21
23 files changed, 216 insertions, 153 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 8fd398dffced..25e7d72f339e 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -32,8 +32,6 @@
#define DRIVER_AUTHOR "Oliver Neukum"
#define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"
-#define HUAWEI_VENDOR_ID 0x12D1
-
static const struct usb_device_id wdm_ids[] = {
{
.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
@@ -41,29 +39,6 @@ static const struct usb_device_id wdm_ids[] = {
.bInterfaceClass = USB_CLASS_COMM,
.bInterfaceSubClass = USB_CDC_SUBCLASS_DMM
},
- {
- /*
- * Huawei E392, E398 and possibly other Qualcomm based modems
- * embed the Qualcomm QMI protocol inside CDC on CDC ECM like
- * control interfaces. Userspace access to this is required
- * to configure the accompanying data interface
- */
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
- USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = HUAWEI_VENDOR_ID,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */
- },
- {
- /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
- USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = HUAWEI_VENDOR_ID,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 57, /* NOTE: CDC ECM control interface! */
- },
{ }
};
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index f536aebc958e..69781016a266 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -367,6 +367,7 @@ static int usb_probe_interface(struct device *dev)
return error;
err:
+ usb_set_intfdata(intf, NULL);
intf->needs_remote_wakeup = 0;
intf->condition = USB_INTERFACE_UNBOUND;
usb_cancel_queued_reset(intf);
@@ -622,14 +623,15 @@ int usb_match_one_id(struct usb_interface *interface,
if (!usb_match_device(dev, id))
return 0;
- /* The interface class, subclass, and protocol should never be
+ /* The interface class, subclass, protocol and number should never be
* checked for a match if the device class is Vendor Specific,
* unless the match record specifies the Vendor ID. */
if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
!(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
(id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS |
- USB_DEVICE_ID_MATCH_INT_PROTOCOL)))
+ USB_DEVICE_ID_MATCH_INT_PROTOCOL |
+ USB_DEVICE_ID_MATCH_INT_NUMBER)))
return 0;
if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
@@ -644,6 +646,10 @@ int usb_match_one_id(struct usb_interface *interface,
(id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
return 0;
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) &&
+ (id->bInterfaceNumber != intf->desc.bInterfaceNumber))
+ return 0;
+
return 1;
}
EXPORT_SYMBOL_GPL(usb_match_one_id);
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index e673b26e598f..e5387a47ef6f 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -92,7 +92,7 @@ static int init_usb_class(void)
}
kref_init(&usb_class->kref);
- usb_class->class = class_create(THIS_MODULE, "usb");
+ usb_class->class = class_create(THIS_MODULE, "usbmisc");
if (IS_ERR(usb_class->class)) {
result = IS_ERR(usb_class->class);
printk(KERN_ERR "class_create failed for usb devices\n");
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index bdd1c6749d88..8b9d669e3784 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1559,7 +1559,7 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
if (add_uevent_var(env,
"MODALIAS=usb:"
- "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+ "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02Xin%02X",
le16_to_cpu(usb_dev->descriptor.idVendor),
le16_to_cpu(usb_dev->descriptor.idProduct),
le16_to_cpu(usb_dev->descriptor.bcdDevice),
@@ -1568,7 +1568,8 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
usb_dev->descriptor.bDeviceProtocol,
alt->desc.bInterfaceClass,
alt->desc.bInterfaceSubClass,
- alt->desc.bInterfaceProtocol))
+ alt->desc.bInterfaceProtocol,
+ alt->desc.bInterfaceNumber))
return -ENOMEM;
return 0;
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 9a56e3adf476..777f03c37725 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -840,7 +840,7 @@ static ssize_t show_modalias(struct device *dev,
alt = intf->cur_altsetting;
return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X"
- "ic%02Xisc%02Xip%02X\n",
+ "ic%02Xisc%02Xip%02Xin%02X\n",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct),
le16_to_cpu(udev->descriptor.bcdDevice),
@@ -849,7 +849,8 @@ static ssize_t show_modalias(struct device *dev,
udev->descriptor.bDeviceProtocol,
alt->desc.bInterfaceClass,
alt->desc.bInterfaceSubClass,
- alt->desc.bInterfaceProtocol);
+ alt->desc.bInterfaceProtocol,
+ alt->desc.bInterfaceNumber);
}
static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c
index 1fc8f1249806..ee0ebacf8227 100644
--- a/drivers/usb/early/ehci-dbgp.c
+++ b/drivers/usb/early/ehci-dbgp.c
@@ -334,7 +334,7 @@ static int dbgp_control_msg(unsigned devnum, int requesttype,
int ret;
read = (requesttype & USB_DIR_IN) != 0;
- if (size > (read ? DBGP_MAX_PACKET:0))
+ if (size > (read ? DBGP_MAX_PACKET : 0))
return -1;
/* Compute the control message */
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 83e58df29fe3..18ba33da34ec 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -652,7 +652,7 @@ config USB_HCD_BCMA
select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
help
- Enbale support for the EHCI and OCHI host controller on an bcma bus.
+ Enable support for the EHCI and OCHI host controller on an bcma bus.
It converts the bcma driver into two platform device drivers
for ehci and ohci.
@@ -664,7 +664,7 @@ config USB_HCD_SSB
select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
help
- Enbale support for the EHCI and OCHI host controller on an bcma bus.
+ Enable support for the EHCI and OCHI host controller on an bcma bus.
It converts the bcma driver into two platform device drivers
for ehci and ohci.
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 43362577b54a..3379945b095e 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -142,19 +142,19 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
if (pdata->operating_mode == FSL_USB2_DR_OTG) {
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- ehci->transceiver = usb_get_transceiver();
- dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, transceiver=0x%p\n",
- hcd, ehci, ehci->transceiver);
+ hcd->phy = usb_get_transceiver();
+ dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, phy=0x%p\n",
+ hcd, ehci, hcd->phy);
- if (ehci->transceiver) {
- retval = otg_set_host(ehci->transceiver->otg,
+ if (hcd->phy) {
+ retval = otg_set_host(hcd->phy->otg,
&ehci_to_hcd(ehci)->self);
if (retval) {
- usb_put_transceiver(ehci->transceiver);
+ usb_put_transceiver(hcd->phy);
goto err4;
}
} else {
- dev_err(&pdev->dev, "can't find transceiver\n");
+ dev_err(&pdev->dev, "can't find phy\n");
retval = -ENODEV;
goto err4;
}
@@ -190,11 +190,10 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- if (ehci->transceiver) {
- otg_set_host(ehci->transceiver->otg, NULL);
- usb_put_transceiver(ehci->transceiver);
+ if (hcd->phy) {
+ otg_set_host(hcd->phy->otg, NULL);
+ usb_put_transceiver(hcd->phy);
}
usb_remove_hcd(hcd);
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index fc9e7cc6ac9b..dd5eef6af6df 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -724,7 +724,7 @@ static int ehci_hub_control (
#ifdef CONFIG_USB_OTG
if ((hcd->self.otg_port == (wIndex + 1))
&& hcd->self.b_hnp_enable) {
- otg_start_hnp(ehci->transceiver->otg);
+ otg_start_hnp(hcd->phy->otg);
break;
}
#endif
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 2694ed6558d2..85c3572155d1 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -175,10 +175,6 @@ struct ehci_hcd { /* one per controller */
#ifdef DEBUG
struct dentry *debug_dir;
#endif
- /*
- * OTG controllers and transceivers need software interaction
- */
- struct usb_phy *transceiver;
};
/* convert between an HCD pointer and the corresponding EHCI_HCD */
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c
index 1e364ec962fb..a446386bf779 100644
--- a/drivers/usb/host/ohci-nxp.c
+++ b/drivers/usb/host/ohci-nxp.c
@@ -43,16 +43,6 @@
#define USB_HOST_NEED_CLK_EN (1 << 21)
#define PAD_CONTROL_LAST_DRIVEN (1 << 19)
-#define USB_OTG_CLK_CTRL IO_ADDRESS(USB_CONFIG_BASE + 0xFF4)
-#define USB_OTG_CLK_STAT IO_ADDRESS(USB_CONFIG_BASE + 0xFF8)
-
-/* USB_OTG_CLK_CTRL bit defines */
-#define AHB_M_CLOCK_ON (1 << 4)
-#define OTG_CLOCK_ON (1 << 3)
-#define I2C_CLOCK_ON (1 << 2)
-#define DEV_CLOCK_ON (1 << 1)
-#define HOST_CLOCK_ON (1 << 0)
-
#define USB_OTG_STAT_CONTROL IO_ADDRESS(USB_CONFIG_BASE + 0x110)
/* USB_OTG_STAT_CONTROL bit defines */
@@ -72,7 +62,9 @@ static struct i2c_client *isp1301_i2c_client;
extern int usb_disabled(void);
-static struct clk *usb_clk;
+static struct clk *usb_pll_clk;
+static struct clk *usb_dev_clk;
+static struct clk *usb_otg_clk;
static void isp1301_configure_pnx4008(void)
{
@@ -249,8 +241,6 @@ static const struct hc_driver ohci_nxp_hc_driver = {
.start_port_reset = ohci_start_port_reset,
};
-#define USB_CLOCK_MASK (AHB_M_CLOCK_ON| OTG_CLOCK_ON | HOST_CLOCK_ON | I2C_CLOCK_ON)
-
static void nxp_set_usb_bits(void)
{
if (machine_is_pnx4008()) {
@@ -327,41 +317,63 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)
/* Enable AHB slave USB clock, needed for further USB clock control */
__raw_writel(USB_SLAVE_HCLK_EN | PAD_CONTROL_LAST_DRIVEN, USB_CTRL);
- isp1301_configure();
-
/* Enable USB PLL */
- usb_clk = clk_get(&pdev->dev, "ck_pll5");
- if (IS_ERR(usb_clk)) {
+ usb_pll_clk = clk_get(&pdev->dev, "ck_pll5");
+ if (IS_ERR(usb_pll_clk)) {
dev_err(&pdev->dev, "failed to acquire USB PLL\n");
- ret = PTR_ERR(usb_clk);
+ ret = PTR_ERR(usb_pll_clk);
goto out1;
}
- ret = clk_enable(usb_clk);
+ ret = clk_enable(usb_pll_clk);
if (ret < 0) {
dev_err(&pdev->dev, "failed to start USB PLL\n");
goto out2;
}
- ret = clk_set_rate(usb_clk, 48000);
+ ret = clk_set_rate(usb_pll_clk, 48000);
if (ret < 0) {
dev_err(&pdev->dev, "failed to set USB clock rate\n");
goto out3;
}
+ /* Enable USB device clock */
+ usb_dev_clk = clk_get(&pdev->dev, "ck_usbd");
+ if (IS_ERR(usb_dev_clk)) {
+ dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n");
+ ret = PTR_ERR(usb_dev_clk);
+ goto out4;
+ }
+
+ ret = clk_enable(usb_dev_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
+ goto out5;
+ }
+
+ /* Enable USB otg clocks */
+ usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg");
+ if (IS_ERR(usb_otg_clk)) {
+ dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n");
+ ret = PTR_ERR(usb_dev_clk);
+ goto out6;
+ }
+
__raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);
- /* Set to enable all needed USB clocks */
- __raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL);
+ ret = clk_enable(usb_otg_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
+ goto out7;
+ }
- while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) !=
- USB_CLOCK_MASK) ;
+ isp1301_configure();
hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd) {
dev_err(&pdev->dev, "Failed to allocate HC buffer\n");
ret = -ENOMEM;
- goto out3;
+ goto out8;
}
/* Set all USB bits in the Start Enable register */
@@ -371,14 +383,14 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)
if (!res) {
dev_err(&pdev->dev, "Failed to get MEM resource\n");
ret = -ENOMEM;
- goto out4;
+ goto out8;
}
hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
if (!hcd->regs) {
dev_err(&pdev->dev, "Failed to devm_request_and_ioremap\n");
ret = -ENOMEM;
- goto out4;
+ goto out8;
}
hcd->rsrc_start = res->start;
hcd->rsrc_len = resource_size(res);
@@ -386,7 +398,7 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = -ENXIO;
- goto out4;
+ goto out8;
}
nxp_start_hc();
@@ -400,13 +412,21 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)
return ret;
nxp_stop_hc();
-out4:
+out8:
nxp_unset_usb_bits();
usb_put_hcd(hcd);
+out7:
+ clk_disable(usb_otg_clk);
+out6:
+ clk_put(usb_otg_clk);
+out5:
+ clk_disable(usb_dev_clk);
+out4:
+ clk_put(usb_dev_clk);
out3:
- clk_disable(usb_clk);
+ clk_disable(usb_pll_clk);
out2:
- clk_put(usb_clk);
+ clk_put(usb_pll_clk);
out1:
isp1301_i2c_client = NULL;
out:
@@ -422,8 +442,10 @@ static int usb_hcd_nxp_remove(struct platform_device *pdev)
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
nxp_unset_usb_bits();
- clk_disable(usb_clk);
- clk_put(usb_clk);
+ clk_disable(usb_pll_clk);
+ clk_put(usb_pll_clk);
+ clk_disable(usb_dev_clk);
+ clk_put(usb_dev_clk);
i2c_unregister_device(isp1301_i2c_client);
isp1301_i2c_client = NULL;
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 9ce35d0d9d5d..eccddb461396 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -167,14 +167,15 @@ static int omap_1510_local_bus_init(void)
static void start_hnp(struct ohci_hcd *ohci)
{
- const unsigned port = ohci_to_hcd(ohci)->self.otg_port - 1;
+ struct usb_hcd *hcd = ohci_to_hcd(ohci);
+ const unsigned port = hcd->self.otg_port - 1;
unsigned long flags;
u32 l;
- otg_start_hnp(ohci->transceiver->otg);
+ otg_start_hnp(hcd->phy->otg);
local_irq_save(flags);
- ohci->transceiver->state = OTG_STATE_A_SUSPEND;
+ hcd->phy->state = OTG_STATE_A_SUSPEND;
writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]);
l = omap_readl(OTG_CTRL);
l &= ~OTG_A_BUSREQ;
@@ -211,18 +212,18 @@ static int ohci_omap_init(struct usb_hcd *hcd)
#ifdef CONFIG_USB_OTG
if (need_transceiver) {
- ohci->transceiver = usb_get_transceiver();
- if (ohci->transceiver) {
- int status = otg_set_host(ohci->transceiver->otg,
+ hcd->phy = usb_get_transceiver();
+ if (hcd->phy) {
+ int status = otg_set_host(hcd->phy->otg,
&ohci_to_hcd(ohci)->self);
- dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n",
- ohci->transceiver->label, status);
+ dev_dbg(hcd->self.controller, "init %s phy, status %d\n",
+ hcd->phy->label, status);
if (status) {
- usb_put_transceiver(ohci->transceiver);
+ usb_put_transceiver(hcd->phy);
return status;
}
} else {
- dev_err(hcd->self.controller, "can't find transceiver\n");
+ dev_err(hcd->self.controller, "can't find phy\n");
return -ENODEV;
}
ohci->start_hnp = start_hnp;
@@ -403,9 +404,9 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
usb_remove_hcd(hcd);
- if (ohci->transceiver) {
- (void) otg_set_host(ohci->transceiver->otg, 0);
- usb_put_transceiver(ohci->transceiver);
+ if (hcd->phy) {
+ (void) otg_set_host(hcd->phy->otg, 0);
+ usb_put_transceiver(hcd->phy);
}
if (machine_is_omap_osk())
gpio_free(9);
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 1b19aea25a2b..d3299143d9e2 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -372,11 +372,6 @@ struct ohci_hcd {
struct ed *ed_controltail; /* last in ctrl list */
struct ed *periodic [NUM_INTS]; /* shadow int_table */
- /*
- * OTG controllers and transceivers need software interaction;
- * other external transceivers should be software-transparent
- */
- struct usb_phy *transceiver;
void (*start_hnp)(struct ohci_hcd *ohci);
/*
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index a1b99243dac9..9a0ca8355905 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -1036,15 +1036,12 @@ static int keyspan_write_room(struct tty_struct *tty)
static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port)
{
struct keyspan_port_private *p_priv;
- struct keyspan_serial_private *s_priv;
- struct usb_serial *serial = port->serial;
const struct keyspan_device_details *d_details;
int i, err;
int baud_rate, device_port;
struct urb *urb;
unsigned int cflag = 0;
- s_priv = usb_get_serial_data(serial);
p_priv = usb_get_serial_port_data(port);
d_details = p_priv->device_details;
@@ -1130,10 +1127,8 @@ static void keyspan_close(struct usb_serial_port *port)
{
int i;
struct usb_serial *serial = port->serial;
- struct keyspan_serial_private *s_priv;
struct keyspan_port_private *p_priv;
- s_priv = usb_get_serial_data(serial);
p_priv = usb_get_serial_port_data(port);
p_priv->rts_state = 0;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index e668a2460bd4..9520c4c54743 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1276,6 +1276,10 @@ static struct usb_serial_driver * const serial_drivers[] = {
static bool debug;
+struct option_private {
+ u8 bInterfaceNumber;
+};
+
module_usb_serial_driver(serial_drivers, option_ids);
static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
@@ -1306,51 +1310,78 @@ static int option_probe(struct usb_serial *serial,
const struct usb_device_id *id)
{
struct usb_wwan_intf_private *data;
-
- /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */
- if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID &&
- serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 &&
- serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8)
+ struct option_private *priv;
+ struct usb_interface_descriptor *iface_desc =
+ &serial->interface->cur_altsetting->desc;
+ struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
+
+ /*
+ * D-Link DWM 652 still exposes CD-Rom emulation interface in modem
+ * mode.
+ */
+ if (dev_desc->idVendor == DLINK_VENDOR_ID &&
+ dev_desc->idProduct == DLINK_PRODUCT_DWM_652 &&
+ iface_desc->bInterfaceClass == 0x08)
return -ENODEV;
/* Bandrich modem and AT command interface is 0xff */
- if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID ||
- serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) &&
- serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff)
+ if ((dev_desc->idVendor == BANDRICH_VENDOR_ID ||
+ dev_desc->idVendor == PIRELLI_VENDOR_ID) &&
+ iface_desc->bInterfaceClass != 0xff)
return -ENODEV;
-
- /* Don't bind reserved interfaces (like network ones) which often have
+ /*
+ * Don't bind reserved interfaces (like network ones) which often have
* the same class/subclass/protocol as the serial interfaces. Look at
* the Windows driver .INF files for reserved interface numbers.
*/
if (is_blacklisted(
- serial->interface->cur_altsetting->desc.bInterfaceNumber,
+ iface_desc->bInterfaceNumber,
OPTION_BLACKLIST_RESERVED_IF,
(const struct option_blacklist_info *) id->driver_info))
return -ENODEV;
-
- /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */
- if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID &&
- serial->dev->descriptor.idProduct == SAMSUNG_PRODUCT_GT_B3730 &&
- serial->interface->cur_altsetting->desc.bInterfaceClass != USB_CLASS_CDC_DATA)
+ /*
+ * Don't bind network interface on Samsung GT-B3730, it is handled by
+ * a separate module.
+ */
+ if (dev_desc->idVendor == SAMSUNG_VENDOR_ID &&
+ dev_desc->idProduct == SAMSUNG_PRODUCT_GT_B3730 &&
+ iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
return -ENODEV;
- data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
+ data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
if (!data)
return -ENOMEM;
- data->send_setup = option_send_setup;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ kfree(data);
+ return -ENOMEM;
+ }
+
+ priv->bInterfaceNumber = iface_desc->bInterfaceNumber;
+ data->private = priv;
+
+ if (!is_blacklisted(iface_desc->bInterfaceNumber,
+ OPTION_BLACKLIST_SENDSETUP,
+ (struct option_blacklist_info *)id->driver_info)) {
+ data->send_setup = option_send_setup;
+ }
spin_lock_init(&data->susp_lock);
- data->private = (void *)id->driver_info;
+
+ usb_set_serial_data(serial, data);
+
return 0;
}
static void option_release(struct usb_serial *serial)
{
- struct usb_wwan_intf_private *priv = usb_get_serial_data(serial);
+ struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
+ struct option_private *priv = intfdata->private;
usb_wwan_release(serial);
kfree(priv);
+ kfree(intfdata);
}
static void option_instat_callback(struct urb *urb)
@@ -1417,18 +1448,11 @@ static void option_instat_callback(struct urb *urb)
static int option_send_setup(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
- struct usb_wwan_intf_private *intfdata =
- (struct usb_wwan_intf_private *) serial->private;
+ struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
+ struct option_private *priv = intfdata->private;
struct usb_wwan_port_private *portdata;
- int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
int val = 0;
- if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP,
- (struct option_blacklist_info *) intfdata->private)) {
- dbg("No send_setup on blacklisted interface #%d\n", ifNum);
- return -EIO;
- }
-
portdata = usb_get_serial_port_data(port);
if (portdata->dtr_state)
@@ -1436,9 +1460,9 @@ static int option_send_setup(struct usb_serial_port *port)
if (portdata->rts_state)
val |= 0x02;
- return usb_control_msg(serial->dev,
- usb_rcvctrlpipe(serial->dev, 0),
- 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT);
+ return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ 0x22, 0x21, val, priv->bInterfaceNumber, NULL,
+ 0, USB_CTRL_SET_TIMEOUT);
}
MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index 8dd88ebe9863..151670b6b72a 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -345,7 +345,6 @@ static void qt2_set_termios(struct tty_struct *tty,
static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
{
struct usb_serial *serial;
- struct qt2_serial_private *serial_priv;
struct qt2_port_private *port_priv;
u8 *data;
u16 device_port;
@@ -357,7 +356,6 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
serial = port->serial;
port_priv = usb_get_serial_port_data(port);
- serial_priv = usb_get_serial_data(serial);
/* set the port to RS232 mode */
status = qt2_control_msg(serial->dev, QT2_GET_SET_QMCR,
@@ -417,13 +415,11 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
static void qt2_close(struct usb_serial_port *port)
{
struct usb_serial *serial;
- struct qt2_serial_private *serial_priv;
struct qt2_port_private *port_priv;
unsigned long flags;
int i;
serial = port->serial;
- serial_priv = usb_get_serial_data(serial);
port_priv = usb_get_serial_port_data(port);
port_priv->is_open = false;
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index 82dd834709c7..5dfb4c36a1b0 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -66,7 +66,7 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
* NOTE: This only works because a scsi_cmnd struct field contains
* a unsigned char cmnd[16], so we know we have storage available
*/
- for (; srb->cmd_len<12; srb->cmd_len++)
+ for (; srb->cmd_len < 12; srb->cmd_len++)
srb->cmnd[srb->cmd_len] = 0;
/* send the command to the transport layer */
@@ -76,14 +76,14 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us)
{
/* fix some commands -- this is a form of mode translation
- * UFI devices only accept 12 byte long commands
+ * UFI devices only accept 12 byte long commands
*
* NOTE: This only works because a scsi_cmnd struct field contains
* a unsigned char cmnd[16], so we know we have storage available
*/
/* Pad the ATAPI command with zeros */
- for (; srb->cmd_len<12; srb->cmd_len++)
+ for (; srb->cmd_len < 12; srb->cmd_len++)
srb->cmnd[srb->cmd_len] = 0;
/* set command length to 12 bytes (this affects the transport layer) */
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 5db93821f9c7..6955045199b0 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -78,6 +78,9 @@ struct ieee1394_device_id {
* of a given interface; other interfaces may support other classes.
* @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
* @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
+ * @bInterfaceNumber: Number of interface; composite devices may use
+ * fixed interface numbers to differentiate between vendor-specific
+ * interfaces.
* @driver_info: Holds information used by the driver. Usually it holds
* a pointer to a descriptor understood by the driver, or perhaps
* device flags.
@@ -115,8 +118,12 @@ struct usb_device_id {
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
+ /* Used for vendor-specific interface matches */
+ __u8 bInterfaceNumber;
+
/* not matched against */
- kernel_ulong_t driver_info;
+ kernel_ulong_t driver_info
+ __attribute__((aligned(sizeof(kernel_ulong_t))));
};
/* Some useful macros to use to create struct usb_device_id */
@@ -130,6 +137,7 @@ struct usb_device_id {
#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080
#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
+#define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400
#define HID_ANY_ID (~0)
#define HID_BUS_ANY 0xffff
diff --git a/include/linux/usb.h b/include/linux/usb.h
index dea39dc551d4..f717fbdaee8e 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -777,6 +777,22 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size)
.bInterfaceProtocol = (pr)
/**
+ * USB_DEVICE_INTERFACE_NUMBER - describe a usb device with a specific interface number
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ * @num: bInterfaceNumber value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific interface number of devices.
+ */
+#define USB_DEVICE_INTERFACE_NUMBER(vend, prod, num) \
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+ USB_DEVICE_ID_MATCH_INT_NUMBER, \
+ .idVendor = (vend), \
+ .idProduct = (prod), \
+ .bInterfaceNumber = (num)
+
+/**
* USB_DEVICE_INFO - macro used to describe a class of usb devices
* @cl: bDeviceClass value
* @sc: bDeviceSubClass value
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 49b3ac29726a..c5fdb148fc02 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -93,6 +93,12 @@ struct usb_hcd {
*/
const struct hc_driver *driver; /* hw-specific hooks */
+ /*
+ * OTG and some Host controllers need software interaction with phys;
+ * other external phys should be software-transparent
+ */
+ struct usb_phy *phy;
+
/* Flags that need to be manipulated atomically because they can
* change while the host controller is running. Always use
* set_bit() or clear_bit() to change their values.
diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h
index 547e59cc00ea..c5d36c65c33b 100644
--- a/include/linux/usb/renesas_usbhs.h
+++ b/include/linux/usb/renesas_usbhs.h
@@ -132,6 +132,14 @@ struct renesas_usbhs_driver_param {
* option:
*
* dma id for dmaengine
+ * The data transfer direction on D0FIFO/D1FIFO should be
+ * fixed for keeping consistency.
+ * So, the platform id settings will be..
+ * .d0_tx_id = xx_TX,
+ * .d1_rx_id = xx_RX,
+ * or
+ * .d1_tx_id = xx_TX,
+ * .d0_rx_id = xx_RX,
*/
int d0_tx_id;
int d0_rx_id;
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 5759751a1f61..7ed6864ef65b 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -156,7 +156,7 @@ static void device_id_check(const char *modname, const char *device_id,
}
/* USB is special because the bcdDevice can be matched against a numeric range */
-/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */
+/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */
static void do_usb_entry(struct usb_device_id *id,
unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
unsigned char range_lo, unsigned char range_hi,
@@ -210,6 +210,9 @@ static void do_usb_entry(struct usb_device_id *id,
ADD(alias, "ip",
id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
id->bInterfaceProtocol);
+ ADD(alias, "in",
+ id->match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER,
+ id->bInterfaceNumber);
add_wildcard(alias);
buf_printf(&mod->dev_table_buf,
diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c
index 82d7c590c026..b0adb2710c02 100644
--- a/tools/usb/testusb.c
+++ b/tools/usb/testusb.c
@@ -425,7 +425,7 @@ int main (int argc, char **argv)
/* for easy use when hotplugging */
device = getenv ("DEVICE");
- while ((c = getopt (argc, argv, "D:aA:c:g:hns:t:v:")) != EOF)
+ while ((c = getopt (argc, argv, "D:aA:c:g:hlns:t:v:")) != EOF)
switch (c) {
case 'D': /* device, if only one */
device = optarg;
@@ -468,10 +468,21 @@ int main (int argc, char **argv)
case 'h':
default:
usage:
- fprintf (stderr, "usage: %s [-n] [-D dev | -a | -A usbfs-dir]\n"
- "\t[-c iterations] [-t testnum]\n"
- "\t[-s packetsize] [-g sglen] [-v vary]\n",
- argv [0]);
+ fprintf (stderr,
+ "usage: %s [options]\n"
+ "Options:\n"
+ "\t-D dev only test specific device\n"
+ "\t-A usbfs-dir\n"
+ "\t-a test all recognized devices\n"
+ "\t-l loop forever(for stress test)\n"
+ "\t-t testnum only run specified case\n"
+ "\t-n no test running, show devices to be tested\n"
+ "Case arguments:\n"
+ "\t-c iterations default 1000\n"
+ "\t-s packetsize default 512\n"
+ "\t-g sglen default 32\n"
+ "\t-v vary default 512\n",
+ argv[0]);
return 1;
}
if (optind != argc)
OpenPOWER on IntegriCloud