From b064eca9b0cdbb2b8f731ae2e44fa02194a1219a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 24 Sep 2008 11:49:19 -0400 Subject: USB: option: add Ericsson F3507g and Dell 5530 Add a few more mobile broadband cards. Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 6b1727e751e3..2d728e897b4d 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -220,6 +220,10 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po #define ZTE_PRODUCT_MF628 0x0015 #define ZTE_PRODUCT_CDMA_TECH 0xfffe +/* Ericsson products */ +#define ERICSSON_VENDOR_ID 0x0bdb +#define ERICSSON_PRODUCT_F3507G 0x1900 + static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -318,6 +322,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, @@ -349,6 +354,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, + { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); -- cgit v1.2.3 From 631556a0763ac155c82bbcbeed7e4b28bd737927 Mon Sep 17 00:00:00 2001 From: Denis Joseph Barrow Date: Tue, 30 Sep 2008 16:49:22 +0200 Subject: USB: option.c remove duplicate device ids now supported in hso.c Remove duplicate device ids which are now supported by drivers/usb/net/hso.c Signed-off-by: Denis Joseph Barrow Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 2d728e897b4d..fa8ec3af5f38 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -79,27 +79,16 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po #define OPTION_PRODUCT_VIPER 0x6600 #define OPTION_PRODUCT_VIPER_BUS 0x6601 #define OPTION_PRODUCT_GT_MAX_READY 0x6701 -#define OPTION_PRODUCT_GT_MAX 0x6711 #define OPTION_PRODUCT_FUJI_MODEM_LIGHT 0x6721 #define OPTION_PRODUCT_FUJI_MODEM_GT 0x6741 #define OPTION_PRODUCT_FUJI_MODEM_EX 0x6761 -#define OPTION_PRODUCT_FUJI_NETWORK_LIGHT 0x6731 -#define OPTION_PRODUCT_FUJI_NETWORK_GT 0x6751 -#define OPTION_PRODUCT_FUJI_NETWORK_EX 0x6771 #define OPTION_PRODUCT_KOI_MODEM 0x6800 -#define OPTION_PRODUCT_KOI_NETWORK 0x6811 #define OPTION_PRODUCT_SCORPION_MODEM 0x6901 -#define OPTION_PRODUCT_SCORPION_NETWORK 0x6911 #define OPTION_PRODUCT_ETNA_MODEM 0x7001 -#define OPTION_PRODUCT_ETNA_NETWORK 0x7011 #define OPTION_PRODUCT_ETNA_MODEM_LITE 0x7021 #define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041 #define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061 -#define OPTION_PRODUCT_ETNA_NETWORK_LITE 0x7031 -#define OPTION_PRODUCT_ETNA_NETWORK_GT 0x7051 -#define OPTION_PRODUCT_ETNA_NETWORK_EX 0x7071 #define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100 -#define OPTION_PRODUCT_ETNA_KOI_NETWORK 0x7111 #define HUAWEI_VENDOR_ID 0x12D1 #define HUAWEI_PRODUCT_E600 0x1001 @@ -239,27 +228,16 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER_BUS) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX_READY) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_LIGHT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_GT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_EX) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_GT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_EX) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_NETWORK) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_NETWORK) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_LITE) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_LITE) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_GT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, -- cgit v1.2.3 From c3d36c453c84554eb12941b3f98abf4fefec000a Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Fri, 3 Oct 2008 17:08:43 -0700 Subject: USB: Add Oceanic product ID to ftdi_sio Add Oceanic PID to ftdi_sio driver Oceanic dive computers (such as the VT3 -- http://www.oceanicworldwide.com/p_computers_vt3.html) all use an onboard FTDI serial converter, with the FTDI vid and a PID of 0xf460. The attached patch adds that pid to ftdi_sio; driver connects to my VT3 after that. Signed-off-by: Vladimir Vukicevic Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c2ac129557aa..ef3dc1a61b61 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -578,6 +578,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) }, { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 8a5b6df3a976..07a3992abad2 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -627,6 +627,11 @@ */ #define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ +/* + * Oceanic product ids + */ +#define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */ + /* * TTi (Thurlby Thandar Instruments) */ -- cgit v1.2.3 From eb86be5424d4c08e686d5e578b72a26c516ae58a Mon Sep 17 00:00:00 2001 From: Harrison Metzger Date: Thu, 14 Aug 2008 11:29:32 -0500 Subject: USB: Added driver for a Delcom USB 7-segment LED Display Added basic support for a Delcom USB 7-segment LED Display Signed-off by: Harrison Metzger Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-bus-usb-devices-usbsevseg | 43 +++ Documentation/usb/misc_usbsevseg.txt | 46 +++ drivers/usb/misc/Kconfig | 9 + drivers/usb/misc/Makefile | 1 + drivers/usb/misc/usbsevseg.c | 394 +++++++++++++++++++++ 5 files changed, 493 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg create mode 100644 Documentation/usb/misc_usbsevseg.txt create mode 100644 drivers/usb/misc/usbsevseg.c diff --git a/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg b/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg new file mode 100644 index 000000000000..cb830df8777c --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg @@ -0,0 +1,43 @@ +Where: /sys/bus/usb/.../powered +Date: August 2008 +Kernel Version: 2.6.26 +Contact: Harrison Metzger +Description: Controls whether the device's display will powered. + A value of 0 is off and a non-zero value is on. + +Where: /sys/bus/usb/.../mode_msb +Where: /sys/bus/usb/.../mode_lsb +Date: August 2008 +Kernel Version: 2.6.26 +Contact: Harrison Metzger +Description: Controls the devices display mode. + For a 6 character display the values are + MSB 0x06; LSB 0x3F, and + for an 8 character display the values are + MSB 0x08; LSB 0xFF. + +Where: /sys/bus/usb/.../textmode +Date: August 2008 +Kernel Version: 2.6.26 +Contact: Harrison Metzger +Description: Controls the way the device interprets its text buffer. + raw: each character controls its segment manually + hex: each character is between 0-15 + ascii: each character is between '0'-'9' and 'A'-'F'. + +Where: /sys/bus/usb/.../text +Date: August 2008 +Kernel Version: 2.6.26 +Contact: Harrison Metzger +Description: The text (or data) for the device to display + +Where: /sys/bus/usb/.../decimals +Date: August 2008 +Kernel Version: 2.6.26 +Contact: Harrison Metzger +Description: Controls the decimal places on the device. + To set the nth decimal place, give this field + the value of 10 ** n. Assume this field has + the value k and has 1 or more decimal places set, + to set the mth place (where m is not already set), + change this fields value to k + 10 ** m. \ No newline at end of file diff --git a/Documentation/usb/misc_usbsevseg.txt b/Documentation/usb/misc_usbsevseg.txt new file mode 100644 index 000000000000..0f6be4f9930b --- /dev/null +++ b/Documentation/usb/misc_usbsevseg.txt @@ -0,0 +1,46 @@ +USB 7-Segment Numeric Display +Manufactured by Delcom Engineering + +Device Information +------------------ +USB VENDOR_ID 0x0fc5 +USB PRODUCT_ID 0x1227 +Both the 6 character and 8 character displays have PRODUCT_ID, +and according to Delcom Engineering no queryable information +can be obtained from the device to tell them apart. + +Device Modes +------------ +By default, the driver assumes the display is only 6 characters +The mode for 6 characters is: + MSB 0x06; LSB 0x3f +For the 8 character display: + MSB 0x08; LSB 0xff +The device can accept "text" either in raw, hex, or ascii textmode. +raw controls each segment manually, +hex expects a value between 0-15 per character, +ascii expects a value between '0'-'9' and 'A'-'F'. +The default is ascii. + +Device Operation +---------------- +1. Turn on the device: + echo 1 > /sys/bus/usb/.../powered +2. Set the device's mode: + echo $mode_msb > /sys/bus/usb/.../mode_msb + echo $mode_lsb > /sys/bus/usb/.../mode_lsb +3. Set the textmode: + echo $textmode > /sys/bus/usb/.../textmode +4. set the text (for example): + echo "123ABC" > /sys/bus/usb/.../text (ascii) + echo "A1B2" > /sys/bus/usb/.../text (ascii) + echo -ne "\x01\x02\x03" > /sys/bus/usb/.../text (hex) +5. Set the decimal places. + The device has either 6 or 8 decimal points. + to set the nth decimal place calculate 10 ** n + and echo it in to /sys/bus/usb/.../decimals + To set multiple decimals points sum up each power. + For example, to set the 0th and 3rd decimal place + echo 1001 > /sys/bus/usb/.../decimals + + diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 4ea50e0abcbb..25e1157ab176 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -42,6 +42,15 @@ config USB_ADUTUX To compile this driver as a module, choose M here. The module will be called adutux. +config USB_SEVSEG + tristate "USB 7-Segment LED Display" + depends on USB + help + Say Y here if you have a USB 7-Segment Display by Delcom + + To compile this driver as a module, choose M here: the + module will be called usbsevseg. + config USB_RIO500 tristate "USB Diamond Rio500 support" depends on USB diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 45b4e12afb08..39ce4a16b3d4 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_USB_RIO500) += rio500.o obj-$(CONFIG_USB_TEST) += usbtest.o obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o obj-$(CONFIG_USB_USS720) += uss720.o +obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c new file mode 100644 index 000000000000..28a6a3a09538 --- /dev/null +++ b/drivers/usb/misc/usbsevseg.c @@ -0,0 +1,394 @@ +/* + * USB 7 Segment Driver + * + * Copyright (C) 2008 Harrison Metzger + * Based on usbled.c by Greg Kroah-Hartman (greg@kroah.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2. + * + */ + +#include +#include +#include +#include +#include +#include +#include + + +#define DRIVER_AUTHOR "Harrison Metzger " +#define DRIVER_DESC "USB 7 Segment Driver" + +#define VENDOR_ID 0x0fc5 +#define PRODUCT_ID 0x1227 +#define MAXLEN 6 + +/* table of devices that work with this driver */ +static struct usb_device_id id_table[] = { + { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, + { }, +}; +MODULE_DEVICE_TABLE(usb, id_table); + +/* the different text display modes the device is capable of */ +static char *display_textmodes[] = {"raw", "hex", "ascii", NULL}; + +struct usb_sevsegdev { + struct usb_device *udev; + + u8 powered; + u8 mode_msb; + u8 mode_lsb; + u8 decimals[MAXLEN]; + u8 textmode; + u8 text[MAXLEN]; + u16 textlength; +}; + +/* sysfs_streq can't replace this completely + * If the device was in hex mode, and the user wanted a 0, + * if str commands are used, we would assume the end of string + * so mem commands are used. + */ +inline size_t my_memlen(const char *buf, size_t count) +{ + if (count > 0 && buf[count-1] == '\n') + return count - 1; + else + return count; +} + +static void update_display_powered(struct usb_sevsegdev *mydev) +{ + int rc; + + rc = usb_control_msg(mydev->udev, + usb_sndctrlpipe(mydev->udev, 0), + 0x12, + 0x48, + (80 * 0x100) + 10, /* (power mode) */ + (0x00 * 0x100) + (mydev->powered ? 1 : 0), + NULL, + 0, + 2000); + if (rc < 0) + dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc); +} + +static void update_display_mode(struct usb_sevsegdev *mydev) +{ + int rc; + + rc = usb_control_msg(mydev->udev, + usb_sndctrlpipe(mydev->udev, 0), + 0x12, + 0x48, + (82 * 0x100) + 10, /* (set mode) */ + (mydev->mode_msb * 0x100) + mydev->mode_lsb, + NULL, + 0, + 2000); + + if (rc < 0) + dev_dbg(&mydev->udev->dev, "mode retval = %d\n", rc); +} + +static void update_display_visual(struct usb_sevsegdev *mydev) +{ + int rc; + int i; + unsigned char *buffer; + u8 decimals = 0; + + buffer = kzalloc(MAXLEN, GFP_KERNEL); + if (!buffer) { + dev_err(&mydev->udev->dev, "out of memory\n"); + return; + } + + /* The device is right to left, where as you write left to right */ + for (i = 0; i < mydev->textlength; i++) + buffer[i] = mydev->text[mydev->textlength-1-i]; + + rc = usb_control_msg(mydev->udev, + usb_sndctrlpipe(mydev->udev, 0), + 0x12, + 0x48, + (85 * 0x100) + 10, /* (write text) */ + (0 * 0x100) + mydev->textmode, /* mode */ + buffer, + mydev->textlength, + 2000); + + if (rc < 0) + dev_dbg(&mydev->udev->dev, "write retval = %d\n", rc); + + kfree(buffer); + + /* The device is right to left, where as you write left to right */ + for (i = 0; i < sizeof(mydev->decimals); i++) + decimals |= mydev->decimals[i] << i; + + rc = usb_control_msg(mydev->udev, + usb_sndctrlpipe(mydev->udev, 0), + 0x12, + 0x48, + (86 * 0x100) + 10, /* (set decimal) */ + (0 * 0x100) + decimals, /* decimals */ + NULL, + 0, + 2000); + + if (rc < 0) + dev_dbg(&mydev->udev->dev, "decimal retval = %d\n", rc); +} + +#define MYDEV_ATTR_SIMPLE_UNSIGNED(name, update_fcn) \ +static ssize_t show_attr_##name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct usb_interface *intf = to_usb_interface(dev); \ + struct usb_sevsegdev *mydev = usb_get_intfdata(intf); \ + \ + return sprintf(buf, "%u\n", mydev->name); \ +} \ + \ +static ssize_t set_attr_##name(struct device *dev, \ + struct device_attribute *attr, const char *buf, size_t count) \ +{ \ + struct usb_interface *intf = to_usb_interface(dev); \ + struct usb_sevsegdev *mydev = usb_get_intfdata(intf); \ + \ + mydev->name = simple_strtoul(buf, NULL, 10); \ + update_fcn(mydev); \ + \ + return count; \ +} \ +static DEVICE_ATTR(name, S_IWUGO | S_IRUGO, show_attr_##name, set_attr_##name); + +static ssize_t show_attr_text(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usb_sevsegdev *mydev = usb_get_intfdata(intf); + + return snprintf(buf, mydev->textlength, "%s\n", mydev->text); +} + +static ssize_t set_attr_text(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usb_sevsegdev *mydev = usb_get_intfdata(intf); + size_t end = my_memlen(buf, count); + + if (end > sizeof(mydev->text)) + return -EINVAL; + + memset(mydev->text, 0, sizeof(mydev->text)); + mydev->textlength = end; + + if (end > 0) + memcpy(mydev->text, buf, end); + + update_display_visual(mydev); + return count; +} + +static DEVICE_ATTR(text, S_IWUGO | S_IRUGO, show_attr_text, set_attr_text); + +static ssize_t show_attr_decimals(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usb_sevsegdev *mydev = usb_get_intfdata(intf); + int i; + int pos; + + for (i = 0; i < sizeof(mydev->decimals); i++) { + pos = sizeof(mydev->decimals) - 1 - i; + if (mydev->decimals[i] == 0) + buf[pos] = '0'; + else if (mydev->decimals[i] == 1) + buf[pos] = '1'; + else + buf[pos] = 'x'; + } + + buf[sizeof(mydev->decimals)] = '\n'; + return sizeof(mydev->decimals) + 1; +} + +static ssize_t set_attr_decimals(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usb_sevsegdev *mydev = usb_get_intfdata(intf); + size_t end = my_memlen(buf, count); + int i; + + if (end > sizeof(mydev->decimals)) + return -EINVAL; + + for (i = 0; i < end; i++) + if (buf[i] != '0' && buf[i] != '1') + return -EINVAL; + + memset(mydev->decimals, 0, sizeof(mydev->decimals)); + for (i = 0; i < end; i++) + if (buf[i] == '1') + mydev->decimals[end-1-i] = 1; + + update_display_visual(mydev); + + return count; +} + +static DEVICE_ATTR(decimals, S_IWUGO | S_IRUGO, + show_attr_decimals, set_attr_decimals); + +static ssize_t show_attr_textmode(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usb_sevsegdev *mydev = usb_get_intfdata(intf); + int i; + + buf[0] = 0; + + for (i = 0; display_textmodes[i]; i++) { + if (mydev->textmode == i) { + strcat(buf, " ["); + strcat(buf, display_textmodes[i]); + strcat(buf, "] "); + } else { + strcat(buf, " "); + strcat(buf, display_textmodes[i]); + strcat(buf, " "); + } + } + strcat(buf, "\n"); + + + return strlen(buf); +} + +static ssize_t set_attr_textmode(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usb_sevsegdev *mydev = usb_get_intfdata(intf); + int i; + + for (i = 0; display_textmodes[i]; i++) { + if (sysfs_streq(display_textmodes[i], buf)) { + mydev->textmode = i; + update_display_visual(mydev); + return count; + } + } + + return -EINVAL; +} + +static DEVICE_ATTR(textmode, S_IWUGO | S_IRUGO, + show_attr_textmode, set_attr_textmode); + + +MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered); +MYDEV_ATTR_SIMPLE_UNSIGNED(mode_msb, update_display_mode); +MYDEV_ATTR_SIMPLE_UNSIGNED(mode_lsb, update_display_mode); + +static struct attribute *dev_attrs[] = { + &dev_attr_powered.attr, + &dev_attr_text.attr, + &dev_attr_textmode.attr, + &dev_attr_decimals.attr, + &dev_attr_mode_msb.attr, + &dev_attr_mode_lsb.attr, + NULL +}; + +static struct attribute_group dev_attr_grp = { + .attrs = dev_attrs, +}; + +static int sevseg_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(interface); + struct usb_sevsegdev *mydev = NULL; + int rc = -ENOMEM; + + mydev = kzalloc(sizeof(struct usb_sevsegdev), GFP_KERNEL); + if (mydev == NULL) { + dev_err(&interface->dev, "Out of memory\n"); + goto error_mem; + } + + mydev->udev = usb_get_dev(udev); + usb_set_intfdata(interface, mydev); + + /*set defaults */ + mydev->textmode = 0x02; /* ascii mode */ + mydev->mode_msb = 0x06; /* 6 characters */ + mydev->mode_lsb = 0x3f; /* scanmode for 6 chars */ + + rc = sysfs_create_group(&interface->dev.kobj, &dev_attr_grp); + if (rc) + goto error; + + dev_info(&interface->dev, "USB 7 Segment device now attached\n"); + return 0; + +error: + usb_set_intfdata(interface, NULL); + usb_put_dev(mydev->udev); + kfree(mydev); +error_mem: + return rc; +} + +static void sevseg_disconnect(struct usb_interface *interface) +{ + struct usb_sevsegdev *mydev; + + mydev = usb_get_intfdata(interface); + sysfs_remove_group(&interface->dev.kobj, &dev_attr_grp); + usb_set_intfdata(interface, NULL); + usb_put_dev(mydev->udev); + kfree(mydev); + dev_info(&interface->dev, "USB 7 Segment now disconnected\n"); +} + +static struct usb_driver sevseg_driver = { + .name = "usbsevseg", + .probe = sevseg_probe, + .disconnect = sevseg_disconnect, + .id_table = id_table, +}; + +static int __init usb_sevseg_init(void) +{ + int rc = 0; + + rc = usb_register(&sevseg_driver); + if (rc) + err("usb_register failed. Error number %d", rc); + return rc; +} + +static void __exit usb_sevseg_exit(void) +{ + usb_deregister(&sevseg_driver); +} + +module_init(usb_sevseg_init); +module_exit(usb_sevseg_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 5b775f672cc993ba9dba5626811ab1f2ac42883b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 26 Aug 2008 16:22:06 -0700 Subject: USB: add USB test and measurement class driver This driver was originaly written by Stefan Kopp, but massively reworked by Greg for submission. Thanks to Felipe Balbi for lots of work in cleaning up this driver. Thanks to Oliver Neukum for reviewing previous versions and pointing out problems. Cc: Stefan Kopp Cc: Marcel Janssen Cc: Felipe Balbi Cc: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/stable/sysfs-driver-usb-usbtmc | 62 ++ Documentation/devices.txt | 3 + Documentation/ioctl-number.txt | 2 + drivers/usb/class/Kconfig | 10 + drivers/usb/class/Makefile | 1 + drivers/usb/class/usbtmc.c | 1087 ++++++++++++++++++++++ include/linux/usb/Kbuild | 2 +- include/linux/usb/tmc.h | 43 + 8 files changed, 1209 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/stable/sysfs-driver-usb-usbtmc create mode 100644 drivers/usb/class/usbtmc.c create mode 100644 include/linux/usb/tmc.h diff --git a/Documentation/ABI/stable/sysfs-driver-usb-usbtmc b/Documentation/ABI/stable/sysfs-driver-usb-usbtmc new file mode 100644 index 000000000000..9a75fb22187d --- /dev/null +++ b/Documentation/ABI/stable/sysfs-driver-usb-usbtmc @@ -0,0 +1,62 @@ +What: /sys/bus/usb/drivers/usbtmc/devices/*/interface_capabilities +What: /sys/bus/usb/drivers/usbtmc/devices/*/device_capabilities +Date: August 2008 +Contact: Greg Kroah-Hartman +Description: + These files show the various USB TMC capabilities as described + by the device itself. The full description of the bitfields + can be found in the USB TMC documents from the USB-IF entitled + "Universal Serial Bus Test and Measurement Class Specification + (USBTMC) Revision 1.0" section 4.2.1.8. + + The files are read only. + + +What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_interface_capabilities +What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_device_capabilities +Date: August 2008 +Contact: Greg Kroah-Hartman +Description: + These files show the various USB TMC capabilities as described + by the device itself. The full description of the bitfields + can be found in the USB TMC documents from the USB-IF entitled + "Universal Serial Bus Test and Measurement Class, Subclass + USB488 Specification (USBTMC-USB488) Revision 1.0" section + 4.2.2. + + The files are read only. + + +What: /sys/bus/usb/drivers/usbtmc/devices/*/TermChar +Date: August 2008 +Contact: Greg Kroah-Hartman +Description: + This file is the TermChar value to be sent to the USB TMC + device as described by the document, "Universal Serial Bus Test + and Measurement Class Specification + (USBTMC) Revision 1.0" as published by the USB-IF. + + Note that the TermCharEnabled file determines if this value is + sent to the device or not. + + +What: /sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled +Date: August 2008 +Contact: Greg Kroah-Hartman +Description: + This file determines if the TermChar is to be sent to the + device on every transaction or not. For more details about + this, please see the document, "Universal Serial Bus Test and + Measurement Class Specification (USBTMC) Revision 1.0" as + published by the USB-IF. + + +What: /sys/bus/usb/drivers/usbtmc/devices/*/auto_abort +Date: August 2008 +Contact: Greg Kroah-Hartman +Description: + This file determines if the the transaction of the USB TMC + device is to be automatically aborted if there is any error. + For more details about this, please see the document, + "Universal Serial Bus Test and Measurement Class Specification + (USBTMC) Revision 1.0" as published by the USB-IF. diff --git a/Documentation/devices.txt b/Documentation/devices.txt index 05c80645e4ee..2be08240ee80 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -2571,6 +2571,9 @@ Your cooperation is appreciated. 160 = /dev/usb/legousbtower0 1st USB Legotower device ... 175 = /dev/usb/legousbtower15 16th USB Legotower device + 176 = /dev/usb/usbtmc1 First USB TMC device + ... + 192 = /dev/usb/usbtmc16 16th USB TMC device 240 = /dev/usb/dabusb0 First daubusb device ... 243 = /dev/usb/dabusb3 Fourth dabusb device diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt index 1c6b545635a2..f8deb85eef6e 100644 --- a/Documentation/ioctl-number.txt +++ b/Documentation/ioctl-number.txt @@ -110,6 +110,8 @@ Code Seq# Include File Comments 'W' 00-1F linux/wanrouter.h conflict! 'X' all linux/xfs_fs.h 'Y' all linux/cyclades.h +'[' 00-07 linux/usb/usbtmc.h USB Test and Measurement Devices + 'a' all ATM on linux 'b' 00-FF bit3 vme host bridge diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig index 66f17ed88cb5..2519e320098f 100644 --- a/drivers/usb/class/Kconfig +++ b/drivers/usb/class/Kconfig @@ -40,3 +40,13 @@ config USB_WDM To compile this driver as a module, choose M here: the module will be called cdc-wdm. +config USB_TMC + tristate "USB Test and Measurement Class support" + depends on USB + help + Say Y here if you want to connect a USB device that follows + the USB.org specification for USB Test and Measurement devices + to your computer's USB port. + + To compile this driver as a module, choose M here: the + module will be called usbtmc. diff --git a/drivers/usb/class/Makefile b/drivers/usb/class/Makefile index 535d59a30600..32e85277b5cf 100644 --- a/drivers/usb/class/Makefile +++ b/drivers/usb/class/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_USB_ACM) += cdc-acm.o obj-$(CONFIG_USB_PRINTER) += usblp.o obj-$(CONFIG_USB_WDM) += cdc-wdm.o +obj-$(CONFIG_USB_TMC) += usbtmc.o diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c new file mode 100644 index 000000000000..543811f6e6e8 --- /dev/null +++ b/drivers/usb/class/usbtmc.c @@ -0,0 +1,1087 @@ +/** + * drivers/usb/class/usbtmc.c - USB Test & Measurment class driver + * + * Copyright (C) 2007 Stefan Kopp, Gechingen, Germany + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 Greg Kroah-Hartman + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * The GNU General Public License is available at + * http://www.gnu.org/copyleft/gpl.html. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define USBTMC_MINOR_BASE 176 + +/* + * Size of driver internal IO buffer. Must be multiple of 4 and at least as + * large as wMaxPacketSize (which is usually 512 bytes). + */ +#define USBTMC_SIZE_IOBUFFER 2048 + +/* Default USB timeout (in milliseconds) */ +#define USBTMC_TIMEOUT 10 + +/* + * Maximum number of read cycles to empty bulk in endpoint during CLEAR and + * ABORT_BULK_IN requests. Ends the loop if (for whatever reason) a short + * packet is never read. + */ +#define USBTMC_MAX_READS_TO_CLEAR_BULK_IN 100 + +static struct usb_device_id usbtmc_devices[] = { + { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), }, + { 0, } /* terminating entry */ +}; + +/* + * This structure is the capabilities for the device + * See section 4.2.1.8 of the USBTMC specification for details. + */ +struct usbtmc_dev_capabilities { + __u8 interface_capabilities; + __u8 device_capabilities; + __u8 usb488_interface_capabilities; + __u8 usb488_device_capabilities; +}; + +/* This structure holds private data for each USBTMC device. One copy is + * allocated for each USBTMC device in the driver's probe function. + */ +struct usbtmc_device_data { + const struct usb_device_id *id; + struct usb_device *usb_dev; + struct usb_interface *intf; + + unsigned int bulk_in; + unsigned int bulk_out; + + u8 bTag; + u8 bTag_last_write; /* needed for abort */ + u8 bTag_last_read; /* needed for abort */ + + /* attributes from the USB TMC spec for this device */ + u8 TermChar; + bool TermCharEnabled; + bool auto_abort; + + struct usbtmc_dev_capabilities capabilities; + struct kref kref; + struct mutex io_mutex; /* only one i/o function running at a time */ +}; +#define to_usbtmc_data(d) container_of(d, struct usbtmc_device_data, kref) + +/* Forward declarations */ +static struct usb_driver usbtmc_driver; + +static void usbtmc_delete(struct kref *kref) +{ + struct usbtmc_device_data *data = to_usbtmc_data(kref); + + usb_put_dev(data->usb_dev); + kfree(data); +} + +static int usbtmc_open(struct inode *inode, struct file *filp) +{ + struct usb_interface *intf; + struct usbtmc_device_data *data; + int retval = -ENODEV; + + intf = usb_find_interface(&usbtmc_driver, iminor(inode)); + if (!intf) { + printk(KERN_ERR KBUILD_MODNAME + ": can not find device for minor %d", iminor(inode)); + goto exit; + } + + data = usb_get_intfdata(intf); + kref_get(&data->kref); + + /* Store pointer in file structure's private data field */ + filp->private_data = data; + +exit: + return retval; +} + +static int usbtmc_release(struct inode *inode, struct file *file) +{ + struct usbtmc_device_data *data = file->private_data; + + kref_put(&data->kref, usbtmc_delete); + return 0; +} + +static int usbtmc_ioctl_abort_bulk_in(struct usbtmc_device_data *data) +{ + char *buffer; + struct device *dev; + int rv; + int n; + int actual; + struct usb_host_interface *current_setting; + int max_size; + + dev = &data->intf->dev; + buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + rv = usb_control_msg(data->usb_dev, + usb_rcvctrlpipe(data->usb_dev, 0), + USBTMC_REQUEST_INITIATE_ABORT_BULK_IN, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, + data->bTag_last_read, data->bulk_in, + buffer, 2, USBTMC_TIMEOUT); + + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", rv); + goto exit; + } + + dev_dbg(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]); + + if (buffer[0] == USBTMC_STATUS_FAILED) { + rv = 0; + goto exit; + } + + if (buffer[0] != USBTMC_STATUS_SUCCESS) { + dev_err(dev, "INITIATE_ABORT_BULK_IN returned %x\n", + buffer[0]); + rv = -EPERM; + goto exit; + } + + max_size = 0; + current_setting = data->intf->cur_altsetting; + for (n = 0; n < current_setting->desc.bNumEndpoints; n++) + if (current_setting->endpoint[n].desc.bEndpointAddress == + data->bulk_in) + max_size = le16_to_cpu(current_setting->endpoint[n]. + desc.wMaxPacketSize); + + if (max_size == 0) { + dev_err(dev, "Couldn't get wMaxPacketSize\n"); + rv = -EPERM; + goto exit; + } + + dev_dbg(&data->intf->dev, "wMaxPacketSize is %d\n", max_size); + + n = 0; + + do { + dev_dbg(dev, "Reading from bulk in EP\n"); + + rv = usb_bulk_msg(data->usb_dev, + usb_rcvbulkpipe(data->usb_dev, + data->bulk_in), + buffer, USBTMC_SIZE_IOBUFFER, + &actual, USBTMC_TIMEOUT); + + n++; + + if (rv < 0) { + dev_err(dev, "usb_bulk_msg returned %d\n", rv); + goto exit; + } + } while ((actual == max_size) && + (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); + + if (actual == max_size) { + dev_err(dev, "Couldn't clear device buffer within %d cycles\n", + USBTMC_MAX_READS_TO_CLEAR_BULK_IN); + rv = -EPERM; + goto exit; + } + + n = 0; + +usbtmc_abort_bulk_in_status: + rv = usb_control_msg(data->usb_dev, + usb_rcvctrlpipe(data->usb_dev, 0), + USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, + 0, data->bulk_in, buffer, 0x08, + USBTMC_TIMEOUT); + + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", rv); + goto exit; + } + + dev_dbg(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]); + + if (buffer[0] == USBTMC_STATUS_SUCCESS) { + rv = 0; + goto exit; + } + + if (buffer[0] != USBTMC_STATUS_PENDING) { + dev_err(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]); + rv = -EPERM; + goto exit; + } + + if (buffer[1] == 1) + do { + dev_dbg(dev, "Reading from bulk in EP\n"); + + rv = usb_bulk_msg(data->usb_dev, + usb_rcvbulkpipe(data->usb_dev, + data->bulk_in), + buffer, USBTMC_SIZE_IOBUFFER, + &actual, USBTMC_TIMEOUT); + + n++; + + if (rv < 0) { + dev_err(dev, "usb_bulk_msg returned %d\n", rv); + goto exit; + } + } while ((actual = max_size) && + (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); + + if (actual == max_size) { + dev_err(dev, "Couldn't clear device buffer within %d cycles\n", + USBTMC_MAX_READS_TO_CLEAR_BULK_IN); + rv = -EPERM; + goto exit; + } + + goto usbtmc_abort_bulk_in_status; + +exit: + kfree(buffer); + return rv; + +} + +static int usbtmc_ioctl_abort_bulk_out(struct usbtmc_device_data *data) +{ + struct device *dev; + u8 *buffer; + int rv; + int n; + + dev = &data->intf->dev; + + buffer = kmalloc(8, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + rv = usb_control_msg(data->usb_dev, + usb_rcvctrlpipe(data->usb_dev, 0), + USBTMC_REQUEST_INITIATE_ABORT_BULK_OUT, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, + data->bTag_last_write, data->bulk_out, + buffer, 2, USBTMC_TIMEOUT); + + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", rv); + goto exit; + } + + dev_dbg(dev, "INITIATE_ABORT_BULK_OUT returned %x\n", buffer[0]); + + if (buffer[0] != USBTMC_STATUS_SUCCESS) { + dev_err(dev, "INITIATE_ABORT_BULK_OUT returned %x\n", + buffer[0]); + rv = -EPERM; + goto exit; + } + + n = 0; + +usbtmc_abort_bulk_out_check_status: + rv = usb_control_msg(data->usb_dev, + usb_rcvctrlpipe(data->usb_dev, 0), + USBTMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, + 0, data->bulk_out, buffer, 0x08, + USBTMC_TIMEOUT); + n++; + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", rv); + goto exit; + } + + dev_dbg(dev, "CHECK_ABORT_BULK_OUT returned %x\n", buffer[0]); + + if (buffer[0] == USBTMC_STATUS_SUCCESS) + goto usbtmc_abort_bulk_out_clear_halt; + + if ((buffer[0] == USBTMC_STATUS_PENDING) && + (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)) + goto usbtmc_abort_bulk_out_check_status; + + rv = -EPERM; + goto exit; + +usbtmc_abort_bulk_out_clear_halt: + rv = usb_control_msg(data->usb_dev, + usb_sndctrlpipe(data->usb_dev, 0), + USB_REQ_CLEAR_FEATURE, + USB_DIR_OUT | USB_TYPE_STANDARD | + USB_RECIP_ENDPOINT, + USB_ENDPOINT_HALT, data->bulk_out, buffer, + 0, USBTMC_TIMEOUT); + + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", rv); + goto exit; + } + rv = 0; + +exit: + kfree(buffer); + return rv; +} + +static ssize_t usbtmc_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + struct usbtmc_device_data *data; + struct device *dev; + unsigned long int n_characters; + u8 *buffer; + int actual; + int done; + int remaining; + int retval; + int this_part; + + /* Get pointer to private data structure */ + data = filp->private_data; + dev = &data->intf->dev; + + buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + mutex_lock(&data->io_mutex); + + remaining = count; + done = 0; + + while (remaining > 0) { + if (remaining > USBTMC_SIZE_IOBUFFER - 12 - 3) + this_part = USBTMC_SIZE_IOBUFFER - 12 - 3; + else + this_part = remaining; + + /* Setup IO buffer for DEV_DEP_MSG_IN message + * Refer to class specs for details + */ + buffer[0] = 2; + buffer[1] = data->bTag; + buffer[2] = ~(data->bTag); + buffer[3] = 0; /* Reserved */ + buffer[4] = (this_part - 12 - 3) & 255; + buffer[5] = ((this_part - 12 - 3) >> 8) & 255; + buffer[6] = ((this_part - 12 - 3) >> 16) & 255; + buffer[7] = ((this_part - 12 - 3) >> 24) & 255; + buffer[8] = data->TermCharEnabled * 2; + /* Use term character? */ + buffer[9] = data->TermChar; + buffer[10] = 0; /* Reserved */ + buffer[11] = 0; /* Reserved */ + + /* Send bulk URB */ + retval = usb_bulk_msg(data->usb_dev, + usb_sndbulkpipe(data->usb_dev, + data->bulk_out), + buffer, 12, &actual, USBTMC_TIMEOUT); + + /* Store bTag (in case we need to abort) */ + data->bTag_last_write = data->bTag; + + /* Increment bTag -- and increment again if zero */ + data->bTag++; + if (!data->bTag) + (data->bTag)++; + + if (retval < 0) { + dev_err(dev, "usb_bulk_msg returned %d\n", retval); + if (data->auto_abort) + usbtmc_ioctl_abort_bulk_out(data); + goto exit; + } + + /* Send bulk URB */ + retval = usb_bulk_msg(data->usb_dev, + usb_rcvbulkpipe(data->usb_dev, + data->bulk_in), + buffer, USBTMC_SIZE_IOBUFFER, &actual, + USBTMC_TIMEOUT); + + /* Store bTag (in case we need to abort) */ + data->bTag_last_read = data->bTag; + + if (retval < 0) { + dev_err(dev, "Unable to read data, error %d\n", retval); + if (data->auto_abort) + usbtmc_ioctl_abort_bulk_in(data); + goto exit; + } + + /* How many characters did the instrument send? */ + n_characters = buffer[4] + + (buffer[5] << 8) + + (buffer[6] << 16) + + (buffer[7] << 24); + + /* Copy buffer to user space */ + if (copy_to_user(buf + done, &buffer[12], n_characters)) { + /* There must have been an addressing problem */ + retval = -EFAULT; + goto exit; + } + + done += n_characters; + if (n_characters < USBTMC_SIZE_IOBUFFER) + remaining = 0; + } + + /* Update file position value */ + *f_pos = *f_pos + done; + retval = done; + +exit: + mutex_unlock(&data->io_mutex); + kfree(buffer); + return retval; +} + +static ssize_t usbtmc_write(struct file *filp, const char __user *buf, + size_t count, loff_t *f_pos) +{ + struct usbtmc_device_data *data; + u8 *buffer; + int retval; + int actual; + unsigned long int n_bytes; + int n; + int remaining; + int done; + int this_part; + + data = filp->private_data; + + buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + mutex_lock(&data->io_mutex); + + remaining = count; + done = 0; + + while (remaining > 0) { + if (remaining > USBTMC_SIZE_IOBUFFER - 12) { + this_part = USBTMC_SIZE_IOBUFFER - 12; + buffer[8] = 0; + } else { + this_part = remaining; + buffer[8] = 1; + } + + /* Setup IO buffer for DEV_DEP_MSG_OUT message */ + buffer[0] = 1; + buffer[1] = data->bTag; + buffer[2] = ~(data->bTag); + buffer[3] = 0; /* Reserved */ + buffer[4] = this_part & 255; + buffer[5] = (this_part >> 8) & 255; + buffer[6] = (this_part >> 16) & 255; + buffer[7] = (this_part >> 24) & 255; + /* buffer[8] is set above... */ + buffer[9] = 0; /* Reserved */ + buffer[10] = 0; /* Reserved */ + buffer[11] = 0; /* Reserved */ + + if (copy_from_user(&buffer[12], buf + done, this_part)) { + retval = -EFAULT; + goto exit; + } + + n_bytes = 12 + this_part; + if (this_part % 4) + n_bytes += 4 - this_part % 4; + for (n = 12 + this_part; n < n_bytes; n++) + buffer[n] = 0; + + retval = usb_bulk_msg(data->usb_dev, + usb_sndbulkpipe(data->usb_dev, + data->bulk_out), + buffer, n_bytes, &actual, USBTMC_TIMEOUT); + + data->bTag_last_write = data->bTag; + data->bTag++; + + if (!data->bTag) + data->bTag++; + + if (retval < 0) { + dev_err(&data->intf->dev, + "Unable to send data, error %d\n", retval); + if (data->auto_abort) + usbtmc_ioctl_abort_bulk_out(data); + goto exit; + } + + remaining -= this_part; + done += this_part; + } + + retval = count; +exit: + mutex_unlock(&data->io_mutex); + kfree(buffer); + return retval; +} + +static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) +{ + struct usb_host_interface *current_setting; + struct usb_endpoint_descriptor *desc; + struct device *dev; + u8 *buffer; + int rv; + int n; + int actual; + int max_size; + + dev = &data->intf->dev; + + dev_dbg(dev, "Sending INITIATE_CLEAR request\n"); + + buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + rv = usb_control_msg(data->usb_dev, + usb_rcvctrlpipe(data->usb_dev, 0), + USBTMC_REQUEST_INITIATE_CLEAR, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, 0, buffer, 1, USBTMC_TIMEOUT); + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", rv); + goto exit; + } + + dev_dbg(dev, "INITIATE_CLEAR returned %x\n", buffer[0]); + + if (buffer[0] != USBTMC_STATUS_SUCCESS) { + dev_err(dev, "INITIATE_CLEAR returned %x\n", buffer[0]); + rv = -EPERM; + goto exit; + } + + max_size = 0; + current_setting = data->intf->cur_altsetting; + for (n = 0; n < current_setting->desc.bNumEndpoints; n++) { + desc = ¤t_setting->endpoint[n].desc; + if (desc->bEndpointAddress == data->bulk_in) + max_size = le16_to_cpu(desc->wMaxPacketSize); + } + + if (max_size == 0) { + dev_err(dev, "Couldn't get wMaxPacketSize\n"); + rv = -EPERM; + goto exit; + } + + dev_dbg(dev, "wMaxPacketSize is %d\n", max_size); + + n = 0; + +usbtmc_clear_check_status: + + dev_dbg(dev, "Sending CHECK_CLEAR_STATUS request\n"); + + rv = usb_control_msg(data->usb_dev, + usb_rcvctrlpipe(data->usb_dev, 0), + USBTMC_REQUEST_CHECK_CLEAR_STATUS, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, 0, buffer, 2, USBTMC_TIMEOUT); + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", rv); + goto exit; + } + + dev_dbg(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]); + + if (buffer[0] == USBTMC_STATUS_SUCCESS) + goto usbtmc_clear_bulk_out_halt; + + if (buffer[0] != USBTMC_STATUS_PENDING) { + dev_err(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]); + rv = -EPERM; + goto exit; + } + + if (buffer[1] == 1) + do { + dev_dbg(dev, "Reading from bulk in EP\n"); + + rv = usb_bulk_msg(data->usb_dev, + usb_rcvbulkpipe(data->usb_dev, + data->bulk_in), + buffer, USBTMC_SIZE_IOBUFFER, + &actual, USBTMC_TIMEOUT); + n++; + + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", + rv); + goto exit; + } + } while ((actual == max_size) && + (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); + + if (actual == max_size) { + dev_err(dev, "Couldn't clear device buffer within %d cycles\n", + USBTMC_MAX_READS_TO_CLEAR_BULK_IN); + rv = -EPERM; + goto exit; + } + + goto usbtmc_clear_check_status; + +usbtmc_clear_bulk_out_halt: + + rv = usb_control_msg(data->usb_dev, + usb_sndctrlpipe(data->usb_dev, 0), + USB_REQ_CLEAR_FEATURE, + USB_DIR_OUT | USB_TYPE_STANDARD | + USB_RECIP_ENDPOINT, + USB_ENDPOINT_HALT, + data->bulk_out, buffer, 0, + USBTMC_TIMEOUT); + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", rv); + goto exit; + } + rv = 0; + +exit: + kfree(buffer); + return rv; +} + +static int usbtmc_ioctl_clear_out_halt(struct usbtmc_device_data *data) +{ + u8 *buffer; + int rv; + + buffer = kmalloc(2, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + rv = usb_control_msg(data->usb_dev, + usb_sndctrlpipe(data->usb_dev, 0), + USB_REQ_CLEAR_FEATURE, + USB_DIR_OUT | USB_TYPE_STANDARD | + USB_RECIP_ENDPOINT, + USB_ENDPOINT_HALT, data->bulk_out, + buffer, 0, USBTMC_TIMEOUT); + + if (rv < 0) { + dev_err(&data->usb_dev->dev, "usb_control_msg returned %d\n", + rv); + goto exit; + } + rv = 0; + +exit: + kfree(buffer); + return rv; +} + +static int usbtmc_ioctl_clear_in_halt(struct usbtmc_device_data *data) +{ + u8 *buffer; + int rv; + + buffer = kmalloc(2, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + rv = usb_control_msg(data->usb_dev, usb_sndctrlpipe(data->usb_dev, 0), + USB_REQ_CLEAR_FEATURE, + USB_DIR_OUT | USB_TYPE_STANDARD | + USB_RECIP_ENDPOINT, + USB_ENDPOINT_HALT, data->bulk_in, buffer, 0, + USBTMC_TIMEOUT); + + if (rv < 0) { + dev_err(&data->usb_dev->dev, "usb_control_msg returned %d\n", + rv); + goto exit; + } + rv = 0; + +exit: + kfree(buffer); + return rv; +} + +static int get_capabilities(struct usbtmc_device_data *data) +{ + struct device *dev = &data->usb_dev->dev; + char *buffer; + int rv; + + buffer = kmalloc(0x18, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + rv = usb_control_msg(data->usb_dev, usb_rcvctrlpipe(data->usb_dev, 0), + USBTMC_REQUEST_GET_CAPABILITIES, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, 0, buffer, 0x18, USBTMC_TIMEOUT); + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", rv); + return rv; + } + + dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); + dev_dbg(dev, "Interface capabilities are %x\n", buffer[4]); + dev_dbg(dev, "Device capabilities are %x\n", buffer[5]); + dev_dbg(dev, "USB488 interface capabilities are %x\n", buffer[14]); + dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); + if (buffer[0] != USBTMC_STATUS_SUCCESS) { + dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); + return -EPERM; + } + + data->capabilities.interface_capabilities = buffer[4]; + data->capabilities.device_capabilities = buffer[5]; + data->capabilities.usb488_interface_capabilities = buffer[14]; + data->capabilities.usb488_device_capabilities = buffer[15]; + + kfree(buffer); + return 0; +} + +#define capability_attribute(name) \ +static ssize_t show_##name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct usb_interface *intf = to_usb_interface(dev); \ + struct usbtmc_device_data *data = usb_get_intfdata(intf); \ + \ + return sprintf(buf, "%d\n", data->capabilities.name); \ +} \ +static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) + +capability_attribute(interface_capabilities); +capability_attribute(device_capabilities); +capability_attribute(usb488_interface_capabilities); +capability_attribute(usb488_device_capabilities); + +static struct attribute *capability_attrs[] = { + &dev_attr_interface_capabilities.attr, + &dev_attr_device_capabilities.attr, + &dev_attr_usb488_interface_capabilities.attr, + &dev_attr_usb488_device_capabilities.attr, + NULL, +}; + +static struct attribute_group capability_attr_grp = { + .attrs = capability_attrs, +}; + +static ssize_t show_TermChar(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usbtmc_device_data *data = usb_get_intfdata(intf); + + return sprintf(buf, "%c\n", data->TermChar); +} + +static ssize_t store_TermChar(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usbtmc_device_data *data = usb_get_intfdata(intf); + + if (count < 1) + return -EINVAL; + data->TermChar = buf[0]; + return count; +} +static DEVICE_ATTR(TermChar, S_IRUGO, show_TermChar, store_TermChar); + +#define data_attribute(name) \ +static ssize_t show_##name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct usb_interface *intf = to_usb_interface(dev); \ + struct usbtmc_device_data *data = usb_get_intfdata(intf); \ + \ + return sprintf(buf, "%d\n", data->name); \ +} \ +static ssize_t store_##name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct usb_interface *intf = to_usb_interface(dev); \ + struct usbtmc_device_data *data = usb_get_intfdata(intf); \ + ssize_t result; \ + unsigned val; \ + \ + result = sscanf(buf, "%u\n", &val); \ + if (result != 1) \ + result = -EINVAL; \ + data->name = val; \ + if (result < 0) \ + return result; \ + else \ + return count; \ +} \ +static DEVICE_ATTR(name, S_IRUGO, show_##name, store_##name) + +data_attribute(TermCharEnabled); +data_attribute(auto_abort); + +static struct attribute *data_attrs[] = { + &dev_attr_TermChar.attr, + &dev_attr_TermCharEnabled.attr, + &dev_attr_auto_abort.attr, + NULL, +}; + +static struct attribute_group data_attr_grp = { + .attrs = data_attrs, +}; + +static int usbtmc_ioctl_indicator_pulse(struct usbtmc_device_data *data) +{ + struct device *dev; + u8 *buffer; + int rv; + + dev = &data->intf->dev; + + buffer = kmalloc(2, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + rv = usb_control_msg(data->usb_dev, + usb_rcvctrlpipe(data->usb_dev, 0), + USBTMC_REQUEST_INDICATOR_PULSE, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, 0, buffer, 0x01, USBTMC_TIMEOUT); + + if (rv < 0) { + dev_err(dev, "usb_control_msg returned %d\n", rv); + goto exit; + } + + dev_dbg(dev, "INDICATOR_PULSE returned %x\n", buffer[0]); + + if (buffer[0] != USBTMC_STATUS_SUCCESS) { + dev_err(dev, "INDICATOR_PULSE returned %x\n", buffer[0]); + rv = -EPERM; + goto exit; + } + rv = 0; + +exit: + kfree(buffer); + return rv; +} + +static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct usbtmc_device_data *data; + int retval = -EBADRQC; + + data = file->private_data; + mutex_lock(&data->io_mutex); + + switch (cmd) { + case USBTMC_IOCTL_CLEAR_OUT_HALT: + retval = usbtmc_ioctl_clear_out_halt(data); + + case USBTMC_IOCTL_CLEAR_IN_HALT: + retval = usbtmc_ioctl_clear_in_halt(data); + + case USBTMC_IOCTL_INDICATOR_PULSE: + retval = usbtmc_ioctl_indicator_pulse(data); + + case USBTMC_IOCTL_CLEAR: + retval = usbtmc_ioctl_clear(data); + + case USBTMC_IOCTL_ABORT_BULK_OUT: + retval = usbtmc_ioctl_abort_bulk_out(data); + + case USBTMC_IOCTL_ABORT_BULK_IN: + retval = usbtmc_ioctl_abort_bulk_in(data); + } + + mutex_unlock(&data->io_mutex); + return retval; +} + +static struct file_operations fops = { + .owner = THIS_MODULE, + .read = usbtmc_read, + .write = usbtmc_write, + .open = usbtmc_open, + .release = usbtmc_release, + .unlocked_ioctl = usbtmc_ioctl, +}; + +static struct usb_class_driver usbtmc_class = { + .name = "usbtmc%d", + .fops = &fops, + .minor_base = USBTMC_MINOR_BASE, +}; + + +static int usbtmc_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usbtmc_device_data *data; + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + int n; + int retcode; + + dev_dbg(&intf->dev, "%s called\n", __func__); + + data = kmalloc(sizeof(struct usbtmc_device_data), GFP_KERNEL); + if (!data) { + dev_err(&intf->dev, "Unable to allocate kernel memory\n"); + return -ENOMEM; + } + + data->intf = intf; + data->id = id; + data->usb_dev = usb_get_dev(interface_to_usbdev(intf)); + usb_set_intfdata(intf, data); + kref_init(&data->kref); + mutex_init(&data->io_mutex); + + /* Initialize USBTMC bTag and other fields */ + data->bTag = 1; + data->TermCharEnabled = 0; + data->TermChar = '\n'; + + /* USBTMC devices have only one setting, so use that */ + iface_desc = data->intf->cur_altsetting; + + /* Find bulk in endpoint */ + for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) { + endpoint = &iface_desc->endpoint[n].desc; + + if (usb_endpoint_is_bulk_in(endpoint)) { + data->bulk_in = endpoint->bEndpointAddress; + dev_dbg(&intf->dev, "Found bulk in endpoint at %u\n", + data->bulk_in); + break; + } + } + + /* Find bulk out endpoint */ + for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) { + endpoint = &iface_desc->endpoint[n].desc; + + if (usb_endpoint_is_bulk_out(endpoint)) { + data->bulk_out = endpoint->bEndpointAddress; + dev_dbg(&intf->dev, "Found Bulk out endpoint at %u\n", + data->bulk_out); + break; + } + } + + retcode = get_capabilities(data); + if (retcode) + dev_err(&intf->dev, "can't read capabilities\n"); + else + retcode = sysfs_create_group(&intf->dev.kobj, + &capability_attr_grp); + + retcode = sysfs_create_group(&intf->dev.kobj, &data_attr_grp); + + retcode = usb_register_dev(intf, &usbtmc_class); + if (retcode) { + dev_err(&intf->dev, "Not able to get a minor" + " (base %u, slice default): %d\n", USBTMC_MINOR_BASE, + retcode); + goto error_register; + } + dev_dbg(&intf->dev, "Using minor number %d\n", intf->minor); + + return 0; + +error_register: + sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp); + sysfs_remove_group(&intf->dev.kobj, &data_attr_grp); + kref_put(&data->kref, usbtmc_delete); + return retcode; +} + +static void usbtmc_disconnect(struct usb_interface *intf) +{ + struct usbtmc_device_data *data; + + dev_dbg(&intf->dev, "usbtmc_disconnect called\n"); + + data = usb_get_intfdata(intf); + usb_deregister_dev(intf, &usbtmc_class); + sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp); + sysfs_remove_group(&intf->dev.kobj, &data_attr_grp); + kref_put(&data->kref, usbtmc_delete); +} + +static struct usb_driver usbtmc_driver = { + .name = "usbtmc", + .id_table = usbtmc_devices, + .probe = usbtmc_probe, + .disconnect = usbtmc_disconnect +}; + +static int __init usbtmc_init(void) +{ + int retcode; + + retcode = usb_register(&usbtmc_driver); + if (retcode) + printk(KERN_ERR KBUILD_MODNAME": Unable to register driver\n"); + return retcode; +} +module_init(usbtmc_init); + +static void __exit usbtmc_exit(void) +{ + usb_deregister(&usbtmc_driver); +} +module_exit(usbtmc_exit); + +MODULE_LICENSE("GPL"); diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild index 42e84fc315e3..29fd73b0bffc 100644 --- a/include/linux/usb/Kbuild +++ b/include/linux/usb/Kbuild @@ -4,4 +4,4 @@ header-y += ch9.h header-y += gadgetfs.h header-y += midi.h header-y += g_printer.h - +header-y += tmc.h diff --git a/include/linux/usb/tmc.h b/include/linux/usb/tmc.h new file mode 100644 index 000000000000..c045ae12556c --- /dev/null +++ b/include/linux/usb/tmc.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007 Stefan Kopp, Gechingen, Germany + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 Greg Kroah-Hartman + * + * This file holds USB constants defined by the USB Device Class + * Definition for Test and Measurement devices published by the USB-IF. + * + * It also has the ioctl definitions for the usbtmc kernel driver that + * userspace needs to know about. + */ + +#ifndef __LINUX_USB_TMC_H +#define __LINUX_USB_TMC_H + +/* USB TMC status values */ +#define USBTMC_STATUS_SUCCESS 0x01 +#define USBTMC_STATUS_PENDING 0x02 +#define USBTMC_STATUS_FAILED 0x80 +#define USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS 0x81 +#define USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS 0x82 +#define USBTMC_STATUS_SPLIT_IN_PROGRESS 0x83 + +/* USB TMC requests values */ +#define USBTMC_REQUEST_INITIATE_ABORT_BULK_OUT 1 +#define USBTMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS 2 +#define USBTMC_REQUEST_INITIATE_ABORT_BULK_IN 3 +#define USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS 4 +#define USBTMC_REQUEST_INITIATE_CLEAR 5 +#define USBTMC_REQUEST_CHECK_CLEAR_STATUS 6 +#define USBTMC_REQUEST_GET_CAPABILITIES 7 +#define USBTMC_REQUEST_INDICATOR_PULSE 64 + +/* Request values for USBTMC driver's ioctl entry point */ +#define USBTMC_IOC_NR 91 +#define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR, 1) +#define USBTMC_IOCTL_CLEAR _IO(USBTMC_IOC_NR, 2) +#define USBTMC_IOCTL_ABORT_BULK_OUT _IO(USBTMC_IOC_NR, 3) +#define USBTMC_IOCTL_ABORT_BULK_IN _IO(USBTMC_IOC_NR, 4) +#define USBTMC_IOCTL_CLEAR_OUT_HALT _IO(USBTMC_IOC_NR, 6) +#define USBTMC_IOCTL_CLEAR_IN_HALT _IO(USBTMC_IOC_NR, 7) + +#endif -- cgit v1.2.3 From 49b707b90c7f7260beb8691fc5d99d71a5549ec0 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 16 Jul 2008 18:00:42 +0200 Subject: drivers/usb/class/usblp.c: adjust error handling code In this code, it is possible to tell statically whether usblp will be NULL in the error handling code. Oliver Neukum suggested to make a goto to the final return rather than return directly. The semantic match that finds this problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @@ identifier f,err,l,l1; type T; expression x,E; statement S; @@ x = NULL ... when != goto l1; * x = f(...) ... when != x err = E; goto l; ... * if (x != NULL) S return err; // Signed-off-by: Julia Lawall Cc: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usblp.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 0647164d36db..68a2239cd0b6 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -1076,15 +1076,16 @@ static int usblp_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev (intf); - struct usblp *usblp = NULL; + struct usblp *usblp; int protocol; int retval; /* Malloc and start initializing usblp structure so we can use it * directly. */ - if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) { + usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL); + if (!usblp) { retval = -ENOMEM; - goto abort; + goto abort_ret; } usblp->dev = dev; mutex_init(&usblp->wmut); @@ -1179,12 +1180,11 @@ abort_intfdata: usb_set_intfdata (intf, NULL); device_remove_file(&intf->dev, &dev_attr_ieee1284_id); abort: - if (usblp) { - kfree(usblp->readbuf); - kfree(usblp->statusbuf); - kfree(usblp->device_id_string); - kfree(usblp); - } + kfree(usblp->readbuf); + kfree(usblp->statusbuf); + kfree(usblp->device_id_string); + kfree(usblp); +abort_ret: return retval; } -- cgit v1.2.3 From 55b447bf79ad25591437d24b78caa9d0ae4fec82 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 29 Jul 2008 15:26:15 +0200 Subject: USB: kill URBs permanently looking at usb_kill_urb() it seems to me that it is unnecessarily lenient. In the use case of disconnect() you never want to use the URB again (for the same device) But leaving urb->reject elevated will make it easier to avoid races between read/write and disconnect. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/urb.c | 56 ++++++++++++++++++++++++++++++++++++++++++++------ include/linux/usb.h | 2 ++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 47111e88f791..a7945ab208c2 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -522,6 +522,7 @@ int usb_unlink_urb(struct urb *urb) } EXPORT_SYMBOL_GPL(usb_unlink_urb); +static DEFINE_MUTEX(usb_reject_mutex); /** * usb_kill_urb - cancel a transfer request and wait for it to finish * @urb: pointer to URB describing a previously submitted request, @@ -544,24 +545,67 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb); */ void usb_kill_urb(struct urb *urb) { - static DEFINE_MUTEX(reject_mutex); - might_sleep(); if (!(urb && urb->dev && urb->ep)) return; - mutex_lock(&reject_mutex); + mutex_lock(&usb_reject_mutex); ++urb->reject; - mutex_unlock(&reject_mutex); + mutex_unlock(&usb_reject_mutex); usb_hcd_unlink_urb(urb, -ENOENT); wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); - mutex_lock(&reject_mutex); + mutex_lock(&usb_reject_mutex); --urb->reject; - mutex_unlock(&reject_mutex); + mutex_unlock(&usb_reject_mutex); } EXPORT_SYMBOL_GPL(usb_kill_urb); +/** + * usb_poison_urb - reliably kill a transfer and prevent further use of an URB + * @urb: pointer to URB describing a previously submitted request, + * may be NULL + * + * This routine cancels an in-progress request. It is guaranteed that + * upon return all completion handlers will have finished and the URB + * will be totally idle and cannot be reused. These features make + * this an ideal way to stop I/O in a disconnect() callback. + * If the request has not already finished or been unlinked + * the completion handler will see urb->status == -ENOENT. + * + * After and while the routine runs, attempts to resubmit the URB will fail + * with error -EPERM. Thus even if the URB's completion handler always + * tries to resubmit, it will not succeed and the URB will become idle. + * + * This routine may not be used in an interrupt context (such as a bottom + * half or a completion handler), or when holding a spinlock, or in other + * situations where the caller can't schedule(). + */ +void usb_poison_urb(struct urb *urb) +{ + might_sleep(); + if (!(urb && urb->dev && urb->ep)) + return; + mutex_lock(&usb_reject_mutex); + ++urb->reject; + mutex_unlock(&usb_reject_mutex); + + usb_hcd_unlink_urb(urb, -ENOENT); + wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); +} +EXPORT_SYMBOL_GPL(usb_poison_urb); + +void usb_unpoison_urb(struct urb *urb) +{ + if (!urb) + return; + + mutex_lock(&usb_reject_mutex); + --urb->reject; + mutex_unlock(&usb_reject_mutex); +} +EXPORT_SYMBOL_GPL(usb_unpoison_urb); + /** * usb_kill_anchored_urbs - cancel transfer requests en masse * @anchor: anchor the requests are bound to diff --git a/include/linux/usb.h b/include/linux/usb.h index 94ac74aba6b6..3371c91e7ff4 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1459,6 +1459,8 @@ extern struct urb *usb_get_urb(struct urb *urb); extern int usb_submit_urb(struct urb *urb, gfp_t mem_flags); extern int usb_unlink_urb(struct urb *urb); extern void usb_kill_urb(struct urb *urb); +extern void usb_poison_urb(struct urb *urb); +extern void usb_unpoison_urb(struct urb *urb); extern void usb_kill_anchored_urbs(struct usb_anchor *anchor); extern void usb_unlink_anchored_urbs(struct usb_anchor *anchor); extern void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor); -- cgit v1.2.3 From 6a2839bedc1502b3f0366cc3ad1099a1d92cf8fb Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 29 Jul 2008 16:18:47 +0200 Subject: USB: extend poisoning to anchors this extends the poisoning concept to anchors. This way poisoning will work with fire and forget drivers. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/urb.c | 57 ++++++++++++++++++++++++++++++++++++++++++-------- include/linux/usb.h | 2 ++ 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index a7945ab208c2..eebc070c3cc7 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -10,6 +10,8 @@ #define to_urb(d) container_of(d, struct urb, kref) +static DEFINE_SPINLOCK(usb_reject_lock); + static void urb_destroy(struct kref *kref) { struct urb *urb = to_urb(kref); @@ -127,6 +129,13 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor) usb_get_urb(urb); list_add_tail(&urb->anchor_list, &anchor->urb_list); urb->anchor = anchor; + + if (unlikely(anchor->poisoned)) { + spin_lock(&usb_reject_lock); + urb->reject++; + spin_unlock(&usb_reject_lock); + } + spin_unlock_irqrestore(&anchor->lock, flags); } EXPORT_SYMBOL_GPL(usb_anchor_urb); @@ -522,7 +531,6 @@ int usb_unlink_urb(struct urb *urb) } EXPORT_SYMBOL_GPL(usb_unlink_urb); -static DEFINE_MUTEX(usb_reject_mutex); /** * usb_kill_urb - cancel a transfer request and wait for it to finish * @urb: pointer to URB describing a previously submitted request, @@ -548,16 +556,16 @@ void usb_kill_urb(struct urb *urb) might_sleep(); if (!(urb && urb->dev && urb->ep)) return; - mutex_lock(&usb_reject_mutex); + spin_lock_irq(&usb_reject_lock); ++urb->reject; - mutex_unlock(&usb_reject_mutex); + spin_unlock_irq(&usb_reject_lock); usb_hcd_unlink_urb(urb, -ENOENT); wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); - mutex_lock(&usb_reject_mutex); + spin_lock_irq(&usb_reject_lock); --urb->reject; - mutex_unlock(&usb_reject_mutex); + spin_unlock_irq(&usb_reject_lock); } EXPORT_SYMBOL_GPL(usb_kill_urb); @@ -586,9 +594,9 @@ void usb_poison_urb(struct urb *urb) might_sleep(); if (!(urb && urb->dev && urb->ep)) return; - mutex_lock(&usb_reject_mutex); + spin_lock_irq(&usb_reject_lock); ++urb->reject; - mutex_unlock(&usb_reject_mutex); + spin_unlock_irq(&usb_reject_lock); usb_hcd_unlink_urb(urb, -ENOENT); wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); @@ -597,12 +605,14 @@ EXPORT_SYMBOL_GPL(usb_poison_urb); void usb_unpoison_urb(struct urb *urb) { + unsigned long flags; + if (!urb) return; - mutex_lock(&usb_reject_mutex); + spin_lock_irqsave(&usb_reject_lock, flags); --urb->reject; - mutex_unlock(&usb_reject_mutex); + spin_unlock_irqrestore(&usb_reject_lock, flags); } EXPORT_SYMBOL_GPL(usb_unpoison_urb); @@ -633,6 +643,35 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor) } EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs); + +/** + * usb_poison_anchored_urbs - cease all traffic from an anchor + * @anchor: anchor the requests are bound to + * + * this allows all outstanding URBs to be poisoned starting + * from the back of the queue. Newly added URBs will also be + * poisoned + */ +void usb_poison_anchored_urbs(struct usb_anchor *anchor) +{ + struct urb *victim; + + spin_lock_irq(&anchor->lock); + anchor->poisoned = 1; + while (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.prev, struct urb, + anchor_list); + /* we must make sure the URB isn't freed before we kill it*/ + usb_get_urb(victim); + spin_unlock_irq(&anchor->lock); + /* this will unanchor the URB */ + usb_poison_urb(victim); + usb_put_urb(victim); + spin_lock_irq(&anchor->lock); + } + spin_unlock_irq(&anchor->lock); +} +EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs); /** * usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse * @anchor: anchor the requests are bound to diff --git a/include/linux/usb.h b/include/linux/usb.h index 3371c91e7ff4..d97927970f54 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1135,6 +1135,7 @@ struct usb_anchor { struct list_head urb_list; wait_queue_head_t wait; spinlock_t lock; + unsigned int poisoned:1; }; static inline void init_usb_anchor(struct usb_anchor *anchor) @@ -1462,6 +1463,7 @@ extern void usb_kill_urb(struct urb *urb); extern void usb_poison_urb(struct urb *urb); extern void usb_unpoison_urb(struct urb *urb); extern void usb_kill_anchored_urbs(struct usb_anchor *anchor); +extern void usb_poison_anchored_urbs(struct usb_anchor *anchor); extern void usb_unlink_anchored_urbs(struct usb_anchor *anchor); extern void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor); extern void usb_unanchor_urb(struct urb *urb); -- cgit v1.2.3 From 7dbcbe88b1495f778f56c742391e49f580dc101a Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Mon, 4 Aug 2008 17:15:40 -0600 Subject: ub: remove sg_stat Remove forgotten code related to sg_stat[]. Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/block/ub.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 3a281ef11ffa..f60e41833f69 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -349,8 +349,6 @@ struct ub_dev { struct work_struct reset_work; wait_queue_head_t reset_wait; - - int sg_stat[6]; }; /* @@ -685,7 +683,6 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) goto drop; } urq->nsg = n_elem; - sc->sg_stat[n_elem < 5 ? n_elem : 5]++; if (blk_pc_request(rq)) { ub_cmd_build_packet(sc, lun, cmd, urq); -- cgit v1.2.3 From 27140219373327f2291da5d74a78db0105b15060 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 18 Aug 2008 13:08:42 +0200 Subject: USB: Let some USB host controllers get IRQ flags from resource [This version fixes a thinko in the r8a66597 driver] This patch let a few discrete USB host controllers drivers (isp116x-hcd, r8a66597-hcd and sl811-hcd) obtain IRQ flags from their IORESOURCE_IRQ resource if configured as such, much like it's been done for the smc91x driver. It spares people writing support for specific boards the burden to configure the interrupt controller independantly, and keeps all IRQ related information in a single resource. HCD that are integrally part of a SoC have been left aside, as there is probably no "wiring" options... Tested on an Xscale PXA-255 based platform with isp116x-hcd. Signed-off-by: Marc Zyngier Cc: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp116x-hcd.c | 13 +++++++++---- drivers/usb/host/r8a66597-hcd.c | 41 ++++++++++++++++++++++++++++++++--------- drivers/usb/host/sl811-hcd.c | 15 +++++++++++---- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index ce1ca0ba0515..4dda31b26892 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1562,11 +1562,12 @@ static int __devinit isp116x_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct isp116x *isp116x; - struct resource *addr, *data; + struct resource *addr, *data, *ires; void __iomem *addr_reg; void __iomem *data_reg; int irq; int ret = 0; + unsigned long irqflags; if (pdev->num_resources < 3) { ret = -ENODEV; @@ -1575,12 +1576,16 @@ static int __devinit isp116x_probe(struct platform_device *pdev) data = platform_get_resource(pdev, IORESOURCE_MEM, 0); addr = platform_get_resource(pdev, IORESOURCE_MEM, 1); - irq = platform_get_irq(pdev, 0); - if (!addr || !data || irq < 0) { + ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + + if (!addr || !data || !ires) { ret = -ENODEV; goto err1; } + irq = ires->start; + irqflags = ires->flags & IRQF_TRIGGER_MASK; + if (pdev->dev.dma_mask) { DBG("DMA not supported\n"); ret = -EINVAL; @@ -1634,7 +1639,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev) goto err6; } - ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); + ret = usb_add_hcd(hcd, irq, irqflags | IRQF_DISABLED); if (ret) goto err6; diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index ea7126f99cab..3a45ad275b41 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -66,7 +66,7 @@ static unsigned short endian; module_param(endian, ushort, 0644); MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); -static unsigned short irq_sense = INTL; +static unsigned short irq_sense = 0xff; module_param(irq_sense, ushort, 0644); MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 " "(default=32)"); @@ -2263,7 +2263,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev) #define resource_len(r) (((r)->end - (r)->start) + 1) static int __init r8a66597_probe(struct platform_device *pdev) { - struct resource *res = NULL; + struct resource *res = NULL, *ires; int irq = -1; void __iomem *reg = NULL; struct usb_hcd *hcd = NULL; @@ -2286,13 +2286,16 @@ static int __init r8a66597_probe(struct platform_device *pdev) goto clean_up; } - irq = platform_get_irq(pdev, 0); - if (irq < 0) { + ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!ires) { ret = -ENODEV; - err("platform_get_irq error."); + err("platform_get_resource IORESOURCE_IRQ error."); goto clean_up; } + irq = ires->start; + irq_trigger = ires->flags & IRQF_TRIGGER_MASK; + reg = ioremap(res->start, resource_len(res)); if (reg == NULL) { ret = -ENOMEM; @@ -2329,10 +2332,30 @@ static int __init r8a66597_probe(struct platform_device *pdev) INIT_LIST_HEAD(&r8a66597->child_device); hcd->rsrc_start = res->start; - if (irq_sense == INTL) - irq_trigger = IRQF_TRIGGER_LOW; - else - irq_trigger = IRQF_TRIGGER_FALLING; + + /* irq_sense setting on cmdline takes precedence over resource + * settings, so the introduction of irqflags in IRQ resourse + * won't disturb existing setups */ + switch (irq_sense) { + case INTL: + irq_trigger = IRQF_TRIGGER_LOW; + break; + case 0: + irq_trigger = IRQF_TRIGGER_FALLING; + break; + case 0xff: + if (irq_trigger) + irq_sense = (irq_trigger & IRQF_TRIGGER_LOW) ? + INTL : 0; + else { + irq_sense = INTL; + irq_trigger = IRQF_TRIGGER_LOW; + } + break; + default: + err("Unknown irq_sense value."); + } + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger); if (ret != 0) { err("Failed to add hcd"); diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 8a74bbb57d08..e106e9d48d4a 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1620,22 +1620,26 @@ sl811h_probe(struct platform_device *dev) { struct usb_hcd *hcd; struct sl811 *sl811; - struct resource *addr, *data; + struct resource *addr, *data, *ires; int irq; void __iomem *addr_reg; void __iomem *data_reg; int retval; u8 tmp, ioaddr = 0; + unsigned long irqflags; /* basic sanity checks first. board-specific init logic should * have initialized these three resources and probably board * specific platform_data. we don't probe for IRQs, and do only * minimal sanity checking. */ - irq = platform_get_irq(dev, 0); - if (dev->num_resources < 3 || irq < 0) + ires = platform_get_resource(dev, IORESOURCE_IRQ, 0); + if (dev->num_resources < 3 || !ires) return -ENODEV; + irq = ires->start; + irqflags = ires->flags & IRQF_TRIGGER_MASK; + /* refuse to confuse usbcore */ if (dev->dev.dma_mask) { DBG("no we won't dma\n"); @@ -1717,8 +1721,11 @@ sl811h_probe(struct platform_device *dev) * triggers (e.g. most ARM CPUs). Initial driver stress testing * was on a system with single edge triggering, so most sorts of * triggering arrangement should work. + * + * Use resource IRQ flags if set by platform device setup. */ - retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); + irqflags |= IRQF_SHARED; + retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | irqflags); if (retval != 0) goto err6; -- cgit v1.2.3 From a7a19fac8a9fbc0182fb1b464848a31529c39433 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 14 Aug 2008 17:04:48 -0700 Subject: usb: gadget Kconfig cleanup This reorders the list of USB peripheral controller drivers so it's more common for the initial (default) value to be relevant: put the SOC integrated silicon up front, discrete stuff last. Alphabetize. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 265 ++++++++++++++++++++++++--------------------- 1 file changed, 144 insertions(+), 121 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index acc95b2ac6f8..5dda2dc708db 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -85,6 +85,13 @@ config USB_GADGET_SELECTED # # USB Peripheral Controller Support # +# The order here is alphabetical, except that integrated controllers go +# before discrete ones so they will be the initial/default value: +# - integrated/SOC controllers first +# - licensed IP used in both SOC and discrete versions +# - discrete ones (including all PCI-only controllers) +# - debug/dummy gadget+hcd is last. +# choice prompt "USB Peripheral Controller" depends on USB_GADGET @@ -94,26 +101,27 @@ choice Many controller drivers are platform-specific; these often need board-specific hooks. -config USB_GADGET_AMD5536UDC - boolean "AMD5536 UDC" - depends on PCI - select USB_GADGET_DUALSPEED +# +# Integrated controllers +# + +config USB_GADGET_AT91 + boolean "Atmel AT91 USB Device Port" + depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 + select USB_GADGET_SELECTED help - The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. - It is a USB Highspeed DMA capable USB device controller. Beside ep0 - it provides 4 IN and 4 OUT endpoints (bulk or interrupt type). - The UDC port supports OTG operation, and may be used as a host port - if it's not being used to implement peripheral or OTG roles. + Many Atmel AT91 processors (such as the AT91RM2000) have a + full speed USB Device Port with support for five configurable + endpoints (plus endpoint zero). Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "amd5536udc" and force all + dynamically linked module called "at91_udc" and force all gadget drivers to also be dynamically linked. -config USB_AMD5536UDC +config USB_AT91 tristate - depends on USB_GADGET_AMD5536UDC + depends on USB_GADGET_AT91 default USB_GADGET - select USB_GADGET_SELECTED config USB_GADGET_ATMEL_USBA boolean "Atmel USBA" @@ -150,28 +158,50 @@ config USB_FSL_USB2 default USB_GADGET select USB_GADGET_SELECTED -config USB_GADGET_NET2280 - boolean "NetChip 228x" - depends on PCI - select USB_GADGET_DUALSPEED +config USB_GADGET_LH7A40X + boolean "LH7A40X" + depends on ARCH_LH7A40X help - NetChip 2280 / 2282 is a PCI based USB peripheral controller which - supports both full and high speed USB 2.0 data transfers. - - It has six configurable endpoints, as well as endpoint zero - (for control transfers) and several endpoints with dedicated - functions. + This driver provides USB Device Controller driver for LH7A40x + +config USB_LH7A40X + tristate + depends on USB_GADGET_LH7A40X + default USB_GADGET + select USB_GADGET_SELECTED + +config USB_GADGET_OMAP + boolean "OMAP USB Device Controller" + depends on ARCH_OMAP + select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 + help + Many Texas Instruments OMAP processors have flexible full + speed USB device controllers, with support for up to 30 + endpoints (plus endpoint zero). This driver supports the + controller in the OMAP 1611, and should work with controllers + in other OMAP processors too, given minor tweaks. Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "net2280" and force all + dynamically linked module called "omap_udc" and force all gadget drivers to also be dynamically linked. -config USB_NET2280 +config USB_OMAP tristate - depends on USB_GADGET_NET2280 + depends on USB_GADGET_OMAP default USB_GADGET select USB_GADGET_SELECTED +config USB_OTG + boolean "OTG Support" + depends on USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD + help + The most notable feature of USB OTG is support for a + "Dual-Role" device, which can act as either a device + or a host. The initial role choice can be changed + later, when two dual-role devices talk to each other. + + Select this only if your OMAP board has a Mini-AB connector. + config USB_GADGET_PXA25X boolean "PXA 25x or IXP 4xx" depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX @@ -203,34 +233,6 @@ config USB_PXA25X_SMALL default y if USB_ETH default y if USB_G_SERIAL -config USB_GADGET_M66592 - boolean "Renesas M66592 USB Peripheral Controller" - select USB_GADGET_DUALSPEED - help - M66592 is a discrete USB peripheral controller chip that - supports both full and high speed USB 2.0 data transfers. - It has seven configurable endpoints, and endpoint zero. - - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "m66592_udc" and force all - gadget drivers to also be dynamically linked. - -config USB_M66592 - tristate - depends on USB_GADGET_M66592 - default USB_GADGET - select USB_GADGET_SELECTED - -config SUPERH_BUILT_IN_M66592 - boolean "Enable SuperH built-in USB like the M66592" - depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722 - help - SH7722 has USB like the M66592. - - The transfer rate is very slow when use "Ethernet Gadget". - However, this problem is improved if change a value of - NET_IP_ALIGN to 4. - config USB_GADGET_PXA27X boolean "PXA 27x" depends on ARCH_PXA && PXA27x @@ -251,40 +253,32 @@ config USB_PXA27X default USB_GADGET select USB_GADGET_SELECTED -config USB_GADGET_GOKU - boolean "Toshiba TC86C001 'Goku-S'" - depends on PCI +config USB_GADGET_S3C2410 + boolean "S3C2410 USB Device Controller" + depends on ARCH_S3C2410 help - The Toshiba TC86C001 is a PCI device which includes controllers - for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI). - - The device controller has three configurable (bulk or interrupt) - endpoints, plus endpoint zero (for control transfers). + Samsung's S3C2410 is an ARM-4 processor with an integrated + full speed USB 1.1 device controller. It has 4 configurable + endpoints, as well as endpoint zero (for control transfers). - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "goku_udc" and to force all - gadget drivers to also be dynamically linked. + This driver has been tested on the S3C2410, S3C2412, and + S3C2440 processors. -config USB_GOKU +config USB_S3C2410 tristate - depends on USB_GADGET_GOKU + depends on USB_GADGET_S3C2410 default USB_GADGET select USB_GADGET_SELECTED +config USB_S3C2410_DEBUG + boolean "S3C2410 udc debug messages" + depends on USB_GADGET_S3C2410 -config USB_GADGET_LH7A40X - boolean "LH7A40X" - depends on ARCH_LH7A40X - help - This driver provides USB Device Controller driver for LH7A40x - -config USB_LH7A40X - tristate - depends on USB_GADGET_LH7A40X - default USB_GADGET - select USB_GADGET_SELECTED +# +# Controllers available in both integrated and discrete versions +# -# built in ../musb along with host support +# musb builds in ../musb along with host support config USB_GADGET_MUSB_HDRC boolean "Inventra HDRC USB Peripheral (TI, ...)" depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG) @@ -294,76 +288,105 @@ config USB_GADGET_MUSB_HDRC This OTG-capable silicon IP is used in dual designs including the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010. -config USB_GADGET_OMAP - boolean "OMAP USB Device Controller" - depends on ARCH_OMAP - select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 +config USB_GADGET_M66592 + boolean "Renesas M66592 USB Peripheral Controller" + select USB_GADGET_DUALSPEED help - Many Texas Instruments OMAP processors have flexible full - speed USB device controllers, with support for up to 30 - endpoints (plus endpoint zero). This driver supports the - controller in the OMAP 1611, and should work with controllers - in other OMAP processors too, given minor tweaks. + M66592 is a discrete USB peripheral controller chip that + supports both full and high speed USB 2.0 data transfers. + It has seven configurable endpoints, and endpoint zero. Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "omap_udc" and force all + dynamically linked module called "m66592_udc" and force all gadget drivers to also be dynamically linked. -config USB_OMAP +config USB_M66592 tristate - depends on USB_GADGET_OMAP + depends on USB_GADGET_M66592 default USB_GADGET select USB_GADGET_SELECTED -config USB_OTG - boolean "OTG Support" - depends on USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD +config SUPERH_BUILT_IN_M66592 + boolean "Enable SuperH built-in USB like the M66592" + depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722 help - The most notable feature of USB OTG is support for a - "Dual-Role" device, which can act as either a device - or a host. The initial role choice can be changed - later, when two dual-role devices talk to each other. + SH7722 has USB like the M66592. - Select this only if your OMAP board has a Mini-AB connector. + The transfer rate is very slow when use "Ethernet Gadget". + However, this problem is improved if change a value of + NET_IP_ALIGN to 4. -config USB_GADGET_S3C2410 - boolean "S3C2410 USB Device Controller" - depends on ARCH_S3C2410 +# +# Controllers available only in discrete form (and all PCI controllers) +# + +config USB_GADGET_AMD5536UDC + boolean "AMD5536 UDC" + depends on PCI + select USB_GADGET_DUALSPEED help - Samsung's S3C2410 is an ARM-4 processor with an integrated - full speed USB 1.1 device controller. It has 4 configurable - endpoints, as well as endpoint zero (for control transfers). + The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. + It is a USB Highspeed DMA capable USB device controller. Beside ep0 + it provides 4 IN and 4 OUT endpoints (bulk or interrupt type). + The UDC port supports OTG operation, and may be used as a host port + if it's not being used to implement peripheral or OTG roles. - This driver has been tested on the S3C2410, S3C2412, and - S3C2440 processors. + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "amd5536udc" and force all + gadget drivers to also be dynamically linked. -config USB_S3C2410 +config USB_AMD5536UDC tristate - depends on USB_GADGET_S3C2410 + depends on USB_GADGET_AMD5536UDC default USB_GADGET select USB_GADGET_SELECTED -config USB_S3C2410_DEBUG - boolean "S3C2410 udc debug messages" - depends on USB_GADGET_S3C2410 +config USB_GADGET_NET2280 + boolean "NetChip 228x" + depends on PCI + select USB_GADGET_DUALSPEED + help + NetChip 2280 / 2282 is a PCI based USB peripheral controller which + supports both full and high speed USB 2.0 data transfers. -config USB_GADGET_AT91 - boolean "AT91 USB Device Port" - depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 + It has six configurable endpoints, as well as endpoint zero + (for control transfers) and several endpoints with dedicated + functions. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "net2280" and force all + gadget drivers to also be dynamically linked. + +config USB_NET2280 + tristate + depends on USB_GADGET_NET2280 + default USB_GADGET select USB_GADGET_SELECTED + +config USB_GADGET_GOKU + boolean "Toshiba TC86C001 'Goku-S'" + depends on PCI help - Many Atmel AT91 processors (such as the AT91RM2000) have a - full speed USB Device Port with support for five configurable - endpoints (plus endpoint zero). + The Toshiba TC86C001 is a PCI device which includes controllers + for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI). + + The device controller has three configurable (bulk or interrupt) + endpoints, plus endpoint zero (for control transfers). Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "at91_udc" and force all + dynamically linked module called "goku_udc" and to force all gadget drivers to also be dynamically linked. -config USB_AT91 +config USB_GOKU tristate - depends on USB_GADGET_AT91 + depends on USB_GADGET_GOKU default USB_GADGET + select USB_GADGET_SELECTED + + +# +# LAST -- dummy/emulated controller +# config USB_GADGET_DUMMY_HCD boolean "Dummy HCD (DEVELOPMENT)" -- cgit v1.2.3 From 851a526dcf97964265cadcc6664a9f0ff7c143c7 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 14 Aug 2008 15:48:30 -0400 Subject: USB: gadget: dummy_hcd: implement set_wedge This patch (as1131) implements the set_wedge() method for dummy_hcd. This method is necessary for strict USBCV compliance in g_file_storage. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/dummy_hcd.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 7600a0c78753..9064696636ac 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -82,6 +82,7 @@ struct dummy_ep { const struct usb_endpoint_descriptor *desc; struct usb_ep ep; unsigned halted : 1; + unsigned wedged : 1; unsigned already_seen : 1; unsigned setup_stage : 1; }; @@ -436,6 +437,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) /* at this point real hardware should be NAKing transfers * to that endpoint, until a buffer is queued to it. */ + ep->halted = ep->wedged = 0; retval = 0; done: return retval; @@ -597,7 +599,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) } static int -dummy_set_halt (struct usb_ep *_ep, int value) +dummy_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) { struct dummy_ep *ep; struct dummy *dum; @@ -609,16 +611,32 @@ dummy_set_halt (struct usb_ep *_ep, int value) if (!dum->driver) return -ESHUTDOWN; if (!value) - ep->halted = 0; + ep->halted = ep->wedged = 0; else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && !list_empty (&ep->queue)) return -EAGAIN; - else + else { ep->halted = 1; + if (wedged) + ep->wedged = 1; + } /* FIXME clear emulated data toggle too */ return 0; } +static int +dummy_set_halt(struct usb_ep *_ep, int value) +{ + return dummy_set_halt_and_wedge(_ep, value, 0); +} + +static int dummy_set_wedge(struct usb_ep *_ep) +{ + if (!_ep || _ep->name == ep0name) + return -EINVAL; + return dummy_set_halt_and_wedge(_ep, 1, 1); +} + static const struct usb_ep_ops dummy_ep_ops = { .enable = dummy_enable, .disable = dummy_disable, @@ -630,6 +648,7 @@ static const struct usb_ep_ops dummy_ep_ops = { .dequeue = dummy_dequeue, .set_halt = dummy_set_halt, + .set_wedge = dummy_set_wedge, }; /*-------------------------------------------------------------------------*/ @@ -760,7 +779,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) ep->ep.name = ep_name [i]; ep->ep.ops = &dummy_ep_ops; list_add_tail (&ep->ep.ep_list, &dum->gadget.ep_list); - ep->halted = ep->already_seen = ep->setup_stage = 0; + ep->halted = ep->wedged = ep->already_seen = + ep->setup_stage = 0; ep->ep.maxpacket = ~0; ep->last_io = jiffies; ep->gadget = &dum->gadget; @@ -1351,7 +1371,7 @@ restart: } else if (setup.bRequestType == Ep_Request) { // endpoint halt ep2 = find_endpoint (dum, w_index); - if (!ep2) { + if (!ep2 || ep2->ep.name == ep0name) { value = -EOPNOTSUPP; break; } @@ -1380,7 +1400,8 @@ restart: value = -EOPNOTSUPP; break; } - ep2->halted = 0; + if (!ep2->wedged) + ep2->halted = 0; value = 0; status = 0; } -- cgit v1.2.3 From 8066134ff8140ae9d8d15cdad3fc6c60c2a8a4e5 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 14 Aug 2008 15:49:11 -0400 Subject: USB: gadget: net2280: implement set_wedge This patch (as1132) implements the set_wedge() method for net2280. This method is necessary for strict USBCV compliance in g_file_storage. Signed-off-by: Alan Stern CC: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/net2280.c | 40 ++++++++++++++++++++++++++++++++++------ drivers/usb/gadget/net2280.h | 1 + 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 5cfb5ebf3881..8ae70de2c37d 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -178,6 +178,7 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) /* ep_reset() has already been called */ ep->stopped = 0; + ep->wedged = 0; ep->out_overflow = 0; /* set speed-dependent max packet; may kick in high bandwidth */ @@ -1218,7 +1219,7 @@ static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req) static int net2280_fifo_status (struct usb_ep *_ep); static int -net2280_set_halt (struct usb_ep *_ep, int value) +net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) { struct net2280_ep *ep; unsigned long flags; @@ -1239,16 +1240,21 @@ net2280_set_halt (struct usb_ep *_ep, int value) else if (ep->is_in && value && net2280_fifo_status (_ep) != 0) retval = -EAGAIN; else { - VDEBUG (ep->dev, "%s %s halt\n", _ep->name, - value ? "set" : "clear"); + VDEBUG (ep->dev, "%s %s %s\n", _ep->name, + value ? "set" : "clear", + wedged ? "wedge" : "halt"); /* set/clear, then synch memory views with the device */ if (value) { if (ep->num == 0) ep->dev->protocol_stall = 1; else set_halt (ep); - } else + if (wedged) + ep->wedged = 1; + } else { clear_halt (ep); + ep->wedged = 0; + } (void) readl (&ep->regs->ep_rsp); } spin_unlock_irqrestore (&ep->dev->lock, flags); @@ -1256,6 +1262,20 @@ net2280_set_halt (struct usb_ep *_ep, int value) return retval; } +static int +net2280_set_halt(struct usb_ep *_ep, int value) +{ + return net2280_set_halt_and_wedge(_ep, value, 0); +} + +static int +net2280_set_wedge(struct usb_ep *_ep) +{ + if (!_ep || _ep->name == ep0name) + return -EINVAL; + return net2280_set_halt_and_wedge(_ep, 1, 1); +} + static int net2280_fifo_status (struct usb_ep *_ep) { @@ -1302,6 +1322,7 @@ static const struct usb_ep_ops net2280_ep_ops = { .dequeue = net2280_dequeue, .set_halt = net2280_set_halt, + .set_wedge = net2280_set_wedge, .fifo_status = net2280_fifo_status, .fifo_flush = net2280_fifo_flush, }; @@ -2410,9 +2431,14 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) goto do_stall; if ((e = get_ep_by_addr (dev, w_index)) == 0) goto do_stall; - clear_halt (e); + if (e->wedged) { + VDEBUG(dev, "%s wedged, halt not cleared\n", + ep->ep.name); + } else { + VDEBUG(dev, "%s clear halt\n", ep->ep.name); + clear_halt(e); + } allow_status (ep); - VDEBUG (dev, "%s clear halt\n", ep->ep.name); goto next_endpoints; } break; @@ -2427,6 +2453,8 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) goto do_stall; if ((e = get_ep_by_addr (dev, w_index)) == 0) goto do_stall; + if (e->ep.name == ep0name) + goto do_stall; set_halt (e); allow_status (ep); VDEBUG (dev, "%s set halt\n", ep->ep.name); diff --git a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h index 81a71dbdc2c6..c36852263d93 100644 --- a/drivers/usb/gadget/net2280.h +++ b/drivers/usb/gadget/net2280.h @@ -109,6 +109,7 @@ struct net2280_ep { in_fifo_validate : 1, out_overflow : 1, stopped : 1, + wedged : 1, is_in : 1, is_iso : 1, responded : 1; -- cgit v1.2.3 From 60beed95e38793c0baff7f94433c1f639d8d5efd Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 18 Aug 2008 17:38:22 -0700 Subject: usb gadget: function activation/deactivation Add a new mechanism to the composite gadget framework, letting functions deactivate (and reactivate) themselves. Think of it as a refcounted wrapper for the software pullup control. A key example of why to use this mechanism involves functions that require a userspace daemon. Those functions shuld use this new mechanism to prevent the gadget from enumerating until those daemons are activated. Without this mechanism, hosts would see devices that malfunction until the relevant daemons start. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/composite.c | 64 ++++++++++++++++++++++++++++++++++++++++++ include/linux/usb/composite.h | 11 ++++++-- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 85c876c1f150..f79fdb839cb8 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -127,6 +127,70 @@ done: return value; } +/** + * usb_function_deactivate - prevent function and gadget enumeration + * @function: the function that isn't yet ready to respond + * + * Blocks response of the gadget driver to host enumeration by + * preventing the data line pullup from being activated. This is + * normally called during @bind() processing to change from the + * initial "ready to respond" state, or when a required resource + * becomes available. + * + * For example, drivers that serve as a passthrough to a userspace + * daemon can block enumeration unless that daemon (such as an OBEX, + * MTP, or print server) is ready to handle host requests. + * + * Not all systems support software control of their USB peripheral + * data pullups. + * + * Returns zero on success, else negative errno. + */ +int usb_function_deactivate(struct usb_function *function) +{ + struct usb_composite_dev *cdev = function->config->cdev; + int status = 0; + + spin_lock(&cdev->lock); + + if (cdev->deactivations == 0) + status = usb_gadget_disconnect(cdev->gadget); + if (status == 0) + cdev->deactivations++; + + spin_unlock(&cdev->lock); + return status; +} + +/** + * usb_function_activate - allow function and gadget enumeration + * @function: function on which usb_function_activate() was called + * + * Reverses effect of usb_function_deactivate(). If no more functions + * are delaying their activation, the gadget driver will respond to + * host enumeration procedures. + * + * Returns zero on success, else negative errno. + */ +int usb_function_activate(struct usb_function *function) +{ + struct usb_composite_dev *cdev = function->config->cdev; + int status = 0; + + spin_lock(&cdev->lock); + + if (WARN_ON(cdev->deactivations == 0)) + status = -EINVAL; + else { + cdev->deactivations--; + if (cdev->deactivations == 0) + status = usb_gadget_connect(cdev->gadget); + } + + spin_unlock(&cdev->lock); + return status; +} + /** * usb_interface_id() - allocate an unused interface ID * @config: configuration associated with the interface diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index c932390c6da0..935c380ffe47 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -130,6 +130,9 @@ struct usb_function { int usb_add_function(struct usb_configuration *, struct usb_function *); +int usb_function_deactivate(struct usb_function *); +int usb_function_activate(struct usb_function *); + int usb_interface_id(struct usb_configuration *, struct usb_function *); /** @@ -316,9 +319,13 @@ struct usb_composite_dev { struct usb_composite_driver *driver; u8 next_string_id; - spinlock_t lock; + /* the gadget driver won't enable the data pullup + * while the deactivation count is nonzero. + */ + unsigned deactivations; - /* REVISIT use and existence of lock ... */ + /* protects at least deactivation count */ + spinlock_t lock; }; extern int usb_string_id(struct usb_composite_dev *c); -- cgit v1.2.3 From 3086775a4916b0fe128d924d83f4e7d7c39e4d0e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 18 Aug 2008 17:39:30 -0700 Subject: usb gadget: cdc obex glue The following patch introduces a new f_obex.c function driver. It allows userspace obex servers to use usb as transport layer for their messages. [ dbrownell@users.sourceforge.net: various fixes and cleanups ] Signed-off-by: Felipe Balbi Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/gadget.tmpl | 3 + drivers/usb/gadget/Kconfig | 8 +- drivers/usb/gadget/f_obex.c | 446 ++++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/serial.c | 14 ++ drivers/usb/gadget/u_serial.h | 1 + include/linux/usb/cdc.h | 9 + 6 files changed, 479 insertions(+), 2 deletions(-) create mode 100644 drivers/usb/gadget/f_obex.c diff --git a/Documentation/DocBook/gadget.tmpl b/Documentation/DocBook/gadget.tmpl index ea3bc9565e6a..6ef2f0073e5a 100644 --- a/Documentation/DocBook/gadget.tmpl +++ b/Documentation/DocBook/gadget.tmpl @@ -557,6 +557,9 @@ Near-term plans include converting all of them, except for "gadgetfs". !Edrivers/usb/gadget/f_acm.c +!Edrivers/usb/gadget/f_ecm.c +!Edrivers/usb/gadget/f_subset.c +!Edrivers/usb/gadget/f_obex.c !Edrivers/usb/gadget/f_serial.c diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 5dda2dc708db..80a7c02dc951 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -576,19 +576,23 @@ config USB_FILE_STORAGE_TEST normal operation. config USB_G_SERIAL - tristate "Serial Gadget (with CDC ACM support)" + tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" help The Serial Gadget talks to the Linux-USB generic serial driver. This driver supports a CDC-ACM module option, which can be used to interoperate with MS-Windows hosts or with the Linux-USB "cdc-acm" driver. + This driver also supports a CDC-OBEX option. You will need a + user space OBEX server talking to /dev/ttyGS*, since the kernel + itself doesn't implement the OBEX protocol. + Say "y" to link the driver statically, or "m" to build a dynamically linked module called "g_serial". For more information, see Documentation/usb/gadget_serial.txt which includes instructions and a "driver info file" needed to - make MS-Windows work with this driver. + make MS-Windows work with CDC ACM. config USB_MIDI_GADGET tristate "MIDI Gadget (EXPERIMENTAL)" diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c new file mode 100644 index 000000000000..86241b2ca8f4 --- /dev/null +++ b/drivers/usb/gadget/f_obex.c @@ -0,0 +1,446 @@ +/* + * f_obex.c -- USB CDC OBEX function driver + * + * Copyright (C) 2008 Nokia Corporation + * Contact: Felipe Balbi + * + * Based on f_acm.c by Al Borchers and David Brownell. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* #define VERBOSE_DEBUG */ + +#include +#include +#include + +#include "u_serial.h" +#include "gadget_chips.h" + + +/* + * This CDC OBEX function support just packages a TTY-ish byte stream. + * A user mode server will put it into "raw" mode and handle all the + * relevant protocol details ... this is just a kernel passthrough. + * + * REVISIT this driver shouldn't actually activate before that user mode + * server is ready to respond! When the "serial gadget" utility code + * adds open/close notifications, this driver should use them with new + * (TBS) composite gadget hooks that wrap usb_gadget_disconnect() and + * usb_gadget_connect() calls with refcounts ... disconnect() when we + * bind, then connect() when the user server code is ready to respond. + */ + +struct obex_ep_descs { + struct usb_endpoint_descriptor *obex_in; + struct usb_endpoint_descriptor *obex_out; +}; + +struct f_obex { + struct gserial port; + u8 ctrl_id; + u8 data_id; + u8 port_num; + + struct obex_ep_descs fs; + struct obex_ep_descs hs; +}; + +static inline struct f_obex *func_to_obex(struct usb_function *f) +{ + return container_of(f, struct f_obex, port.func); +} + +/*-------------------------------------------------------------------------*/ + +#define OBEX_CTRL_IDX 0 +#define OBEX_DATA_IDX 1 + +static struct usb_string obex_string_defs[] = { + [OBEX_CTRL_IDX].s = "CDC Object Exchange (OBEX)", + [OBEX_DATA_IDX].s = "CDC OBEX Data", + { }, /* end of list */ +}; + +static struct usb_gadget_strings obex_string_table = { + .language = 0x0409, /* en-US */ + .strings = obex_string_defs, +}; + +static struct usb_gadget_strings *obex_strings[] = { + &obex_string_table, + NULL, +}; + +/*-------------------------------------------------------------------------*/ + +static struct usb_interface_descriptor obex_control_intf __initdata = { + .bLength = sizeof(obex_control_intf), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_OBEX, +}; + +static struct usb_interface_descriptor obex_data_nop_intf __initdata = { + .bLength = sizeof(obex_data_nop_intf), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 1, + + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = USB_CLASS_CDC_DATA, +}; + +static struct usb_interface_descriptor obex_data_intf __initdata = { + .bLength = sizeof(obex_data_intf), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 2, + + .bAlternateSetting = 1, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_CDC_DATA, +}; + +static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = { + .bLength = sizeof(obex_cdc_header_desc), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = USB_CDC_HEADER_TYPE, + .bcdCDC = __constant_cpu_to_le16(0x0120), +}; + +static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = { + .bLength = sizeof(obex_cdc_union_desc), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = USB_CDC_UNION_TYPE, + .bMasterInterface0 = 1, + .bSlaveInterface0 = 2, +}; + +static struct usb_cdc_obex_desc obex_desc __initdata = { + .bLength = sizeof(obex_desc), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = USB_CDC_OBEX_TYPE, + .bcdVersion = __constant_cpu_to_le16(0x0100), +}; + +/* High-Speed Support */ + +static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(512), +}; + +static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(512), +}; + +static struct usb_descriptor_header *hs_function[] __initdata = { + (struct usb_descriptor_header *) &obex_control_intf, + (struct usb_descriptor_header *) &obex_cdc_header_desc, + (struct usb_descriptor_header *) &obex_desc, + (struct usb_descriptor_header *) &obex_cdc_union_desc, + + (struct usb_descriptor_header *) &obex_data_nop_intf, + (struct usb_descriptor_header *) &obex_data_intf, + (struct usb_descriptor_header *) &obex_hs_ep_in_desc, + (struct usb_descriptor_header *) &obex_hs_ep_out_desc, + NULL, +}; + +/* Full-Speed Support */ + +static struct usb_endpoint_descriptor obex_fs_ep_in_desc __initdata = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, +}; + +static struct usb_endpoint_descriptor obex_fs_ep_out_desc __initdata = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, +}; + +static struct usb_descriptor_header *fs_function[] __initdata = { + (struct usb_descriptor_header *) &obex_control_intf, + (struct usb_descriptor_header *) &obex_cdc_header_desc, + (struct usb_descriptor_header *) &obex_desc, + (struct usb_descriptor_header *) &obex_cdc_union_desc, + + (struct usb_descriptor_header *) &obex_data_nop_intf, + (struct usb_descriptor_header *) &obex_data_intf, + (struct usb_descriptor_header *) &obex_fs_ep_in_desc, + (struct usb_descriptor_header *) &obex_fs_ep_out_desc, + NULL, +}; + +/*-------------------------------------------------------------------------*/ + +static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt) +{ + struct f_obex *obex = func_to_obex(f); + struct usb_composite_dev *cdev = f->config->cdev; + + if (intf == obex->ctrl_id) { + if (alt != 0) + goto fail; + /* NOP */ + DBG(cdev, "reset obex ttyGS%d control\n", obex->port_num); + + } else if (intf == obex->data_id) { + if (alt > 1) + goto fail; + + if (obex->port.in->driver_data) { + DBG(cdev, "reset obex ttyGS%d\n", obex->port_num); + gserial_disconnect(&obex->port); + } + + if (!obex->port.in_desc) { + DBG(cdev, "init obex ttyGS%d\n", obex->port_num); + obex->port.in_desc = ep_choose(cdev->gadget, + obex->hs.obex_in, obex->fs.obex_in); + obex->port.out_desc = ep_choose(cdev->gadget, + obex->hs.obex_out, obex->fs.obex_out); + } + + if (alt == 1) { + DBG(cdev, "activate obex ttyGS%d\n", obex->port_num); + gserial_connect(&obex->port, obex->port_num); + } + + } else + goto fail; + + return 0; + +fail: + return -EINVAL; +} + +static int obex_get_alt(struct usb_function *f, unsigned intf) +{ + struct f_obex *obex = func_to_obex(f); + + if (intf == obex->ctrl_id) + return 0; + + return obex->port.in->driver_data ? 1 : 0; +} + +static void obex_disable(struct usb_function *f) +{ + struct f_obex *obex = func_to_obex(f); + struct usb_composite_dev *cdev = f->config->cdev; + + DBG(cdev, "obex ttyGS%d disable\n", obex->port_num); + gserial_disconnect(&obex->port); +} + +/*-------------------------------------------------------------------------*/ + +static int __init +obex_bind(struct usb_configuration *c, struct usb_function *f) +{ + struct usb_composite_dev *cdev = c->cdev; + struct f_obex *obex = func_to_obex(f); + int status; + struct usb_ep *ep; + + /* allocate instance-specific interface IDs, and patch descriptors */ + + status = usb_interface_id(c, f); + if (status < 0) + goto fail; + obex->ctrl_id = status; + + obex_control_intf.bInterfaceNumber = status; + obex_cdc_union_desc.bMasterInterface0 = status; + + status = usb_interface_id(c, f); + if (status < 0) + goto fail; + obex->data_id = status; + + obex_data_nop_intf.bInterfaceNumber = status; + obex_data_intf.bInterfaceNumber = status; + obex_cdc_union_desc.bSlaveInterface0 = status; + + /* allocate instance-specific endpoints */ + + ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_in_desc); + if (!ep) + goto fail; + obex->port.in = ep; + ep->driver_data = cdev; /* claim */ + + ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc); + if (!ep) + goto fail; + obex->port.out = ep; + ep->driver_data = cdev; /* claim */ + + /* copy descriptors, and track endpoint copies */ + f->descriptors = usb_copy_descriptors(fs_function); + + obex->fs.obex_in = usb_find_endpoint(fs_function, + f->descriptors, &obex_fs_ep_in_desc); + obex->fs.obex_out = usb_find_endpoint(fs_function, + f->descriptors, &obex_fs_ep_out_desc); + + /* support all relevant hardware speeds... we expect that when + * hardware is dual speed, all bulk-capable endpoints work at + * both speeds + */ + if (gadget_is_dualspeed(c->cdev->gadget)) { + + obex_hs_ep_in_desc.bEndpointAddress = + obex_fs_ep_in_desc.bEndpointAddress; + obex_hs_ep_out_desc.bEndpointAddress = + obex_fs_ep_out_desc.bEndpointAddress; + + /* copy descriptors, and track endpoint copies */ + f->hs_descriptors = usb_copy_descriptors(hs_function); + + obex->hs.obex_in = usb_find_endpoint(hs_function, + f->descriptors, &obex_hs_ep_in_desc); + obex->hs.obex_out = usb_find_endpoint(hs_function, + f->descriptors, &obex_hs_ep_out_desc); + } + + DBG(cdev, "obex ttyGS%d: %s speed IN/%s OUT/%s\n", + obex->port_num, + gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", + obex->port.in->name, obex->port.out->name); + + return 0; + +fail: + /* we might as well release our claims on endpoints */ + if (obex->port.out) + obex->port.out->driver_data = NULL; + if (obex->port.in) + obex->port.in->driver_data = NULL; + + ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); + + return status; +} + +static void +obex_unbind(struct usb_configuration *c, struct usb_function *f) +{ + if (gadget_is_dualspeed(c->cdev->gadget)) + usb_free_descriptors(f->hs_descriptors); + usb_free_descriptors(f->descriptors); + kfree(func_to_obex(f)); +} + +/* Some controllers can't support CDC OBEX ... */ +static inline bool can_support_obex(struct usb_configuration *c) +{ + /* Since the first interface is a NOP, we can ignore the + * issue of multi-interface support on most controllers. + * + * Altsettings are mandatory, however... + */ + if (!gadget_supports_altsettings(c->cdev->gadget)) + return false; + + /* everything else is *probably* fine ... */ + return true; +} + +/** + * obex_bind_config - add a CDC OBEX function to a configuration + * @c: the configuration to support the CDC OBEX instance + * @port_num: /dev/ttyGS* port this interface will use + * Context: single threaded during gadget setup + * + * Returns zero on success, else negative errno. + * + * Caller must have called @gserial_setup() with enough ports to + * handle all the ones it binds. Caller is also responsible + * for calling @gserial_cleanup() before module unload. + */ +int __init obex_bind_config(struct usb_configuration *c, u8 port_num) +{ + struct f_obex *obex; + int status; + + if (!can_support_obex(c)) + return -EINVAL; + + /* maybe allocate device-global string IDs, and patch descriptors */ + if (obex_string_defs[OBEX_CTRL_IDX].id == 0) { + status = usb_string_id(c->cdev); + if (status < 0) + return status; + obex_string_defs[OBEX_CTRL_IDX].id = status; + + obex_control_intf.iInterface = status; + + status = usb_string_id(c->cdev); + if (status < 0) + return status; + obex_string_defs[OBEX_DATA_IDX].id = status; + + obex_data_nop_intf.iInterface = + obex_data_intf.iInterface = status; + } + + /* allocate and initialize one new instance */ + obex = kzalloc(sizeof *obex, GFP_KERNEL); + if (!obex) + return -ENOMEM; + + obex->port_num = port_num; + + obex->port.func.name = "obex"; + obex->port.func.strings = obex_strings; + /* descriptors are per-instance copies */ + obex->port.func.bind = obex_bind; + obex->port.func.unbind = obex_unbind; + obex->port.func.set_alt = obex_set_alt; + obex->port.func.get_alt = obex_get_alt; + obex->port.func.disable = obex_disable; + + status = usb_add_function(c, &obex->port.func); + if (status) + kfree(obex); + + return status; +} + +MODULE_AUTHOR("Felipe Balbi"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 3faa7a7022df..2dee848b2f59 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -43,6 +43,7 @@ #include "epautoconf.c" #include "f_acm.c" +#include "f_obex.c" #include "f_serial.c" #include "u_serial.c" @@ -56,6 +57,7 @@ #define GS_VENDOR_ID 0x0525 /* NetChip */ #define GS_PRODUCT_ID 0xa4a6 /* Linux-USB Serial Gadget */ #define GS_CDC_PRODUCT_ID 0xa4a7 /* ... as CDC-ACM */ +#define GS_CDC_OBEX_PRODUCT_ID 0xa4a9 /* ... as CDC-OBEX */ /* string IDs are assigned dynamically */ @@ -125,6 +127,10 @@ static int use_acm = true; module_param(use_acm, bool, 0); MODULE_PARM_DESC(use_acm, "Use CDC ACM, default=yes"); +static int use_obex = false; +module_param(use_obex, bool, 0); +MODULE_PARM_DESC(use_obex, "Use CDC OBEX, default=no"); + static unsigned n_ports = 1; module_param(n_ports, uint, 0); MODULE_PARM_DESC(n_ports, "number of ports to create, default=1"); @@ -139,6 +145,8 @@ static int __init serial_bind_config(struct usb_configuration *c) for (i = 0; i < n_ports && status == 0; i++) { if (use_acm) status = acm_bind_config(c, i); + else if (use_obex) + status = obex_bind_config(c, i); else status = gser_bind_config(c, i); } @@ -249,6 +257,12 @@ static int __init init(void) device_desc.bDeviceClass = USB_CLASS_COMM; device_desc.idProduct = __constant_cpu_to_le16(GS_CDC_PRODUCT_ID); + } else if (use_obex) { + serial_config_driver.label = "CDC OBEX config"; + serial_config_driver.bConfigurationValue = 3; + device_desc.bDeviceClass = USB_CLASS_COMM; + device_desc.idProduct = + __constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID); } else { serial_config_driver.label = "Generic Serial config"; serial_config_driver.bConfigurationValue = 1; diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/u_serial.h index af3910d01aea..300f0ed9475d 100644 --- a/drivers/usb/gadget/u_serial.h +++ b/drivers/usb/gadget/u_serial.h @@ -62,5 +62,6 @@ void gserial_disconnect(struct gserial *); /* functions are bound to configurations by a config or gadget driver */ int acm_bind_config(struct usb_configuration *c, u8 port_num); int gser_bind_config(struct usb_configuration *c, u8 port_num); +int obex_bind_config(struct usb_configuration *c, u8 port_num); #endif /* __U_SERIAL_H */ diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h index ca228bb94218..18a729343ffa 100644 --- a/include/linux/usb/cdc.h +++ b/include/linux/usb/cdc.h @@ -160,6 +160,15 @@ struct usb_cdc_mdlm_detail_desc { __u8 bDetailData[0]; } __attribute__ ((packed)); +/* "OBEX Control Model Functional Descriptor" */ +struct usb_cdc_obex_desc { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + __le16 bcdVersion; +} __attribute__ ((packed)); + /*-------------------------------------------------------------------------*/ /* -- cgit v1.2.3 From 2121427836c9eeaed3002e1add89f1e8c7a00261 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 18 Aug 2008 17:45:25 -0700 Subject: usb gadget: defer obex enumeration Some USB peripheral controller drivers support software control over the data pullup. Use those controls to prevent the OBEX function from enumerating until the userspace server has opened the /dev/ttyGS* node it will use to implement protocol chitchat with the USB host. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_obex.c | 61 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index 86241b2ca8f4..80c2e7e9622f 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c @@ -35,13 +35,8 @@ * This CDC OBEX function support just packages a TTY-ish byte stream. * A user mode server will put it into "raw" mode and handle all the * relevant protocol details ... this is just a kernel passthrough. - * - * REVISIT this driver shouldn't actually activate before that user mode - * server is ready to respond! When the "serial gadget" utility code - * adds open/close notifications, this driver should use them with new - * (TBS) composite gadget hooks that wrap usb_gadget_disconnect() and - * usb_gadget_connect() calls with refcounts ... disconnect() when we - * bind, then connect() when the user server code is ready to respond. + * When possible, we prevent gadget enumeration until that server is + * ready to handle the commands. */ struct obex_ep_descs { @@ -54,6 +49,7 @@ struct f_obex { u8 ctrl_id; u8 data_id; u8 port_num; + u8 can_activate; struct obex_ep_descs fs; struct obex_ep_descs hs; @@ -64,6 +60,11 @@ static inline struct f_obex *func_to_obex(struct usb_function *f) return container_of(f, struct f_obex, port.func); } +static inline struct f_obex *port_to_obex(struct gserial *p) +{ + return container_of(p, struct f_obex, port); +} + /*-------------------------------------------------------------------------*/ #define OBEX_CTRL_IDX 0 @@ -269,6 +270,38 @@ static void obex_disable(struct usb_function *f) /*-------------------------------------------------------------------------*/ +static void obex_connect(struct gserial *g) +{ + struct f_obex *obex = port_to_obex(g); + struct usb_composite_dev *cdev = g->func.config->cdev; + int status; + + if (!obex->can_activate) + return; + + status = usb_function_activate(&g->func); + if (status) + DBG(cdev, "obex ttyGS%d function activate --> %d\n", + obex->port_num, status); +} + +static void obex_disconnect(struct gserial *g) +{ + struct f_obex *obex = port_to_obex(g); + struct usb_composite_dev *cdev = g->func.config->cdev; + int status; + + if (!obex->can_activate) + return; + + status = usb_function_deactivate(&g->func); + if (status) + DBG(cdev, "obex ttyGS%d function deactivate --> %d\n", + obex->port_num, status); +} + +/*-------------------------------------------------------------------------*/ + static int __init obex_bind(struct usb_configuration *c, struct usb_function *f) { @@ -338,6 +371,17 @@ obex_bind(struct usb_configuration *c, struct usb_function *f) f->descriptors, &obex_hs_ep_out_desc); } + /* Avoid letting this gadget enumerate until the userspace + * OBEX server is active. + */ + status = usb_function_deactivate(f); + if (status < 0) + WARNING(cdev, "obex ttyGS%d: can't prevent enumeration, %d\n", + obex->port_num, status); + else + obex->can_activate = true; + + DBG(cdev, "obex ttyGS%d: %s speed IN/%s OUT/%s\n", obex->port_num, gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", @@ -426,6 +470,9 @@ int __init obex_bind_config(struct usb_configuration *c, u8 port_num) obex->port_num = port_num; + obex->port.connect = obex_connect; + obex->port.disconnect = obex_disconnect; + obex->port.func.name = "obex"; obex->port.func.strings = obex_strings; /* descriptors are per-instance copies */ -- cgit v1.2.3 From 58209018cfd6f1fa8d0139af7c39dbfe73de21fd Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sat, 23 Aug 2008 13:56:30 +0800 Subject: USB: remove unused #include The driver(s) below do not use LINUX_VERSION_CODE nor KERNEL_VERSION. drivers/usb/gadget/pxa27x_udc.c This patch removes the said #include . Signed-off-by: Huang Weiyi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/pxa27x_udc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 7cbc78a6853d..bcf375ca3d72 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From bedf0883cbe3015d21aec5ed47ddffb429f6cca7 Mon Sep 17 00:00:00 2001 From: Julien Brunel Date: Mon, 1 Sep 2008 10:57:27 +0200 Subject: USB: drivers/usb/misc: Use an IS_ERR test rather than a NULL test In case of error, the function backlight_device_register returns an ERR pointer, but never returns a NULL pointer. So a NULL test that may come after a call to this function should be strengthened by an IS_ERR test. The semantic match that finds this problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @match_bad_null_test@ expression x, E; statement S1,S2; @@ x = backlight_device_register(...) ... when != x = E * if (x != NULL) S1 else S2 // Signed-off-by: Julien Brunel Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/appledisplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index a076c24a312a..71d672ea1229 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -314,7 +314,7 @@ error: pdata->urbdata, pdata->urb->transfer_dma); usb_free_urb(pdata->urb); } - if (pdata->bd) + if (pdata->bd && !IS_ERR(pdata->bd)) backlight_device_unregister(pdata->bd); kfree(pdata->msgdata); } -- cgit v1.2.3 From 3948f0e0c999a6201e9898bb8fbe3c6cc1199276 Mon Sep 17 00:00:00 2001 From: Li Yang Date: Tue, 2 Sep 2008 19:58:10 +0800 Subject: usb: add Freescale QE/CPM USB peripheral controller driver Some of Freescale SoC chips have a QE or CPM co-processor which supports full speed USB. The driver adds device mode support of both QE and CPM USB controller to Linux USB gadget. The driver is tested with MPC8360 and MPC8272, and should work with other models having QE/CPM given minor tweaks. Signed-off-by: Xie Xiaobo Signed-off-by: Li Yang Acked-by: Arnd Bergmann Cc: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 19 + drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/fsl_qe_udc.c | 2723 +++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/fsl_qe_udc.h | 436 ++++++ drivers/usb/gadget/gadget_chips.h | 9 + 5 files changed, 3188 insertions(+) create mode 100644 drivers/usb/gadget/fsl_qe_udc.c create mode 100644 drivers/usb/gadget/fsl_qe_udc.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 80a7c02dc951..c0dfd9be3115 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -341,6 +341,25 @@ config USB_AMD5536UDC default USB_GADGET select USB_GADGET_SELECTED +config USB_GADGET_FSL_QE + boolean "Freescale QE/CPM USB Device Controller" + depends on FSL_SOC && (QUICC_ENGINE || CPM) + help + Some of Freescale PowerPC processors have a Full Speed + QE/CPM2 USB controller, which support device mode with 4 + programmable endpoints. This driver supports the + controller in the MPC8360 and MPC8272, and should work with + controllers having QE or CPM2, given minor tweaks. + + Set CONFIG_USB_GADGET to "m" to build this driver as a + dynmically linked module called "fsl_qe_udc". + +config USB_FSL_QE + tristate + depends on USB_GADGET_FSL_QE + default USB_GADGET + select USB_GADGET_SELECTED + config USB_GADGET_NET2280 boolean "NetChip 228x" depends on PCI diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 2267fa0b51b2..bd4041b47dce 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_USB_AT91) += at91_udc.o obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o obj-$(CONFIG_USB_M66592) += m66592-udc.o +obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o # # USB gadget drivers diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c new file mode 100644 index 000000000000..e9400e62f171 --- /dev/null +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -0,0 +1,2723 @@ +/* + * driver/usb/gadget/fsl_qe_udc.c + * + * Copyright (c) 2006-2008 Freescale Semiconductor, Inc. All rights reserved. + * + * Xie Xiaobo + * Li Yang + * Based on bareboard code from Shlomi Gridish. + * + * Description: + * Freescle QE/CPM USB Pheripheral Controller Driver + * The controller can be found on MPC8360, MPC8272, and etc. + * MPC8360 Rev 1.1 may need QE mircocode update + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#undef USB_TRACE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fsl_qe_udc.h" + +#define DRIVER_DESC "Freescale QE/CPM USB Device Controller driver" +#define DRIVER_AUTHOR "Xie XiaoBo" +#define DRIVER_VERSION "1.0" + +#define DMA_ADDR_INVALID (~(dma_addr_t)0) + +static const char driver_name[] = "fsl_qe_udc"; +static const char driver_desc[] = DRIVER_DESC; + +/*ep name is important in gadget, it should obey the convention of ep_match()*/ +static const char *const ep_name[] = { + "ep0-control", /* everyone has ep0 */ + /* 3 configurable endpoints */ + "ep1", + "ep2", + "ep3", +}; + +static struct usb_endpoint_descriptor qe_ep0_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = 0, + .bmAttributes = USB_ENDPOINT_XFER_CONTROL, + .wMaxPacketSize = USB_MAX_CTRL_PAYLOAD, +}; + +/* it is initialized in probe() */ +static struct qe_udc *udc_controller; + +/******************************************************************** + * Internal Used Function Start +********************************************************************/ +/*----------------------------------------------------------------- + * done() - retire a request; caller blocked irqs + *--------------------------------------------------------------*/ +static void done(struct qe_ep *ep, struct qe_req *req, int status) +{ + struct qe_udc *udc = ep->udc; + unsigned char stopped = ep->stopped; + + /* the req->queue pointer is used by ep_queue() func, in which + * the request will be added into a udc_ep->queue 'd tail + * so here the req will be dropped from the ep->queue + */ + list_del_init(&req->queue); + + /* req.status should be set as -EINPROGRESS in ep_queue() */ + if (req->req.status == -EINPROGRESS) + req->req.status = status; + else + status = req->req.status; + + if (req->mapped) { + dma_unmap_single(udc->gadget.dev.parent, + req->req.dma, req->req.length, + ep_is_in(ep) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + req->req.dma = DMA_ADDR_INVALID; + req->mapped = 0; + } else + dma_sync_single_for_cpu(udc->gadget.dev.parent, + req->req.dma, req->req.length, + ep_is_in(ep) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + + if (status && (status != -ESHUTDOWN)) + dev_vdbg(udc->dev, "complete %s req %p stat %d len %u/%u\n", + ep->ep.name, &req->req, status, + req->req.actual, req->req.length); + + /* don't modify queue heads during completion callback */ + ep->stopped = 1; + spin_unlock(&udc->lock); + + /* this complete() should a func implemented by gadget layer, + * eg fsg->bulk_in_complete() */ + if (req->req.complete) + req->req.complete(&ep->ep, &req->req); + + spin_lock(&udc->lock); + + ep->stopped = stopped; +} + +/*----------------------------------------------------------------- + * nuke(): delete all requests related to this ep + *--------------------------------------------------------------*/ +static void nuke(struct qe_ep *ep, int status) +{ + /* Whether this eq has request linked */ + while (!list_empty(&ep->queue)) { + struct qe_req *req = NULL; + req = list_entry(ep->queue.next, struct qe_req, queue); + + done(ep, req, status); + } +} + +/*---------------------------------------------------------------------------* + * USB and Endpoint manipulate process, include parameter and register * + *---------------------------------------------------------------------------*/ +/* @value: 1--set stall 0--clean stall */ +static int qe_eprx_stall_change(struct qe_ep *ep, int value) +{ + u16 tem_usep; + u8 epnum = ep->epnum; + struct qe_udc *udc = ep->udc; + + tem_usep = in_be16(&udc->usb_regs->usb_usep[epnum]); + tem_usep = tem_usep & ~USB_RHS_MASK; + if (value == 1) + tem_usep |= USB_RHS_STALL; + else if (ep->dir == USB_DIR_IN) + tem_usep |= USB_RHS_IGNORE_OUT; + + out_be16(&udc->usb_regs->usb_usep[epnum], tem_usep); + return 0; +} + +static int qe_eptx_stall_change(struct qe_ep *ep, int value) +{ + u16 tem_usep; + u8 epnum = ep->epnum; + struct qe_udc *udc = ep->udc; + + tem_usep = in_be16(&udc->usb_regs->usb_usep[epnum]); + tem_usep = tem_usep & ~USB_THS_MASK; + if (value == 1) + tem_usep |= USB_THS_STALL; + else if (ep->dir == USB_DIR_OUT) + tem_usep |= USB_THS_IGNORE_IN; + + out_be16(&udc->usb_regs->usb_usep[epnum], tem_usep); + + return 0; +} + +static int qe_ep0_stall(struct qe_udc *udc) +{ + qe_eptx_stall_change(&udc->eps[0], 1); + qe_eprx_stall_change(&udc->eps[0], 1); + udc_controller->ep0_state = WAIT_FOR_SETUP; + udc_controller->ep0_dir = 0; + return 0; +} + +static int qe_eprx_nack(struct qe_ep *ep) +{ + u8 epnum = ep->epnum; + struct qe_udc *udc = ep->udc; + + if (ep->state == EP_STATE_IDLE) { + /* Set the ep's nack */ + clrsetbits_be16(&udc->usb_regs->usb_usep[epnum], + USB_RHS_MASK, USB_RHS_NACK); + + /* Mask Rx and Busy interrupts */ + clrbits16(&udc->usb_regs->usb_usbmr, + (USB_E_RXB_MASK | USB_E_BSY_MASK)); + + ep->state = EP_STATE_NACK; + } + return 0; +} + +static int qe_eprx_normal(struct qe_ep *ep) +{ + struct qe_udc *udc = ep->udc; + + if (ep->state == EP_STATE_NACK) { + clrsetbits_be16(&udc->usb_regs->usb_usep[ep->epnum], + USB_RTHS_MASK, USB_THS_IGNORE_IN); + + /* Unmask RX interrupts */ + out_be16(&udc->usb_regs->usb_usber, + USB_E_BSY_MASK | USB_E_RXB_MASK); + setbits16(&udc->usb_regs->usb_usbmr, + (USB_E_RXB_MASK | USB_E_BSY_MASK)); + + ep->state = EP_STATE_IDLE; + ep->has_data = 0; + } + + return 0; +} + +static int qe_ep_cmd_stoptx(struct qe_ep *ep) +{ + if (ep->udc->soc_type == PORT_CPM) + cpm_command(CPM_USB_STOP_TX | (ep->epnum << CPM_USB_EP_SHIFT), + CPM_USB_STOP_TX_OPCODE); + else + qe_issue_cmd(QE_USB_STOP_TX, QE_CR_SUBBLOCK_USB, + ep->epnum, 0); + + return 0; +} + +static int qe_ep_cmd_restarttx(struct qe_ep *ep) +{ + if (ep->udc->soc_type == PORT_CPM) + cpm_command(CPM_USB_RESTART_TX | (ep->epnum << + CPM_USB_EP_SHIFT), CPM_USB_RESTART_TX_OPCODE); + else + qe_issue_cmd(QE_USB_RESTART_TX, QE_CR_SUBBLOCK_USB, + ep->epnum, 0); + + return 0; +} + +static int qe_ep_flushtxfifo(struct qe_ep *ep) +{ + struct qe_udc *udc = ep->udc; + int i; + + i = (int)ep->epnum; + + qe_ep_cmd_stoptx(ep); + out_8(&udc->usb_regs->usb_uscom, + USB_CMD_FLUSH_FIFO | (USB_CMD_EP_MASK & (ep->epnum))); + out_be16(&udc->ep_param[i]->tbptr, in_be16(&udc->ep_param[i]->tbase)); + out_be32(&udc->ep_param[i]->tstate, 0); + out_be16(&udc->ep_param[i]->tbcnt, 0); + + ep->c_txbd = ep->txbase; + ep->n_txbd = ep->txbase; + qe_ep_cmd_restarttx(ep); + return 0; +} + +static int qe_ep_filltxfifo(struct qe_ep *ep) +{ + struct qe_udc *udc = ep->udc; + + out_8(&udc->usb_regs->usb_uscom, + USB_CMD_STR_FIFO | (USB_CMD_EP_MASK & (ep->epnum))); + return 0; +} + +static int qe_epbds_reset(struct qe_udc *udc, int pipe_num) +{ + struct qe_ep *ep; + u32 bdring_len; + struct qe_bd __iomem *bd; + int i; + + ep = &udc->eps[pipe_num]; + + if (ep->dir == USB_DIR_OUT) + bdring_len = USB_BDRING_LEN_RX; + else + bdring_len = USB_BDRING_LEN; + + bd = ep->rxbase; + for (i = 0; i < (bdring_len - 1); i++) { + out_be32((u32 __iomem *)bd, R_E | R_I); + bd++; + } + out_be32((u32 __iomem *)bd, R_E | R_I | R_W); + + bd = ep->txbase; + for (i = 0; i < USB_BDRING_LEN_TX - 1; i++) { + out_be32(&bd->buf, 0); + out_be32((u32 __iomem *)bd, 0); + bd++; + } + out_be32((u32 __iomem *)bd, T_W); + + return 0; +} + +static int qe_ep_reset(struct qe_udc *udc, int pipe_num) +{ + struct qe_ep *ep; + u16 tmpusep; + + ep = &udc->eps[pipe_num]; + tmpusep = in_be16(&udc->usb_regs->usb_usep[pipe_num]); + tmpusep &= ~USB_RTHS_MASK; + + switch (ep->dir) { + case USB_DIR_BOTH: + qe_ep_flushtxfifo(ep); + break; + case USB_DIR_OUT: + tmpusep |= USB_THS_IGNORE_IN; + break; + case USB_DIR_IN: + qe_ep_flushtxfifo(ep); + tmpusep |= USB_RHS_IGNORE_OUT; + break; + default: + break; + } + out_be16(&udc->usb_regs->usb_usep[pipe_num], tmpusep); + + qe_epbds_reset(udc, pipe_num); + + return 0; +} + +static int qe_ep_toggledata01(struct qe_ep *ep) +{ + ep->data01 ^= 0x1; + return 0; +} + +static int qe_ep_bd_init(struct qe_udc *udc, unsigned char pipe_num) +{ + struct qe_ep *ep = &udc->eps[pipe_num]; + unsigned long tmp_addr = 0; + struct usb_ep_para __iomem *epparam; + int i; + struct qe_bd __iomem *bd; + int bdring_len; + + if (ep->dir == USB_DIR_OUT) + bdring_len = USB_BDRING_LEN_RX; + else + bdring_len = USB_BDRING_LEN; + + epparam = udc->ep_param[pipe_num]; + /* alloc multi-ram for BD rings and set the ep parameters */ + tmp_addr = cpm_muram_alloc(sizeof(struct qe_bd) * (bdring_len + + USB_BDRING_LEN_TX), QE_ALIGNMENT_OF_BD); + out_be16(&epparam->rbase, (u16)tmp_addr); + out_be16(&epparam->tbase, (u16)(tmp_addr + + (sizeof(struct qe_bd) * bdring_len))); + + out_be16(&epparam->rbptr, in_be16(&epparam->rbase)); + out_be16(&epparam->tbptr, in_be16(&epparam->tbase)); + + ep->rxbase = cpm_muram_addr(tmp_addr); + ep->txbase = cpm_muram_addr(tmp_addr + (sizeof(struct qe_bd) + * bdring_len)); + ep->n_rxbd = ep->rxbase; + ep->e_rxbd = ep->rxbase; + ep->n_txbd = ep->txbase; + ep->c_txbd = ep->txbase; + ep->data01 = 0; /* data0 */ + + /* Init TX and RX bds */ + bd = ep->rxbase; + for (i = 0; i < bdring_len - 1; i++) { + out_be32(&bd->buf, 0); + out_be32((u32 __iomem *)bd, 0); + bd++; + } + out_be32(&bd->buf, 0); + out_be32((u32 __iomem *)bd, R_W); + + bd = ep->txbase; + for (i = 0; i < USB_BDRING_LEN_TX - 1; i++) { + out_be32(&bd->buf, 0); + out_be32((u32 __iomem *)bd, 0); + bd++; + } + out_be32(&bd->buf, 0); + out_be32((u32 __iomem *)bd, T_W); + + return 0; +} + +static int qe_ep_rxbd_update(struct qe_ep *ep) +{ + unsigned int size; + int i; + unsigned int tmp; + struct qe_bd __iomem *bd; + unsigned int bdring_len; + + if (ep->rxbase == NULL) + return -EINVAL; + + bd = ep->rxbase; + + ep->rxframe = kmalloc(sizeof(*ep->rxframe), GFP_ATOMIC); + if (ep->rxframe == NULL) { + dev_err(ep->udc->dev, "malloc rxframe failed\n"); + return -ENOMEM; + } + + qe_frame_init(ep->rxframe); + + if (ep->dir == USB_DIR_OUT) + bdring_len = USB_BDRING_LEN_RX; + else + bdring_len = USB_BDRING_LEN; + + size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (bdring_len + 1); + ep->rxbuffer = kzalloc(size, GFP_ATOMIC); + if (ep->rxbuffer == NULL) { + dev_err(ep->udc->dev, "malloc rxbuffer failed,size=%d\n", + size); + kfree(ep->rxframe); + return -ENOMEM; + } + + ep->rxbuf_d = virt_to_phys((void *)ep->rxbuffer); + if (ep->rxbuf_d == DMA_ADDR_INVALID) { + ep->rxbuf_d = dma_map_single(udc_controller->gadget.dev.parent, + ep->rxbuffer, + size, + DMA_FROM_DEVICE); + ep->rxbufmap = 1; + } else { + dma_sync_single_for_device(udc_controller->gadget.dev.parent, + ep->rxbuf_d, size, + DMA_FROM_DEVICE); + ep->rxbufmap = 0; + } + + size = ep->ep.maxpacket + USB_CRC_SIZE + 2; + tmp = ep->rxbuf_d; + tmp = (u32)(((tmp >> 2) << 2) + 4); + + for (i = 0; i < bdring_len - 1; i++) { + out_be32(&bd->buf, tmp); + out_be32((u32 __iomem *)bd, (R_E | R_I)); + tmp = tmp + size; + bd++; + } + out_be32(&bd->buf, tmp); + out_be32((u32 __iomem *)bd, (R_E | R_I | R_W)); + + return 0; +} + +static int qe_ep_register_init(struct qe_udc *udc, unsigned char pipe_num) +{ + struct qe_ep *ep = &udc->eps[pipe_num]; + struct usb_ep_para __iomem *epparam; + u16 usep, logepnum; + u16 tmp; + u8 rtfcr = 0; + + epparam = udc->ep_param[pipe_num]; + + usep = 0; + logepnum = (ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); + usep |= (logepnum << USB_EPNUM_SHIFT); + + switch (ep->desc->bmAttributes & 0x03) { + case USB_ENDPOINT_XFER_BULK: + usep |= USB_TRANS_BULK; + break; + case USB_ENDPOINT_XFER_ISOC: + usep |= USB_TRANS_ISO; + break; + case USB_ENDPOINT_XFER_INT: + usep |= USB_TRANS_INT; + break; + default: + usep |= USB_TRANS_CTR; + break; + } + + switch (ep->dir) { + case USB_DIR_OUT: + usep |= USB_THS_IGNORE_IN; + break; + case USB_DIR_IN: + usep |= USB_RHS_IGNORE_OUT; + break; + default: + break; + } + out_be16(&udc->usb_regs->usb_usep[pipe_num], usep); + + rtfcr = 0x30; + out_8(&epparam->rbmr, rtfcr); + out_8(&epparam->tbmr, rtfcr); + + tmp = (u16)(ep->ep.maxpacket + USB_CRC_SIZE); + /* MRBLR must be divisble by 4 */ + tmp = (u16)(((tmp >> 2) << 2) + 4); + out_be16(&epparam->mrblr, tmp); + + return 0; +} + +static int qe_ep_init(struct qe_udc *udc, + unsigned char pipe_num, + const struct usb_endpoint_descriptor *desc) +{ + struct qe_ep *ep = &udc->eps[pipe_num]; + unsigned long flags; + int reval = 0; + u16 max = 0; + + max = le16_to_cpu(desc->wMaxPacketSize); + + /* check the max package size validate for this endpoint */ + /* Refer to USB2.0 spec table 9-13, + */ + if (pipe_num != 0) { + switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_BULK: + if (strstr(ep->ep.name, "-iso") + || strstr(ep->ep.name, "-int")) + goto en_done; + switch (udc->gadget.speed) { + case USB_SPEED_HIGH: + if ((max == 128) || (max == 256) || (max == 512)) + break; + default: + switch (max) { + case 4: + case 8: + case 16: + case 32: + case 64: + break; + default: + case USB_SPEED_LOW: + goto en_done; + } + } + break; + case USB_ENDPOINT_XFER_INT: + if (strstr(ep->ep.name, "-iso")) /* bulk is ok */ + goto en_done; + switch (udc->gadget.speed) { + case USB_SPEED_HIGH: + if (max <= 1024) + break; + case USB_SPEED_FULL: + if (max <= 64) + break; + default: + if (max <= 8) + break; + goto en_done; + } + break; + case USB_ENDPOINT_XFER_ISOC: + if (strstr(ep->ep.name, "-bulk") + || strstr(ep->ep.name, "-int")) + goto en_done; + switch (udc->gadget.speed) { + case USB_SPEED_HIGH: + if (max <= 1024) + break; + case USB_SPEED_FULL: + if (max <= 1023) + break; + default: + goto en_done; + } + break; + case USB_ENDPOINT_XFER_CONTROL: + if (strstr(ep->ep.name, "-iso") + || strstr(ep->ep.name, "-int")) + goto en_done; + switch (udc->gadget.speed) { + case USB_SPEED_HIGH: + case USB_SPEED_FULL: + switch (max) { + case 1: + case 2: + case 4: + case 8: + case 16: + case 32: + case 64: + break; + default: + goto en_done; + } + case USB_SPEED_LOW: + switch (max) { + case 1: + case 2: + case 4: + case 8: + break; + default: + goto en_done; + } + default: + goto en_done; + } + break; + + default: + goto en_done; + } + } /* if ep0*/ + + spin_lock_irqsave(&udc->lock, flags); + + /* initialize ep structure */ + ep->ep.maxpacket = max; + ep->tm = (u8)(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); + ep->desc = desc; + ep->stopped = 0; + ep->init = 1; + + if (pipe_num == 0) { + ep->dir = USB_DIR_BOTH; + udc->ep0_dir = USB_DIR_OUT; + udc->ep0_state = WAIT_FOR_SETUP; + } else { + switch (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { + case USB_DIR_OUT: + ep->dir = USB_DIR_OUT; + break; + case USB_DIR_IN: + ep->dir = USB_DIR_IN; + default: + break; + } + } + + /* hardware special operation */ + qe_ep_bd_init(udc, pipe_num); + if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_OUT)) { + reval = qe_ep_rxbd_update(ep); + if (reval) + goto en_done1; + } + + if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_IN)) { + ep->txframe = kmalloc(sizeof(*ep->txframe), GFP_ATOMIC); + if (ep->txframe == NULL) { + dev_err(udc->dev, "malloc txframe failed\n"); + goto en_done2; + } + qe_frame_init(ep->txframe); + } + + qe_ep_register_init(udc, pipe_num); + + /* Now HW will be NAKing transfers to that EP, + * until a buffer is queued to it. */ + spin_unlock_irqrestore(&udc->lock, flags); + + return 0; +en_done2: + kfree(ep->rxbuffer); + kfree(ep->rxframe); +en_done1: + spin_unlock_irqrestore(&udc->lock, flags); +en_done: + dev_dbg(udc->dev, "failed to initialize %s\n", ep->ep.name); + return -ENODEV; +} + +static inline void qe_usb_enable(void) +{ + setbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN); +} + +static inline void qe_usb_disable(void) +{ + clrbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN); +} + +/*----------------------------------------------------------------------------* + * USB and EP basic manipulate function end * + *----------------------------------------------------------------------------*/ + + +/****************************************************************************** + UDC transmit and receive process + ******************************************************************************/ +static void recycle_one_rxbd(struct qe_ep *ep) +{ + u32 bdstatus; + + bdstatus = in_be32((u32 __iomem *)ep->e_rxbd); + bdstatus = R_I | R_E | (bdstatus & R_W); + out_be32((u32 __iomem *)ep->e_rxbd, bdstatus); + + if (bdstatus & R_W) + ep->e_rxbd = ep->rxbase; + else + ep->e_rxbd++; +} + +static void recycle_rxbds(struct qe_ep *ep, unsigned char stopatnext) +{ + u32 bdstatus; + struct qe_bd __iomem *bd, *nextbd; + unsigned char stop = 0; + + nextbd = ep->n_rxbd; + bd = ep->e_rxbd; + bdstatus = in_be32((u32 __iomem *)bd); + + while (!(bdstatus & R_E) && !(bdstatus & BD_LENGTH_MASK) && !stop) { + bdstatus = R_E | R_I | (bdstatus & R_W); + out_be32((u32 __iomem *)bd, bdstatus); + + if (bdstatus & R_W) + bd = ep->rxbase; + else + bd++; + + bdstatus = in_be32((u32 __iomem *)bd); + if (stopatnext && (bd == nextbd)) + stop = 1; + } + + ep->e_rxbd = bd; +} + +static void ep_recycle_rxbds(struct qe_ep *ep) +{ + struct qe_bd __iomem *bd = ep->n_rxbd; + u32 bdstatus; + u8 epnum = ep->epnum; + struct qe_udc *udc = ep->udc; + + bdstatus = in_be32((u32 __iomem *)bd); + if (!(bdstatus & R_E) && !(bdstatus & BD_LENGTH_MASK)) { + bd = ep->rxbase + + ((in_be16(&udc->ep_param[epnum]->rbptr) - + in_be16(&udc->ep_param[epnum]->rbase)) + >> 3); + bdstatus = in_be32((u32 __iomem *)bd); + + if (bdstatus & R_W) + bd = ep->rxbase; + else + bd++; + + ep->e_rxbd = bd; + recycle_rxbds(ep, 0); + ep->e_rxbd = ep->n_rxbd; + } else + recycle_rxbds(ep, 1); + + if (in_be16(&udc->usb_regs->usb_usber) & USB_E_BSY_MASK) + out_be16(&udc->usb_regs->usb_usber, USB_E_BSY_MASK); + + if (ep->has_data <= 0 && (!list_empty(&ep->queue))) + qe_eprx_normal(ep); + + ep->localnack = 0; +} + +static void setup_received_handle(struct qe_udc *udc, + struct usb_ctrlrequest *setup); +static int qe_ep_rxframe_handle(struct qe_ep *ep); +static void ep0_req_complete(struct qe_udc *udc, struct qe_req *req); +/* when BD PID is setup, handle the packet */ +static int ep0_setup_handle(struct qe_udc *udc) +{ + struct qe_ep *ep = &udc->eps[0]; + struct qe_frame *pframe; + unsigned int fsize; + u8 *cp; + + pframe = ep->rxframe; + if ((frame_get_info(pframe) & PID_SETUP) + && (udc->ep0_state == WAIT_FOR_SETUP)) { + fsize = frame_get_length(pframe); + if (unlikely(fsize != 8)) + return -EINVAL; + cp = (u8 *)&udc->local_setup_buff; + memcpy(cp, pframe->data, fsize); + ep->data01 = 1; + + /* handle the usb command base on the usb_ctrlrequest */ + setup_received_handle(udc, &udc->local_setup_buff); + return 0; + } + return -EINVAL; +} + +static int qe_ep0_rx(struct qe_udc *udc) +{ + struct qe_ep *ep = &udc->eps[0]; + struct qe_frame *pframe; + struct qe_bd __iomem *bd; + u32 bdstatus, length; + u32 vaddr; + + pframe = ep->rxframe; + + if (ep->dir == USB_DIR_IN) { + dev_err(udc->dev, "ep0 not a control endpoint\n"); + return -EINVAL; + } + + bd = ep->n_rxbd; + bdstatus = in_be32((u32 __iomem *)bd); + length = bdstatus & BD_LENGTH_MASK; + + while (!(bdstatus & R_E) && length) { + if ((bdstatus & R_F) && (bdstatus & R_L) + && !(bdstatus & R_ERROR)) { + if (length == USB_CRC_SIZE) { + udc->ep0_state = WAIT_FOR_SETUP; + dev_vdbg(udc->dev, + "receive a ZLP in status phase\n"); + } else { + qe_frame_clean(pframe); + vaddr = (u32)phys_to_virt(in_be32(&bd->buf)); + frame_set_data(pframe, (u8 *)vaddr); + frame_set_length(pframe, + (length - USB_CRC_SIZE)); + frame_set_status(pframe, FRAME_OK); + switch (bdstatus & R_PID) { + case R_PID_SETUP: + frame_set_info(pframe, PID_SETUP); + break; + case R_PID_DATA1: + frame_set_info(pframe, PID_DATA1); + break; + default: + frame_set_info(pframe, PID_DATA0); + break; + } + + if ((bdstatus & R_PID) == R_PID_SETUP) + ep0_setup_handle(udc); + else + qe_ep_rxframe_handle(ep); + } + } else { + dev_err(udc->dev, "The receive frame with error!\n"); + } + + /* note: don't clear the rxbd's buffer address */ + recycle_one_rxbd(ep); + + /* Get next BD */ + if (bdstatus & R_W) + bd = ep->rxbase; + else + bd++; + + bdstatus = in_be32((u32 __iomem *)bd); + length = bdstatus & BD_LENGTH_MASK; + + } + + ep->n_rxbd = bd; + + return 0; +} + +static int qe_ep_rxframe_handle(struct qe_ep *ep) +{ + struct qe_frame *pframe; + u8 framepid = 0; + unsigned int fsize; + u8 *cp; + struct qe_req *req; + + pframe = ep->rxframe; + + if (frame_get_info(pframe) & PID_DATA1) + framepid = 0x1; + + if (framepid != ep->data01) { + dev_err(ep->udc->dev, "the data01 error!\n"); + return -EIO; + } + + fsize = frame_get_length(pframe); + if (list_empty(&ep->queue)) { + dev_err(ep->udc->dev, "the %s have no requeue!\n", ep->name); + } else { + req = list_entry(ep->queue.next, struct qe_req, queue); + + cp = (u8 *)(req->req.buf) + req->req.actual; + if (cp) { + memcpy(cp, pframe->data, fsize); + req->req.actual += fsize; + if ((fsize < ep->ep.maxpacket) || + (req->req.actual >= req->req.length)) { + if (ep->epnum == 0) + ep0_req_complete(ep->udc, req); + else + done(ep, req, 0); + if (list_empty(&ep->queue) && ep->epnum != 0) + qe_eprx_nack(ep); + } + } + } + + qe_ep_toggledata01(ep); + + return 0; +} + +static void ep_rx_tasklet(unsigned long data) +{ + struct qe_udc *udc = (struct qe_udc *)data; + struct qe_ep *ep; + struct qe_frame *pframe; + struct qe_bd __iomem *bd; + unsigned long flags; + u32 bdstatus, length; + u32 vaddr, i; + + spin_lock_irqsave(&udc->lock, flags); + + for (i = 1; i < USB_MAX_ENDPOINTS; i++) { + ep = &udc->eps[i]; + + if (ep->dir == USB_DIR_IN || ep->enable_tasklet == 0) { + dev_dbg(udc->dev, + "This is a transmit ep or disable tasklet!\n"); + continue; + } + + pframe = ep->rxframe; + bd = ep->n_rxbd; + bdstatus = in_be32((u32 __iomem *)bd); + length = bdstatus & BD_LENGTH_MASK; + + while (!(bdstatus & R_E) && length) { + if (list_empty(&ep->queue)) { + qe_eprx_nack(ep); + dev_dbg(udc->dev, + "The rxep have noreq %d\n", + ep->has_data); + break; + } + + if ((bdstatus & R_F) && (bdstatus & R_L) + && !(bdstatus & R_ERROR)) { + qe_frame_clean(pframe); + vaddr = (u32)phys_to_virt(in_be32(&bd->buf)); + frame_set_data(pframe, (u8 *)vaddr); + frame_set_length(pframe, + (length - USB_CRC_SIZE)); + frame_set_status(pframe, FRAME_OK); + switch (bdstatus & R_PID) { + case R_PID_DATA1: + frame_set_info(pframe, PID_DATA1); + break; + case R_PID_SETUP: + frame_set_info(pframe, PID_SETUP); + break; + default: + frame_set_info(pframe, PID_DATA0); + break; + } + /* handle the rx frame */ + qe_ep_rxframe_handle(ep); + } else { + dev_err(udc->dev, + "error in received frame\n"); + } + /* note: don't clear the rxbd's buffer address */ + /*clear the length */ + out_be32((u32 __iomem *)bd, bdstatus & BD_STATUS_MASK); + ep->has_data--; + if (!(ep->localnack)) + recycle_one_rxbd(ep); + + /* Get next BD */ + if (bdstatus & R_W) + bd = ep->rxbase; + else + bd++; + + bdstatus = in_be32((u32 __iomem *)bd); + length = bdstatus & BD_LENGTH_MASK; + } + + ep->n_rxbd = bd; + + if (ep->localnack) + ep_recycle_rxbds(ep); + + ep->enable_tasklet = 0; + } /* for i=1 */ + + spin_unlock_irqrestore(&udc->lock, flags); +} + +static int qe_ep_rx(struct qe_ep *ep) +{ + struct qe_udc *udc; + struct qe_frame *pframe; + struct qe_bd __iomem *bd; + u16 swoffs, ucoffs, emptybds; + + udc = ep->udc; + pframe = ep->rxframe; + + if (ep->dir == USB_DIR_IN) { + dev_err(udc->dev, "transmit ep in rx function\n"); + return -EINVAL; + } + + bd = ep->n_rxbd; + + swoffs = (u16)(bd - ep->rxbase); + ucoffs = (u16)((in_be16(&udc->ep_param[ep->epnum]->rbptr) - + in_be16(&udc->ep_param[ep->epnum]->rbase)) >> 3); + if (swoffs < ucoffs) + emptybds = USB_BDRING_LEN_RX - ucoffs + swoffs; + else + emptybds = swoffs - ucoffs; + + if (emptybds < MIN_EMPTY_BDS) { + qe_eprx_nack(ep); + ep->localnack = 1; + dev_vdbg(udc->dev, "%d empty bds, send NACK\n", emptybds); + } + ep->has_data = USB_BDRING_LEN_RX - emptybds; + + if (list_empty(&ep->queue)) { + qe_eprx_nack(ep); + dev_vdbg(udc->dev, "The rxep have no req queued with %d BDs\n", + ep->has_data); + return 0; + } + + tasklet_schedule(&udc->rx_tasklet); + ep->enable_tasklet = 1; + + return 0; +} + +/* send data from a frame, no matter what tx_req */ +static int qe_ep_tx(struct qe_ep *ep, struct qe_frame *frame) +{ + struct qe_udc *udc = ep->udc; + struct qe_bd __iomem *bd; + u16 saveusbmr; + u32 bdstatus, pidmask; + u32 paddr; + + if (ep->dir == USB_DIR_OUT) { + dev_err(udc->dev, "receive ep passed to tx function\n"); + return -EINVAL; + } + + /* Disable the Tx interrupt */ + saveusbmr = in_be16(&udc->usb_regs->usb_usbmr); + out_be16(&udc->usb_regs->usb_usbmr, + saveusbmr & ~(USB_E_TXB_MASK | USB_E_TXE_MASK)); + + bd = ep->n_txbd; + bdstatus = in_be32((u32 __iomem *)bd); + + if (!(bdstatus & (T_R | BD_LENGTH_MASK))) { + if (frame_get_length(frame) == 0) { + frame_set_data(frame, udc->nullbuf); + frame_set_length(frame, 2); + frame->info |= (ZLP | NO_CRC); + dev_vdbg(udc->dev, "the frame size = 0\n"); + } + paddr = virt_to_phys((void *)frame->data); + out_be32(&bd->buf, paddr); + bdstatus = (bdstatus&T_W); + if (!(frame_get_info(frame) & NO_CRC)) + bdstatus |= T_R | T_I | T_L | T_TC + | frame_get_length(frame); + else + bdstatus |= T_R | T_I | T_L | frame_get_length(frame); + + /* if the packet is a ZLP in status phase */ + if ((ep->epnum == 0) && (udc->ep0_state == DATA_STATE_NEED_ZLP)) + ep->data01 = 0x1; + + if (ep->data01) { + pidmask = T_PID_DATA1; + frame->info |= PID_DATA1; + } else { + pidmask = T_PID_DATA0; + frame->info |= PID_DATA0; + } + bdstatus |= T_CNF; + bdstatus |= pidmask; + out_be32((u32 __iomem *)bd, bdstatus); + qe_ep_filltxfifo(ep); + + /* enable the TX interrupt */ + out_be16(&udc->usb_regs->usb_usbmr, saveusbmr); + + qe_ep_toggledata01(ep); + if (bdstatus & T_W) + ep->n_txbd = ep->txbase; + else + ep->n_txbd++; + + return 0; + } else { + out_be16(&udc->usb_regs->usb_usbmr, saveusbmr); + dev_vdbg(udc->dev, "The tx bd is not ready!\n"); + return -EBUSY; + } +} + +/* when an bd was transmitted, the function can * + * handle the tx_req, not include ep0 */ +static int txcomplete(struct qe_ep *ep, unsigned char restart) +{ + if (ep->tx_req != NULL) { + if (!restart) { + int asent = ep->last; + ep->sent += asent; + ep->last -= asent; + } else { + ep->last = 0; + } + + /* a request already were transmitted completely */ + if ((ep->tx_req->req.length - ep->sent) <= 0) { + ep->tx_req->req.actual = (unsigned int)ep->sent; + done(ep, ep->tx_req, 0); + ep->tx_req = NULL; + ep->last = 0; + ep->sent = 0; + } + } + + /* we should gain a new tx_req fot this endpoint */ + if (ep->tx_req == NULL) { + if (!list_empty(&ep->queue)) { + ep->tx_req = list_entry(ep->queue.next, struct qe_req, + queue); + ep->last = 0; + ep->sent = 0; + } + } + + return 0; +} + +/* give a frame and a tx_req,send some data */ +static int qe_usb_senddata(struct qe_ep *ep, struct qe_frame *frame) +{ + unsigned int size; + u8 *buf; + + qe_frame_clean(frame); + size = min_t(u32, (ep->tx_req->req.length - ep->sent), + ep->ep.maxpacket); + buf = (u8 *)ep->tx_req->req.buf + ep->sent; + if (buf && size) { + ep->last = size; + frame_set_data(frame, buf); + frame_set_length(frame, size); + frame_set_status(frame, FRAME_OK); + frame_set_info(frame, 0); + return qe_ep_tx(ep, frame); + } + return -EIO; +} + +/* give a frame struct,send a ZLP */ +static int sendnulldata(struct qe_ep *ep, struct qe_frame *frame, uint infor) +{ + struct qe_udc *udc = ep->udc; + + if (frame == NULL) + return -ENODEV; + + qe_frame_clean(frame); + frame_set_data(frame, (u8 *)udc->nullbuf); + frame_set_length(frame, 2); + frame_set_status(frame, FRAME_OK); + frame_set_info(frame, (ZLP | NO_CRC | infor)); + + return qe_ep_tx(ep, frame); +} + +static int frame_create_tx(struct qe_ep *ep, struct qe_frame *frame) +{ + struct qe_req *req = ep->tx_req; + int reval; + + if (req == NULL) + return -ENODEV; + + if ((req->req.length - ep->sent) > 0) + reval = qe_usb_senddata(ep, frame); + else + reval = sendnulldata(ep, frame, 0); + + return reval; +} + +/* if direction is DIR_IN, the status is Device->Host + * if direction is DIR_OUT, the status transaction is Device<-Host + * in status phase, udc create a request and gain status */ +static int ep0_prime_status(struct qe_udc *udc, int direction) +{ + + struct qe_ep *ep = &udc->eps[0]; + + if (direction == USB_DIR_IN) { + udc->ep0_state = DATA_STATE_NEED_ZLP; + udc->ep0_dir = USB_DIR_IN; + sendnulldata(ep, ep->txframe, SETUP_STATUS | NO_REQ); + } else { + udc->ep0_dir = USB_DIR_OUT; + udc->ep0_state = WAIT_FOR_OUT_STATUS; + } + + return 0; +} + +/* a request complete in ep0, whether gadget request or udc request */ +static void ep0_req_complete(struct qe_udc *udc, struct qe_req *req) +{ + struct qe_ep *ep = &udc->eps[0]; + /* because usb and ep's status already been set in ch9setaddress() */ + + switch (udc->ep0_state) { + case DATA_STATE_XMIT: + done(ep, req, 0); + /* receive status phase */ + if (ep0_prime_status(udc, USB_DIR_OUT)) + qe_ep0_stall(udc); + break; + + case DATA_STATE_NEED_ZLP: + done(ep, req, 0); + udc->ep0_state = WAIT_FOR_SETUP; + break; + + case DATA_STATE_RECV: + done(ep, req, 0); + /* send status phase */ + if (ep0_prime_status(udc, USB_DIR_IN)) + qe_ep0_stall(udc); + break; + + case WAIT_FOR_OUT_STATUS: + done(ep, req, 0); + udc->ep0_state = WAIT_FOR_SETUP; + break; + + case WAIT_FOR_SETUP: + dev_vdbg(udc->dev, "Unexpected interrupt\n"); + break; + + default: + qe_ep0_stall(udc); + break; + } +} + +static int ep0_txcomplete(struct qe_ep *ep, unsigned char restart) +{ + struct qe_req *tx_req = NULL; + struct qe_frame *frame = ep->txframe; + + if ((frame_get_info(frame) & (ZLP | NO_REQ)) == (ZLP | NO_REQ)) { + if (!restart) + ep->udc->ep0_state = WAIT_FOR_SETUP; + else + sendnulldata(ep, ep->txframe, SETUP_STATUS | NO_REQ); + return 0; + } + + tx_req = ep->tx_req; + if (tx_req != NULL) { + if (!restart) { + int asent = ep->last; + ep->sent += asent; + ep->last -= asent; + } else { + ep->last = 0; + } + + /* a request already were transmitted completely */ + if ((ep->tx_req->req.length - ep->sent) <= 0) { + ep->tx_req->req.actual = (unsigned int)ep->sent; + ep0_req_complete(ep->udc, ep->tx_req); + ep->tx_req = NULL; + ep->last = 0; + ep->sent = 0; + } + } else { + dev_vdbg(ep->udc->dev, "the ep0_controller have no req\n"); + } + + return 0; +} + +static int ep0_txframe_handle(struct qe_ep *ep) +{ + /* if have error, transmit again */ + if (frame_get_status(ep->txframe) & FRAME_ERROR) { + qe_ep_flushtxfifo(ep); + dev_vdbg(ep->udc->dev, "The EP0 transmit data have error!\n"); + if (frame_get_info(ep->txframe) & PID_DATA0) + ep->data01 = 0; + else + ep->data01 = 1; + + ep0_txcomplete(ep, 1); + } else + ep0_txcomplete(ep, 0); + + frame_create_tx(ep, ep->txframe); + return 0; +} + +static int qe_ep0_txconf(struct qe_ep *ep) +{ + struct qe_bd __iomem *bd; + struct qe_frame *pframe; + u32 bdstatus; + + bd = ep->c_txbd; + bdstatus = in_be32((u32 __iomem *)bd); + while (!(bdstatus & T_R) && (bdstatus & ~T_W)) { + pframe = ep->txframe; + + /* clear and recycle the BD */ + out_be32((u32 __iomem *)bd, bdstatus & T_W); + out_be32(&bd->buf, 0); + if (bdstatus & T_W) + ep->c_txbd = ep->txbase; + else + ep->c_txbd++; + + if (ep->c_txbd == ep->n_txbd) { + if (bdstatus & DEVICE_T_ERROR) { + frame_set_status(pframe, FRAME_ERROR); + if (bdstatus & T_TO) + pframe->status |= TX_ER_TIMEOUT; + if (bdstatus & T_UN) + pframe->status |= TX_ER_UNDERUN; + } + ep0_txframe_handle(ep); + } + + bd = ep->c_txbd; + bdstatus = in_be32((u32 __iomem *)bd); + } + + return 0; +} + +static int ep_txframe_handle(struct qe_ep *ep) +{ + if (frame_get_status(ep->txframe) & FRAME_ERROR) { + qe_ep_flushtxfifo(ep); + dev_vdbg(ep->udc->dev, "The EP0 transmit data have error!\n"); + if (frame_get_info(ep->txframe) & PID_DATA0) + ep->data01 = 0; + else + ep->data01 = 1; + + txcomplete(ep, 1); + } else + txcomplete(ep, 0); + + frame_create_tx(ep, ep->txframe); /* send the data */ + return 0; +} + +/* confirm the already trainsmited bd */ +static int qe_ep_txconf(struct qe_ep *ep) +{ + struct qe_bd __iomem *bd; + struct qe_frame *pframe = NULL; + u32 bdstatus; + unsigned char breakonrxinterrupt = 0; + + bd = ep->c_txbd; + bdstatus = in_be32((u32 __iomem *)bd); + while (!(bdstatus & T_R) && (bdstatus & ~T_W)) { + pframe = ep->txframe; + if (bdstatus & DEVICE_T_ERROR) { + frame_set_status(pframe, FRAME_ERROR); + if (bdstatus & T_TO) + pframe->status |= TX_ER_TIMEOUT; + if (bdstatus & T_UN) + pframe->status |= TX_ER_UNDERUN; + } + + /* clear and recycle the BD */ + out_be32((u32 __iomem *)bd, bdstatus & T_W); + out_be32(&bd->buf, 0); + if (bdstatus & T_W) + ep->c_txbd = ep->txbase; + else + ep->c_txbd++; + + /* handle the tx frame */ + ep_txframe_handle(ep); + bd = ep->c_txbd; + bdstatus = in_be32((u32 __iomem *)bd); + } + if (breakonrxinterrupt) + return -EIO; + else + return 0; +} + +/* Add a request in queue, and try to transmit a packet */ +static int ep_req_send(struct qe_ep *ep, struct qe_req *req) +{ + int reval = 0; + + if (ep->tx_req == NULL) { + ep->sent = 0; + ep->last = 0; + txcomplete(ep, 0); /* can gain a new tx_req */ + reval = frame_create_tx(ep, ep->txframe); + } + return reval; +} + +/* Maybe this is a good ideal */ +static int ep_req_rx(struct qe_ep *ep, struct qe_req *req) +{ + struct qe_udc *udc = ep->udc; + struct qe_frame *pframe = NULL; + struct qe_bd __iomem *bd; + u32 bdstatus, length; + u32 vaddr, fsize; + u8 *cp; + u8 finish_req = 0; + u8 framepid; + + if (list_empty(&ep->queue)) { + dev_vdbg(udc->dev, "the req already finish!\n"); + return 0; + } + pframe = ep->rxframe; + + bd = ep->n_rxbd; + bdstatus = in_be32((u32 __iomem *)bd); + length = bdstatus & BD_LENGTH_MASK; + + while (!(bdstatus & R_E) && length) { + if (finish_req) + break; + if ((bdstatus & R_F) && (bdstatus & R_L) + && !(bdstatus & R_ERROR)) { + qe_frame_clean(pframe); + vaddr = (u32)phys_to_virt(in_be32(&bd->buf)); + frame_set_data(pframe, (u8 *)vaddr); + frame_set_length(pframe, (length - USB_CRC_SIZE)); + frame_set_status(pframe, FRAME_OK); + switch (bdstatus & R_PID) { + case R_PID_DATA1: + frame_set_info(pframe, PID_DATA1); break; + default: + frame_set_info(pframe, PID_DATA0); break; + } + /* handle the rx frame */ + + if (frame_get_info(pframe) & PID_DATA1) + framepid = 0x1; + else + framepid = 0; + + if (framepid != ep->data01) { + dev_vdbg(udc->dev, "the data01 error!\n"); + } else { + fsize = frame_get_length(pframe); + + cp = (u8 *)(req->req.buf) + req->req.actual; + if (cp) { + memcpy(cp, pframe->data, fsize); + req->req.actual += fsize; + if ((fsize < ep->ep.maxpacket) + || (req->req.actual >= + req->req.length)) { + finish_req = 1; + done(ep, req, 0); + if (list_empty(&ep->queue)) + qe_eprx_nack(ep); + } + } + qe_ep_toggledata01(ep); + } + } else { + dev_err(udc->dev, "The receive frame with error!\n"); + } + + /* note: don't clear the rxbd's buffer address * + * only Clear the length */ + out_be32((u32 __iomem *)bd, (bdstatus & BD_STATUS_MASK)); + ep->has_data--; + + /* Get next BD */ + if (bdstatus & R_W) + bd = ep->rxbase; + else + bd++; + + bdstatus = in_be32((u32 __iomem *)bd); + length = bdstatus & BD_LENGTH_MASK; + } + + ep->n_rxbd = bd; + ep_recycle_rxbds(ep); + + return 0; +} + +/* only add the request in queue */ +static int ep_req_receive(struct qe_ep *ep, struct qe_req *req) +{ + if (ep->state == EP_STATE_NACK) { + if (ep->has_data <= 0) { + /* Enable rx and unmask rx interrupt */ + qe_eprx_normal(ep); + } else { + /* Copy the exist BD data */ + ep_req_rx(ep, req); + } + } + + return 0; +} + +/******************************************************************** + Internal Used Function End +********************************************************************/ + +/*----------------------------------------------------------------------- + Endpoint Management Functions For Gadget + -----------------------------------------------------------------------*/ +static int qe_ep_enable(struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) +{ + struct qe_udc *udc; + struct qe_ep *ep; + int retval = 0; + unsigned char epnum; + + ep = container_of(_ep, struct qe_ep, ep); + + /* catch various bogus parameters */ + if (!_ep || !desc || ep->desc || _ep->name == ep_name[0] || + (desc->bDescriptorType != USB_DT_ENDPOINT)) + return -EINVAL; + + udc = ep->udc; + if (!udc->driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) + return -ESHUTDOWN; + + epnum = (u8)desc->bEndpointAddress & 0xF; + + retval = qe_ep_init(udc, epnum, desc); + if (retval != 0) { + cpm_muram_free(cpm_muram_offset(ep->rxbase)); + dev_dbg(udc->dev, "enable ep%d failed\n", ep->epnum); + return -EINVAL; + } + dev_dbg(udc->dev, "enable ep%d successful\n", ep->epnum); + return 0; +} + +static int qe_ep_disable(struct usb_ep *_ep) +{ + struct qe_udc *udc; + struct qe_ep *ep; + unsigned long flags; + unsigned int size; + + ep = container_of(_ep, struct qe_ep, ep); + udc = ep->udc; + + if (!_ep || !ep->desc) { + dev_dbg(udc->dev, "%s not enabled\n", _ep ? ep->ep.name : NULL); + return -EINVAL; + } + + spin_lock_irqsave(&udc->lock, flags); + /* Nuke all pending requests (does flush) */ + nuke(ep, -ESHUTDOWN); + ep->desc = NULL; + ep->stopped = 1; + spin_unlock_irqrestore(&udc->lock, flags); + + cpm_muram_free(cpm_muram_offset(ep->rxbase)); + + if (ep->dir == USB_DIR_OUT) + size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * + (USB_BDRING_LEN_RX + 1); + else + size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * + (USB_BDRING_LEN + 1); + + if (ep->dir != USB_DIR_IN) { + kfree(ep->rxframe); + if (ep->rxbufmap) { + dma_unmap_single(udc_controller->gadget.dev.parent, + ep->rxbuf_d, size, + DMA_FROM_DEVICE); + ep->rxbuf_d = DMA_ADDR_INVALID; + } else { + dma_sync_single_for_cpu( + udc_controller->gadget.dev.parent, + ep->rxbuf_d, size, + DMA_FROM_DEVICE); + } + kfree(ep->rxbuffer); + } + + if (ep->dir != USB_DIR_OUT) + kfree(ep->txframe); + + dev_dbg(udc->dev, "disabled %s OK\n", _ep->name); + return 0; +} + +static struct usb_request *qe_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) +{ + struct qe_req *req; + + req = kzalloc(sizeof(*req), gfp_flags); + if (!req) + return NULL; + + req->req.dma = DMA_ADDR_INVALID; + + INIT_LIST_HEAD(&req->queue); + + return &req->req; +} + +static void qe_free_request(struct usb_ep *_ep, struct usb_request *_req) +{ + struct qe_req *req; + + req = container_of(_req, struct qe_req, req); + + if (_req) + kfree(req); +} + +/* queues (submits) an I/O request to an endpoint */ +static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, + gfp_t gfp_flags) +{ + struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); + struct qe_req *req = container_of(_req, struct qe_req, req); + struct qe_udc *udc; + unsigned long flags; + int reval; + + udc = ep->udc; + /* catch various bogus parameters */ + if (!_req || !req->req.complete || !req->req.buf + || !list_empty(&req->queue)) { + dev_dbg(udc->dev, "bad params\n"); + return -EINVAL; + } + if (!_ep || (!ep->desc && ep_index(ep))) { + dev_dbg(udc->dev, "bad ep\n"); + return -EINVAL; + } + + if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) + return -ESHUTDOWN; + + req->ep = ep; + + /* map virtual address to hardware */ + if (req->req.dma == DMA_ADDR_INVALID) { + req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, + req->req.buf, + req->req.length, + ep_is_in(ep) + ? DMA_TO_DEVICE : + DMA_FROM_DEVICE); + req->mapped = 1; + } else { + dma_sync_single_for_device(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, + ep_is_in(ep) + ? DMA_TO_DEVICE : + DMA_FROM_DEVICE); + req->mapped = 0; + } + + req->req.status = -EINPROGRESS; + req->req.actual = 0; + + list_add_tail(&req->queue, &ep->queue); + dev_vdbg(udc->dev, "gadget have request in %s! %d\n", + ep->name, req->req.length); + spin_lock_irqsave(&udc->lock, flags); + /* push the request to device */ + if (ep_is_in(ep)) + reval = ep_req_send(ep, req); + + /* EP0 */ + if (ep_index(ep) == 0 && req->req.length > 0) { + if (ep_is_in(ep)) + udc->ep0_state = DATA_STATE_XMIT; + else + udc->ep0_state = DATA_STATE_RECV; + } + + if (ep->dir == USB_DIR_OUT) + reval = ep_req_receive(ep, req); + + spin_unlock_irqrestore(&udc->lock, flags); + + return 0; +} + +/* dequeues (cancels, unlinks) an I/O request from an endpoint */ +static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) +{ + struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); + struct qe_req *req; + unsigned long flags; + + if (!_ep || !_req) + return -EINVAL; + + spin_lock_irqsave(&ep->udc->lock, flags); + + /* make sure it's actually queued on this endpoint */ + list_for_each_entry(req, &ep->queue, queue) { + if (&req->req == _req) + break; + } + + if (&req->req != _req) { + spin_unlock_irqrestore(&ep->udc->lock, flags); + return -EINVAL; + } + + done(ep, req, -ECONNRESET); + + spin_unlock_irqrestore(&ep->udc->lock, flags); + return 0; +} + +/*----------------------------------------------------------------- + * modify the endpoint halt feature + * @ep: the non-isochronous endpoint being stalled + * @value: 1--set halt 0--clear halt + * Returns zero, or a negative error code. +*----------------------------------------------------------------*/ +static int qe_ep_set_halt(struct usb_ep *_ep, int value) +{ + struct qe_ep *ep; + unsigned long flags; + int status = -EOPNOTSUPP; + struct qe_udc *udc; + + ep = container_of(_ep, struct qe_ep, ep); + if (!_ep || !ep->desc) { + status = -EINVAL; + goto out; + } + + if (ep->epnum != 0) { + status = 0; + goto out; + } + + udc = ep->udc; + /* Attempt to halt IN ep will fail if any transfer requests + * are still queue */ + if (value && ep_is_in(ep) && !list_empty(&ep->queue)) { + status = -EAGAIN; + goto out; + } + + status = 0; + spin_lock_irqsave(&ep->udc->lock, flags); + qe_eptx_stall_change(ep, value); + qe_eprx_stall_change(ep, value); + spin_unlock_irqrestore(&ep->udc->lock, flags); + + if (ep->epnum == 0) { + udc->ep0_state = WAIT_FOR_SETUP; + udc->ep0_dir = 0; + } +out: + dev_vdbg(udc->dev, " %s %s halt stat %d\n", ep->ep.name, + value ? "set" : "clear", status); + + return status; +} + +static struct usb_ep_ops qe_ep_ops = { + .enable = qe_ep_enable, + .disable = qe_ep_disable, + + .alloc_request = qe_alloc_request, + .free_request = qe_free_request, + + .queue = qe_ep_queue, + .dequeue = qe_ep_dequeue, + + .set_halt = qe_ep_set_halt, +}; + +/*------------------------------------------------------------------------ + Gadget Driver Layer Operations + ------------------------------------------------------------------------*/ + +/* Get the current frame number */ +static int qe_get_frame(struct usb_gadget *gadget) +{ + u16 tmp; + + tmp = in_be16(&udc_controller->usb_param->frame_n); + if (tmp & 0x8000) + tmp = tmp & 0x07ff; + else + tmp = -EINVAL; + + return (int)tmp; +} + +/* Tries to wake up the host connected to this gadget + * + * Return : 0-success + * Negative-this feature not enabled by host or not supported by device hw + */ +static int qe_wakeup(struct usb_gadget *gadget) +{ + return -ENOTSUPP; +} + +/* Notify controller that VBUS is powered, Called by whatever + detects VBUS sessions */ +static int qe_vbus_session(struct usb_gadget *gadget, int is_active) +{ + return -ENOTSUPP; +} + +/* constrain controller's VBUS power usage + * This call is used by gadget drivers during SET_CONFIGURATION calls, + * reporting how much power the device may consume. For example, this + * could affect how quickly batteries are recharged. + * + * Returns zero on success, else negative errno. + */ +static int qe_vbus_draw(struct usb_gadget *gadget, unsigned mA) +{ + return -ENOTSUPP; +} + +/* Change Data+ pullup status + * this func is used by usb_gadget_connect/disconnect + */ +static int qe_pullup(struct usb_gadget *gadget, int is_on) +{ + return -ENOTSUPP; +} + +/* defined in usb_gadget.h */ +static struct usb_gadget_ops qe_gadget_ops = { + .get_frame = qe_get_frame, + .wakeup = qe_wakeup, +/* .set_selfpowered = qe_set_selfpowered,*/ /* always selfpowered */ + .vbus_session = qe_vbus_session, + .vbus_draw = qe_vbus_draw, + .pullup = qe_pullup, +}; + +/*------------------------------------------------------------------------- + USB ep0 Setup process in BUS Enumeration + -------------------------------------------------------------------------*/ +static int udc_reset_ep_queue(struct qe_udc *udc, u8 pipe) +{ + struct qe_ep *ep = &udc->eps[pipe]; + + nuke(ep, -ECONNRESET); + ep->tx_req = NULL; + return 0; +} + +static int reset_queues(struct qe_udc *udc) +{ + u8 pipe; + + for (pipe = 0; pipe < USB_MAX_ENDPOINTS; pipe++) + udc_reset_ep_queue(udc, pipe); + + /* report disconnect; the driver is already quiesced */ + spin_unlock(&udc->lock); + udc->driver->disconnect(&udc->gadget); + spin_lock(&udc->lock); + + return 0; +} + +static void ch9setaddress(struct qe_udc *udc, u16 value, u16 index, + u16 length) +{ + /* Save the new address to device struct */ + udc->device_address = (u8) value; + /* Update usb state */ + udc->usb_state = USB_STATE_ADDRESS; + + /* Status phase , send a ZLP */ + if (ep0_prime_status(udc, USB_DIR_IN)) + qe_ep0_stall(udc); +} + +static void ownercomplete(struct usb_ep *_ep, struct usb_request *_req) +{ + struct qe_req *req = container_of(_req, struct qe_req, req); + + req->req.buf = NULL; + kfree(req); +} + +static void ch9getstatus(struct qe_udc *udc, u16 value, u16 index, + u16 length) +{ + u16 usb_status = 0; /* fix me to give correct status */ + + struct qe_req *req; + struct qe_ep *ep; + int status = 0; + + ep = &udc->eps[0]; + + req = container_of(qe_alloc_request(&ep->ep, GFP_KERNEL), + struct qe_req, req); + req->req.length = 2; + req->req.buf = udc->nullbuf; + memcpy(req->req.buf, (u8 *)&usb_status, 2); + req->req.status = -EINPROGRESS; + req->req.actual = 0; + req->req.complete = ownercomplete; + + udc->ep0_dir = USB_DIR_IN; + + /* data phase */ + status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC); + + if (status) { + dev_err(udc->dev, "Can't respond to getstatus request \n"); + qe_ep0_stall(udc); + } +} + +/* only handle the setup request, suppose the device in normal status */ +static void setup_received_handle(struct qe_udc *udc, + struct usb_ctrlrequest *setup) +{ + /* Fix Endian (udc->local_setup_buff is cpu Endian now)*/ + u16 wValue = le16_to_cpu(setup->wValue); + u16 wIndex = le16_to_cpu(setup->wIndex); + u16 wLength = le16_to_cpu(setup->wLength); + + /* clear the previous request in the ep0 */ + udc_reset_ep_queue(udc, 0); + + if (setup->bRequestType & USB_DIR_IN) + udc->ep0_dir = USB_DIR_IN; + else + udc->ep0_dir = USB_DIR_OUT; + + switch (setup->bRequest) { + case USB_REQ_GET_STATUS: + /* Data+Status phase form udc */ + if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) + != (USB_DIR_IN | USB_TYPE_STANDARD)) + break; + ch9getstatus(udc, wValue, wIndex, wLength); + return; + + case USB_REQ_SET_ADDRESS: + /* Status phase from udc */ + if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | + USB_RECIP_DEVICE)) + break; + ch9setaddress(udc, wValue, wIndex, wLength); + return; + + case USB_REQ_CLEAR_FEATURE: + case USB_REQ_SET_FEATURE: + /* Requests with no data phase, status phase from udc */ + if ((setup->bRequestType & USB_TYPE_MASK) + != USB_TYPE_STANDARD) + break; + + if ((setup->bRequestType & USB_RECIP_MASK) + == USB_RECIP_ENDPOINT) { + int pipe = wIndex & USB_ENDPOINT_NUMBER_MASK; + struct qe_ep *ep; + + if (wValue != 0 || wLength != 0 + || pipe > USB_MAX_ENDPOINTS) + break; + ep = &udc->eps[pipe]; + + spin_unlock(&udc->lock); + qe_ep_set_halt(&ep->ep, + (setup->bRequest == USB_REQ_SET_FEATURE) + ? 1 : 0); + spin_lock(&udc->lock); + } + + ep0_prime_status(udc, USB_DIR_IN); + + return; + + default: + break; + } + + if (wLength) { + /* Data phase from gadget, status phase from udc */ + if (setup->bRequestType & USB_DIR_IN) { + udc->ep0_state = DATA_STATE_XMIT; + udc->ep0_dir = USB_DIR_IN; + } else{ + udc->ep0_state = DATA_STATE_RECV; + udc->ep0_dir = USB_DIR_OUT; + } + spin_unlock(&udc->lock); + if (udc->driver->setup(&udc->gadget, + &udc->local_setup_buff) < 0) + qe_ep0_stall(udc); + spin_lock(&udc->lock); + } else { + /* No data phase, IN status from gadget */ + udc->ep0_dir = USB_DIR_IN; + spin_unlock(&udc->lock); + if (udc->driver->setup(&udc->gadget, + &udc->local_setup_buff) < 0) + qe_ep0_stall(udc); + spin_lock(&udc->lock); + udc->ep0_state = DATA_STATE_NEED_ZLP; + } +} + +/*------------------------------------------------------------------------- + USB Interrupt handlers + -------------------------------------------------------------------------*/ +static void suspend_irq(struct qe_udc *udc) +{ + udc->resume_state = udc->usb_state; + udc->usb_state = USB_STATE_SUSPENDED; + + /* report suspend to the driver ,serial.c not support this*/ + if (udc->driver->suspend) + udc->driver->suspend(&udc->gadget); +} + +static void resume_irq(struct qe_udc *udc) +{ + udc->usb_state = udc->resume_state; + udc->resume_state = 0; + + /* report resume to the driver , serial.c not support this*/ + if (udc->driver->resume) + udc->driver->resume(&udc->gadget); +} + +static void idle_irq(struct qe_udc *udc) +{ + u8 usbs; + + usbs = in_8(&udc->usb_regs->usb_usbs); + if (usbs & USB_IDLE_STATUS_MASK) { + if ((udc->usb_state) != USB_STATE_SUSPENDED) + suspend_irq(udc); + } else { + if (udc->usb_state == USB_STATE_SUSPENDED) + resume_irq(udc); + } +} + +static int reset_irq(struct qe_udc *udc) +{ + unsigned char i; + + qe_usb_disable(); + out_8(&udc->usb_regs->usb_usadr, 0); + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) { + if (udc->eps[i].init) + qe_ep_reset(udc, i); + } + + reset_queues(udc); + udc->usb_state = USB_STATE_DEFAULT; + udc->ep0_state = WAIT_FOR_SETUP; + udc->ep0_dir = USB_DIR_OUT; + qe_usb_enable(); + return 0; +} + +static int bsy_irq(struct qe_udc *udc) +{ + return 0; +} + +static int txe_irq(struct qe_udc *udc) +{ + return 0; +} + +/* ep0 tx interrupt also in here */ +static int tx_irq(struct qe_udc *udc) +{ + struct qe_ep *ep; + struct qe_bd __iomem *bd; + int i, res = 0; + + if ((udc->usb_state == USB_STATE_ADDRESS) + && (in_8(&udc->usb_regs->usb_usadr) == 0)) + out_8(&udc->usb_regs->usb_usadr, udc->device_address); + + for (i = (USB_MAX_ENDPOINTS-1); ((i >= 0) && (res == 0)); i--) { + ep = &udc->eps[i]; + if (ep && ep->init && (ep->dir != USB_DIR_OUT)) { + bd = ep->c_txbd; + if (!(in_be32((u32 __iomem *)bd) & T_R) + && (in_be32(&bd->buf))) { + /* Disable the TX Interrupt */ + /*confirm the transmitted bd*/ + if (ep->epnum == 0) + res = qe_ep0_txconf(ep); + else + res = qe_ep_txconf(ep); + /* Enable the TX Interrupt */ + } + } + } + return res; +} + + +/* setup packect's rx is handle in the function too */ +static void rx_irq(struct qe_udc *udc) +{ + struct qe_ep *ep; + struct qe_bd __iomem *bd; + int i; + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) { + ep = &udc->eps[i]; + if (ep && ep->init && (ep->dir != USB_DIR_IN)) { + bd = ep->n_rxbd; + if (!(in_be32((u32 __iomem *)bd) & R_E) + && (in_be32(&bd->buf))) { + if (ep->epnum == 0) { + qe_ep0_rx(udc); + } else { + /*non-setup package receive*/ + qe_ep_rx(ep); + } + } + } + } +} + +static irqreturn_t qe_udc_irq(int irq, void *_udc) +{ + struct qe_udc *udc = (struct qe_udc *)_udc; + u16 irq_src; + irqreturn_t status = IRQ_NONE; + unsigned long flags; + + + spin_lock_irqsave(&udc->lock, flags); + + irq_src = in_be16(&udc->usb_regs->usb_usber) & + in_be16(&udc->usb_regs->usb_usbmr); + /* Clear notification bits */ + out_be16(&udc->usb_regs->usb_usber, irq_src); + /* USB Interrupt */ + if (irq_src & USB_E_IDLE_MASK) { + idle_irq(udc); + irq_src &= ~USB_E_IDLE_MASK; + status = IRQ_HANDLED; + } + + if (irq_src & USB_E_TXB_MASK) { + tx_irq(udc); + irq_src &= ~USB_E_TXB_MASK; + status = IRQ_HANDLED; + } + + if (irq_src & USB_E_RXB_MASK) { + rx_irq(udc); + irq_src &= ~USB_E_RXB_MASK; + status = IRQ_HANDLED; + } + + if (irq_src & USB_E_RESET_MASK) { + reset_irq(udc); + irq_src &= ~USB_E_RESET_MASK; + status = IRQ_HANDLED; + } + + if (irq_src & USB_E_BSY_MASK) { + bsy_irq(udc); + irq_src &= ~USB_E_BSY_MASK; + status = IRQ_HANDLED; + } + + if (irq_src & USB_E_TXE_MASK) { + txe_irq(udc); + irq_src &= ~USB_E_TXE_MASK; + status = IRQ_HANDLED; + } + + spin_unlock_irqrestore(&udc->lock, flags); + + return status; +} + +/*------------------------------------------------------------------------- + Gadget driver register and unregister. + --------------------------------------------------------------------------*/ +int usb_gadget_register_driver(struct usb_gadget_driver *driver) +{ + int retval; + unsigned long flags = 0; + + /* standard operations */ + if (!udc_controller) + return -ENODEV; + + if (!driver || (driver->speed != USB_SPEED_FULL + && driver->speed != USB_SPEED_HIGH) + || !driver->bind || !driver->disconnect + || !driver->setup) + return -EINVAL; + + if (udc_controller->driver) + return -EBUSY; + + /* lock is needed but whether should use this lock or another */ + spin_lock_irqsave(&udc_controller->lock, flags); + + driver->driver.bus = NULL; + /* hook up the driver */ + udc_controller->driver = driver; + udc_controller->gadget.dev.driver = &driver->driver; + udc_controller->gadget.speed = (enum usb_device_speed)(driver->speed); + spin_unlock_irqrestore(&udc_controller->lock, flags); + + retval = driver->bind(&udc_controller->gadget); + if (retval) { + dev_err(udc_controller->dev, "bind to %s --> %d", + driver->driver.name, retval); + udc_controller->gadget.dev.driver = NULL; + udc_controller->driver = NULL; + return retval; + } + + /* Enable IRQ reg and Set usbcmd reg EN bit */ + qe_usb_enable(); + + out_be16(&udc_controller->usb_regs->usb_usber, 0xffff); + out_be16(&udc_controller->usb_regs->usb_usbmr, USB_E_DEFAULT_DEVICE); + udc_controller->usb_state = USB_STATE_ATTACHED; + udc_controller->ep0_state = WAIT_FOR_SETUP; + udc_controller->ep0_dir = USB_DIR_OUT; + dev_info(udc_controller->dev, "%s bind to driver %s \n", + udc_controller->gadget.name, driver->driver.name); + return 0; +} +EXPORT_SYMBOL(usb_gadget_register_driver); + +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +{ + struct qe_ep *loop_ep; + unsigned long flags; + + if (!udc_controller) + return -ENODEV; + + if (!driver || driver != udc_controller->driver) + return -EINVAL; + + /* stop usb controller, disable intr */ + qe_usb_disable(); + + /* in fact, no needed */ + udc_controller->usb_state = USB_STATE_ATTACHED; + udc_controller->ep0_state = WAIT_FOR_SETUP; + udc_controller->ep0_dir = 0; + + /* stand operation */ + spin_lock_irqsave(&udc_controller->lock, flags); + udc_controller->gadget.speed = USB_SPEED_UNKNOWN; + nuke(&udc_controller->eps[0], -ESHUTDOWN); + list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list, + ep.ep_list) + nuke(loop_ep, -ESHUTDOWN); + spin_unlock_irqrestore(&udc_controller->lock, flags); + + /* unbind gadget and unhook driver. */ + driver->unbind(&udc_controller->gadget); + udc_controller->gadget.dev.driver = NULL; + udc_controller->driver = NULL; + + dev_info(udc_controller->dev, "unregistered gadget driver '%s'\r\n", + driver->driver.name); + return 0; +} +EXPORT_SYMBOL(usb_gadget_unregister_driver); + +/* udc structure's alloc and setup, include ep-param alloc */ +static struct qe_udc __devinit *qe_udc_config(struct of_device *ofdev) +{ + struct qe_udc *udc; + struct device_node *np = ofdev->node; + unsigned int tmp_addr = 0; + struct usb_device_para __iomem *usbpram; + unsigned int i; + u64 size; + u32 offset; + + udc = kzalloc(sizeof(*udc), GFP_KERNEL); + if (udc == NULL) { + dev_err(&ofdev->dev, "malloc udc failed\n"); + goto cleanup; + } + + udc->dev = &ofdev->dev; + + /* get default address of usb parameter in MURAM from device tree */ + offset = *of_get_address(np, 1, &size, NULL); + udc->usb_param = cpm_muram_addr(offset); + memset_io(udc->usb_param, 0, size); + + usbpram = udc->usb_param; + out_be16(&usbpram->frame_n, 0); + out_be32(&usbpram->rstate, 0); + + tmp_addr = cpm_muram_alloc((USB_MAX_ENDPOINTS * + sizeof(struct usb_ep_para)), + USB_EP_PARA_ALIGNMENT); + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) { + out_be16(&usbpram->epptr[i], (u16)tmp_addr); + udc->ep_param[i] = cpm_muram_addr(tmp_addr); + tmp_addr += 32; + } + + memset_io(udc->ep_param[0], 0, + USB_MAX_ENDPOINTS * sizeof(struct usb_ep_para)); + + udc->resume_state = USB_STATE_NOTATTACHED; + udc->usb_state = USB_STATE_POWERED; + udc->ep0_dir = 0; + + spin_lock_init(&udc->lock); + return udc; + +cleanup: + kfree(udc); + return NULL; +} + +/* USB Controller register init */ +static int __devinit qe_udc_reg_init(struct qe_udc *udc) +{ + struct usb_ctlr __iomem *qe_usbregs; + qe_usbregs = udc->usb_regs; + + /* Init the usb register */ + out_8(&qe_usbregs->usb_usmod, 0x01); + out_be16(&qe_usbregs->usb_usbmr, 0); + out_8(&qe_usbregs->usb_uscom, 0); + out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR); + + return 0; +} + +static int __devinit qe_ep_config(struct qe_udc *udc, unsigned char pipe_num) +{ + struct qe_ep *ep = &udc->eps[pipe_num]; + + ep->udc = udc; + strcpy(ep->name, ep_name[pipe_num]); + ep->ep.name = ep_name[pipe_num]; + + ep->ep.ops = &qe_ep_ops; + ep->stopped = 1; + ep->ep.maxpacket = (unsigned short) ~0; + ep->desc = NULL; + ep->dir = 0xff; + ep->epnum = (u8)pipe_num; + ep->sent = 0; + ep->last = 0; + ep->init = 0; + ep->rxframe = NULL; + ep->txframe = NULL; + ep->tx_req = NULL; + ep->state = EP_STATE_IDLE; + ep->has_data = 0; + + /* the queue lists any req for this ep */ + INIT_LIST_HEAD(&ep->queue); + + /* gagdet.ep_list used for ep_autoconfig so no ep0*/ + if (pipe_num != 0) + list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); + + ep->gadget = &udc->gadget; + + return 0; +} + +/*----------------------------------------------------------------------- + * UDC device Driver operation functions * + *----------------------------------------------------------------------*/ +static void qe_udc_release(struct device *dev) +{ + int i = 0; + + complete(udc_controller->done); + cpm_muram_free(cpm_muram_offset(udc_controller->ep_param[0])); + for (i = 0; i < USB_MAX_ENDPOINTS; i++) + udc_controller->ep_param[i] = NULL; + + kfree(udc_controller); + udc_controller = NULL; +} + +/* Driver probe functions */ +static int __devinit qe_udc_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct device_node *np = ofdev->node; + struct qe_ep *ep; + unsigned int ret = 0; + unsigned int i; + const void *prop; + + prop = of_get_property(np, "mode", NULL); + if (!prop || strcmp(prop, "peripheral")) + return -ENODEV; + + /* Initialize the udc structure including QH member and other member */ + udc_controller = qe_udc_config(ofdev); + if (!udc_controller) { + dev_dbg(&ofdev->dev, "udc_controll is NULL\n"); + return -ENOMEM; + } + + udc_controller->soc_type = (unsigned long)match->data; + udc_controller->usb_regs = of_iomap(np, 0); + if (!udc_controller->usb_regs) { + ret = -ENOMEM; + goto err1; + } + + /* initialize usb hw reg except for regs for EP, + * leave usbintr reg untouched*/ + qe_udc_reg_init(udc_controller); + + /* here comes the stand operations for probe + * set the qe_udc->gadget.xxx */ + udc_controller->gadget.ops = &qe_gadget_ops; + + /* gadget.ep0 is a pointer */ + udc_controller->gadget.ep0 = &udc_controller->eps[0].ep; + + INIT_LIST_HEAD(&udc_controller->gadget.ep_list); + + /* modify in register gadget process */ + udc_controller->gadget.speed = USB_SPEED_UNKNOWN; + + /* name: Identifies the controller hardware type. */ + udc_controller->gadget.name = driver_name; + + device_initialize(&udc_controller->gadget.dev); + + strcpy(udc_controller->gadget.dev.bus_id, "gadget"); + + udc_controller->gadget.dev.release = qe_udc_release; + udc_controller->gadget.dev.parent = &ofdev->dev; + + + /* EP:intialization qe_ep struct */ + for (i = 0; i < USB_MAX_ENDPOINTS ; i++) { + /*because the ep type isn't decide here so + * qe_ep_init() should be called in ep_enable() */ + + /* setup the qe_ep struct and link ep.ep.list + * into gadget.ep_list */ + qe_ep_config(udc_controller, (unsigned char)i); + } + + /* ep0 initialization in here */ + ret = qe_ep_init(udc_controller, 0, &qe_ep0_desc); + if (ret) + goto err2; + + /* create a buf for ZLP send */ + udc_controller->nullbuf = kzalloc(256, GFP_KERNEL); + if (udc_controller->nullbuf == NULL) { + dev_dbg(udc_controller->dev, "cannot alloc nullbuf\n"); + ret = -ENOMEM; + goto err3; + } + + udc_controller->nullp = virt_to_phys((void *)udc_controller->nullbuf); + if (udc_controller->nullp == DMA_ADDR_INVALID) { + udc_controller->nullp = dma_map_single( + udc_controller->gadget.dev.parent, + udc_controller->nullbuf, + 256, + DMA_TO_DEVICE); + udc_controller->nullmap = 1; + } else { + dma_sync_single_for_device(udc_controller->gadget.dev.parent, + udc_controller->nullp, 256, + DMA_TO_DEVICE); + } + + tasklet_init(&udc_controller->rx_tasklet, ep_rx_tasklet, + (unsigned long)udc_controller); + /* request irq and disable DR */ + udc_controller->usb_irq = irq_of_parse_and_map(np, 0); + + ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0, + driver_name, udc_controller); + if (ret) { + dev_err(udc_controller->dev, "cannot request irq %d err %d \n", + udc_controller->usb_irq, ret); + goto err4; + } + + ret = device_add(&udc_controller->gadget.dev); + if (ret) + goto err5; + + dev_info(udc_controller->dev, + "QE/CPM USB controller initialized as device\n"); + return 0; + +err5: + free_irq(udc_controller->usb_irq, udc_controller); +err4: + if (udc_controller->nullmap) { + dma_unmap_single(udc_controller->gadget.dev.parent, + udc_controller->nullp, 256, + DMA_TO_DEVICE); + udc_controller->nullp = DMA_ADDR_INVALID; + } else { + dma_sync_single_for_cpu(udc_controller->gadget.dev.parent, + udc_controller->nullp, 256, + DMA_TO_DEVICE); + } + kfree(udc_controller->nullbuf); +err3: + ep = &udc_controller->eps[0]; + cpm_muram_free(cpm_muram_offset(ep->rxbase)); + kfree(ep->rxframe); + kfree(ep->rxbuffer); + kfree(ep->txframe); +err2: + iounmap(udc_controller->usb_regs); +err1: + kfree(udc_controller); + + return ret; +} + +#ifdef CONFIG_PM +static int qe_udc_suspend(struct of_device *dev, pm_message_t state) +{ + return -ENOTSUPP; +} + +static int qe_udc_resume(struct of_device *dev) +{ + return -ENOTSUPP; +} +#endif + +static int __devexit qe_udc_remove(struct of_device *ofdev) +{ + struct qe_ep *ep; + unsigned int size; + + DECLARE_COMPLETION(done); + + if (!udc_controller) + return -ENODEV; + + udc_controller->done = &done; + tasklet_disable(&udc_controller->rx_tasklet); + + if (udc_controller->nullmap) { + dma_unmap_single(udc_controller->gadget.dev.parent, + udc_controller->nullp, 256, + DMA_TO_DEVICE); + udc_controller->nullp = DMA_ADDR_INVALID; + } else { + dma_sync_single_for_cpu(udc_controller->gadget.dev.parent, + udc_controller->nullp, 256, + DMA_TO_DEVICE); + } + kfree(udc_controller->nullbuf); + + ep = &udc_controller->eps[0]; + cpm_muram_free(cpm_muram_offset(ep->rxbase)); + size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (USB_BDRING_LEN + 1); + + kfree(ep->rxframe); + if (ep->rxbufmap) { + dma_unmap_single(udc_controller->gadget.dev.parent, + ep->rxbuf_d, size, + DMA_FROM_DEVICE); + ep->rxbuf_d = DMA_ADDR_INVALID; + } else { + dma_sync_single_for_cpu(udc_controller->gadget.dev.parent, + ep->rxbuf_d, size, + DMA_FROM_DEVICE); + } + + kfree(ep->rxbuffer); + kfree(ep->txframe); + + free_irq(udc_controller->usb_irq, udc_controller); + + tasklet_kill(&udc_controller->rx_tasklet); + + iounmap(udc_controller->usb_regs); + + device_unregister(&udc_controller->gadget.dev); + /* wait for release() of gadget.dev to free udc */ + wait_for_completion(&done); + + return 0; +} + +/*-------------------------------------------------------------------------*/ +static struct of_device_id __devinitdata qe_udc_match[] = { + { + .compatible = "fsl,mpc8360-qe-usb", + .data = (void *)PORT_QE, + }, + { + .compatible = "fsl,mpc8272-cpm-usb", + .data = (void *)PORT_CPM, + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, qe_udc_match); + +static struct of_platform_driver udc_driver = { + .name = (char *)driver_name, + .match_table = qe_udc_match, + .probe = qe_udc_probe, + .remove = __devexit_p(qe_udc_remove), +#ifdef CONFIG_PM + .suspend = qe_udc_suspend, + .resume = qe_udc_resume, +#endif +}; + +static int __init qe_udc_init(void) +{ + printk(KERN_INFO "%s: %s, %s\n", driver_name, driver_desc, + DRIVER_VERSION); + return of_register_platform_driver(&udc_driver); +} + +static void __exit qe_udc_exit(void) +{ + of_unregister_platform_driver(&udc_driver); +} + +module_init(qe_udc_init); +module_exit(qe_udc_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); + diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/fsl_qe_udc.h new file mode 100644 index 000000000000..b4c07a22e8e7 --- /dev/null +++ b/drivers/usb/gadget/fsl_qe_udc.h @@ -0,0 +1,436 @@ +/* + * drivers/usb/gadget/qe_udc.h + * + * Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights reserved. + * + * Xiaobo Xie + * Li Yang + * + * Description: + * Freescale USB device/endpoint management registers + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#ifndef __FSL_QE_UDC_H +#define __FSL_QE_UDC_H + +/* SoC type */ +#define PORT_CPM 0 +#define PORT_QE 1 + +#define USB_MAX_ENDPOINTS 4 +#define USB_MAX_PIPES USB_MAX_ENDPOINTS +#define USB_EP0_MAX_SIZE 64 +#define USB_MAX_CTRL_PAYLOAD 0x4000 +#define USB_BDRING_LEN 16 +#define USB_BDRING_LEN_RX 256 +#define USB_BDRING_LEN_TX 16 +#define MIN_EMPTY_BDS 128 +#define MAX_DATA_BDS 8 +#define USB_CRC_SIZE 2 +#define USB_DIR_BOTH 0x88 +#define R_BUF_MAXSIZE 0x800 +#define USB_EP_PARA_ALIGNMENT 32 + +/* USB Mode Register bit define */ +#define USB_MODE_EN 0x01 +#define USB_MODE_HOST 0x02 +#define USB_MODE_TEST 0x04 +#define USB_MODE_SFTE 0x08 +#define USB_MODE_RESUME 0x40 +#define USB_MODE_LSS 0x80 + +/* USB Slave Address Register Mask */ +#define USB_SLVADDR_MASK 0x7F + +/* USB Endpoint register define */ +#define USB_EPNUM_MASK 0xF000 +#define USB_EPNUM_SHIFT 12 + +#define USB_TRANS_MODE_SHIFT 8 +#define USB_TRANS_CTR 0x0000 +#define USB_TRANS_INT 0x0100 +#define USB_TRANS_BULK 0x0200 +#define USB_TRANS_ISO 0x0300 + +#define USB_EP_MF 0x0020 +#define USB_EP_RTE 0x0010 + +#define USB_THS_SHIFT 2 +#define USB_THS_MASK 0x000c +#define USB_THS_NORMAL 0x0 +#define USB_THS_IGNORE_IN 0x0004 +#define USB_THS_NACK 0x0008 +#define USB_THS_STALL 0x000c + +#define USB_RHS_SHIFT 0 +#define USB_RHS_MASK 0x0003 +#define USB_RHS_NORMAL 0x0 +#define USB_RHS_IGNORE_OUT 0x0001 +#define USB_RHS_NACK 0x0002 +#define USB_RHS_STALL 0x0003 + +#define USB_RTHS_MASK 0x000f + +/* USB Command Register define */ +#define USB_CMD_STR_FIFO 0x80 +#define USB_CMD_FLUSH_FIFO 0x40 +#define USB_CMD_ISFT 0x20 +#define USB_CMD_DSFT 0x10 +#define USB_CMD_EP_MASK 0x03 + +/* USB Event and Mask Register define */ +#define USB_E_MSF_MASK 0x0800 +#define USB_E_SFT_MASK 0x0400 +#define USB_E_RESET_MASK 0x0200 +#define USB_E_IDLE_MASK 0x0100 +#define USB_E_TXE4_MASK 0x0080 +#define USB_E_TXE3_MASK 0x0040 +#define USB_E_TXE2_MASK 0x0020 +#define USB_E_TXE1_MASK 0x0010 +#define USB_E_SOF_MASK 0x0008 +#define USB_E_BSY_MASK 0x0004 +#define USB_E_TXB_MASK 0x0002 +#define USB_E_RXB_MASK 0x0001 +#define USBER_ALL_CLEAR 0x0fff + +#define USB_E_DEFAULT_DEVICE (USB_E_RESET_MASK | USB_E_TXE4_MASK | \ + USB_E_TXE3_MASK | USB_E_TXE2_MASK | \ + USB_E_TXE1_MASK | USB_E_BSY_MASK | \ + USB_E_TXB_MASK | USB_E_RXB_MASK) + +#define USB_E_TXE_MASK (USB_E_TXE4_MASK | USB_E_TXE3_MASK|\ + USB_E_TXE2_MASK | USB_E_TXE1_MASK) +/* USB Status Register define */ +#define USB_IDLE_STATUS_MASK 0x01 + +/* USB Start of Frame Timer */ +#define USB_USSFT_MASK 0x3FFF + +/* USB Frame Number Register */ +#define USB_USFRN_MASK 0xFFFF + +struct usb_device_para{ + u16 epptr[4]; + u32 rstate; + u32 rptr; + u16 frame_n; + u16 rbcnt; + u32 rtemp; + u32 rxusb_data; + u16 rxuptr; + u8 reso[2]; + u32 softbl; + u8 sofucrctemp; +}; + +struct usb_ep_para{ + u16 rbase; + u16 tbase; + u8 rbmr; + u8 tbmr; + u16 mrblr; + u16 rbptr; + u16 tbptr; + u32 tstate; + u32 tptr; + u16 tcrc; + u16 tbcnt; + u32 ttemp; + u16 txusbu_ptr; + u8 reserve[2]; +}; + +#define USB_BUSMODE_GBL 0x20 +#define USB_BUSMODE_BO_MASK 0x18 +#define USB_BUSMODE_BO_SHIFT 0x3 +#define USB_BUSMODE_BE 0x2 +#define USB_BUSMODE_CETM 0x04 +#define USB_BUSMODE_DTB 0x02 + +/* Endpoint basic handle */ +#define ep_index(EP) ((EP)->desc->bEndpointAddress & 0xF) +#define ep_maxpacket(EP) ((EP)->ep.maxpacket) +#define ep_is_in(EP) ((ep_index(EP) == 0) ? (EP->udc->ep0_dir == \ + USB_DIR_IN) : ((EP)->desc->bEndpointAddress \ + & USB_DIR_IN) == USB_DIR_IN) + +/* ep0 transfer state */ +#define WAIT_FOR_SETUP 0 +#define DATA_STATE_XMIT 1 +#define DATA_STATE_NEED_ZLP 2 +#define WAIT_FOR_OUT_STATUS 3 +#define DATA_STATE_RECV 4 + +/* ep tramsfer mode */ +#define USBP_TM_CTL 0 +#define USBP_TM_ISO 1 +#define USBP_TM_BULK 2 +#define USBP_TM_INT 3 + +/*----------------------------------------------------------------------------- + USB RX And TX DATA Frame + -----------------------------------------------------------------------------*/ +struct qe_frame{ + u8 *data; + u32 len; + u32 status; + u32 info; + + void *privdata; + struct list_head node; +}; + +/* Frame structure, info field. */ +#define PID_DATA0 0x80000000 /* Data toggle zero */ +#define PID_DATA1 0x40000000 /* Data toggle one */ +#define PID_SETUP 0x20000000 /* setup bit */ +#define SETUP_STATUS 0x10000000 /* setup status bit */ +#define SETADDR_STATUS 0x08000000 /* setupup address status bit */ +#define NO_REQ 0x04000000 /* Frame without request */ +#define HOST_DATA 0x02000000 /* Host data frame */ +#define FIRST_PACKET_IN_FRAME 0x01000000 /* first packet in the frame */ +#define TOKEN_FRAME 0x00800000 /* Host token frame */ +#define ZLP 0x00400000 /* Zero length packet */ +#define IN_TOKEN_FRAME 0x00200000 /* In token package */ +#define OUT_TOKEN_FRAME 0x00100000 /* Out token package */ +#define SETUP_TOKEN_FRAME 0x00080000 /* Setup token package */ +#define STALL_FRAME 0x00040000 /* Stall handshake */ +#define NACK_FRAME 0x00020000 /* Nack handshake */ +#define NO_PID 0x00010000 /* No send PID */ +#define NO_CRC 0x00008000 /* No send CRC */ +#define HOST_COMMAND 0x00004000 /* Host command frame */ + +/* Frame status field */ +/* Receive side */ +#define FRAME_OK 0x00000000 /* Frame tranmitted or received OK */ +#define FRAME_ERROR 0x80000000 /* Error occured on frame */ +#define START_FRAME_LOST 0x40000000 /* START_FRAME_LOST */ +#define END_FRAME_LOST 0x20000000 /* END_FRAME_LOST */ +#define RX_ER_NONOCT 0x10000000 /* Rx Non Octet Aligned Packet */ +#define RX_ER_BITSTUFF 0x08000000 /* Frame Aborted --Received packet + with bit stuff error */ +#define RX_ER_CRC 0x04000000 /* Received packet with CRC error */ +#define RX_ER_OVERUN 0x02000000 /* Over-run occured on reception */ +#define RX_ER_PID 0x01000000 /* Wrong PID received */ +/* Tranmit side */ +#define TX_ER_NAK 0x00800000 /* Received NAK handshake */ +#define TX_ER_STALL 0x00400000 /* Received STALL handshake */ +#define TX_ER_TIMEOUT 0x00200000 /* Transmit time out */ +#define TX_ER_UNDERUN 0x00100000 /* Transmit underrun */ +#define FRAME_INPROGRESS 0x00080000 /* Frame is being transmitted */ +#define ER_DATA_UNDERUN 0x00040000 /* Frame is shorter then expected */ +#define ER_DATA_OVERUN 0x00020000 /* Frame is longer then expected */ + +/* QE USB frame operation functions */ +#define frame_get_length(frm) (frm->len) +#define frame_set_length(frm, leng) (frm->len = leng) +#define frame_get_data(frm) (frm->data) +#define frame_set_data(frm, dat) (frm->data = dat) +#define frame_get_info(frm) (frm->info) +#define frame_set_info(frm, inf) (frm->info = inf) +#define frame_get_status(frm) (frm->status) +#define frame_set_status(frm, stat) (frm->status = stat) +#define frame_get_privdata(frm) (frm->privdata) +#define frame_set_privdata(frm, dat) (frm->privdata = dat) + +static inline void qe_frame_clean(struct qe_frame *frm) +{ + frame_set_data(frm, NULL); + frame_set_length(frm, 0); + frame_set_status(frm, FRAME_OK); + frame_set_info(frm, 0); + frame_set_privdata(frm, NULL); +} + +static inline void qe_frame_init(struct qe_frame *frm) +{ + qe_frame_clean(frm); + INIT_LIST_HEAD(&(frm->node)); +} + +struct qe_req { + struct usb_request req; + struct list_head queue; + /* ep_queue() func will add + a request->queue into a udc_ep->queue 'd tail */ + struct qe_ep *ep; + unsigned mapped:1; +}; + +struct qe_ep { + struct usb_ep ep; + struct list_head queue; + struct qe_udc *udc; + const struct usb_endpoint_descriptor *desc; + struct usb_gadget *gadget; + + u8 state; + + struct qe_bd __iomem *rxbase; + struct qe_bd __iomem *n_rxbd; + struct qe_bd __iomem *e_rxbd; + + struct qe_bd __iomem *txbase; + struct qe_bd __iomem *n_txbd; + struct qe_bd __iomem *c_txbd; + + struct qe_frame *rxframe; + u8 *rxbuffer; + dma_addr_t rxbuf_d; + u8 rxbufmap; + unsigned char localnack; + int has_data; + + struct qe_frame *txframe; + struct qe_req *tx_req; + int sent; /*data already sent */ + int last; /*data sent in the last time*/ + + u8 dir; + u8 epnum; + u8 tm; /* transfer mode */ + u8 data01; + u8 init; + + u8 already_seen; + u8 enable_tasklet; + u8 setup_stage; + u32 last_io; /* timestamp */ + + char name[14]; + + unsigned double_buf:1; + unsigned stopped:1; + unsigned fnf:1; + unsigned has_dma:1; + + u8 ackwait; + u8 dma_channel; + u16 dma_counter; + int lch; + + struct timer_list timer; +}; + +struct qe_udc { + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + struct device *dev; + struct qe_ep eps[USB_MAX_ENDPOINTS]; + struct usb_ctrlrequest local_setup_buff; + spinlock_t lock; /* lock for set/config qe_udc */ + unsigned long soc_type; /* QE or CPM soc */ + + struct qe_req *status_req; /* ep0 status request */ + + /* USB and EP Parameter Block pointer */ + struct usb_device_para __iomem *usb_param; + struct usb_ep_para __iomem *ep_param[4]; + + u32 max_pipes; /* Device max pipes */ + u32 max_use_endpts; /* Max endpointes to be used */ + u32 bus_reset; /* Device is bus reseting */ + u32 resume_state; /* USB state to resume*/ + u32 usb_state; /* USB current state */ + u32 usb_next_state; /* USB next state */ + u32 ep0_state; /* Enpoint zero state */ + u32 ep0_dir; /* Enpoint zero direction: can be + USB_DIR_IN or USB_DIR_OUT*/ + u32 usb_sof_count; /* SOF count */ + u32 errors; /* USB ERRORs count */ + + u8 *tmpbuf; + u32 c_start; + u32 c_end; + + u8 *nullbuf; + dma_addr_t nullp; + u8 nullmap; + u8 device_address; /* Device USB address */ + + unsigned int usb_clock; + unsigned int usb_irq; + struct usb_ctlr __iomem *usb_regs; + + struct tasklet_struct rx_tasklet; + + struct completion *done; /* to make sure release() is done */ +}; + +#define EP_STATE_IDLE 0 +#define EP_STATE_NACK 1 +#define EP_STATE_STALL 2 + +/* + * transmit BD's status + */ +#define T_R 0x80000000 /* ready bit */ +#define T_W 0x20000000 /* wrap bit */ +#define T_I 0x10000000 /* interrupt on completion */ +#define T_L 0x08000000 /* last */ +#define T_TC 0x04000000 /* transmit CRC */ +#define T_CNF 0x02000000 /* wait for transmit confirm */ +#define T_LSP 0x01000000 /* Low-speed transaction */ +#define T_PID 0x00c00000 /* packet id */ +#define T_NAK 0x00100000 /* No ack. */ +#define T_STAL 0x00080000 /* Stall recieved */ +#define T_TO 0x00040000 /* time out */ +#define T_UN 0x00020000 /* underrun */ + +#define DEVICE_T_ERROR (T_UN | T_TO) +#define HOST_T_ERROR (T_UN | T_TO | T_NAK | T_STAL) +#define DEVICE_T_BD_MASK DEVICE_T_ERROR +#define HOST_T_BD_MASK HOST_T_ERROR + +#define T_PID_SHIFT 6 +#define T_PID_DATA0 0x00800000 /* Data 0 toggle */ +#define T_PID_DATA1 0x00c00000 /* Data 1 toggle */ + +/* + * receive BD's status + */ +#define R_E 0x80000000 /* buffer empty */ +#define R_W 0x20000000 /* wrap bit */ +#define R_I 0x10000000 /* interrupt on reception */ +#define R_L 0x08000000 /* last */ +#define R_F 0x04000000 /* first */ +#define R_PID 0x00c00000 /* packet id */ +#define R_NO 0x00100000 /* Rx Non Octet Aligned Packet */ +#define R_AB 0x00080000 /* Frame Aborted */ +#define R_CR 0x00040000 /* CRC Error */ +#define R_OV 0x00020000 /* Overrun */ + +#define R_ERROR (R_NO | R_AB | R_CR | R_OV) +#define R_BD_MASK R_ERROR + +#define R_PID_DATA0 0x00000000 +#define R_PID_DATA1 0x00400000 +#define R_PID_SETUP 0x00800000 + +#define CPM_USB_STOP_TX 0x2e600000 +#define CPM_USB_RESTART_TX 0x2e600000 +#define CPM_USB_STOP_TX_OPCODE 0x0a +#define CPM_USB_RESTART_TX_OPCODE 0x0b +#define CPM_USB_EP_SHIFT 5 + +#ifndef CONFIG_CPM +inline int cpm_command(u32 command, u8 opcode) +{ + return -EOPNOTSUPP; +} +#endif + +#ifndef CONFIG_QUICC_ENGINE +inline int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, + u32 cmd_input) +{ + return -EOPNOTSUPP; +} +#endif + +#endif /* __FSL_QE_UDC_H */ diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 17d9905101b7..4e3107dd2f34 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -151,6 +151,13 @@ #define gadget_is_m66592(g) 0 #endif +/* Freescale CPM/QE UDC SUPPORT */ +#ifdef CONFIG_USB_GADGET_FSL_QE +#define gadget_is_fsl_qe(g) !strcmp("fsl_qe_udc", (g)->name) +#else +#define gadget_is_fsl_qe(g) 0 +#endif + // CONFIG_USB_GADGET_SX2 // CONFIG_USB_GADGET_AU1X00 @@ -216,6 +223,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x20; else if (gadget_is_m66592(gadget)) return 0x21; + else if (gadget_is_fsl_qe(gadget)) + return 0x22; return -ENOENT; } -- cgit v1.2.3 From 8bfa24727087d7252f9ecfb5fea2dfc92d797fbd Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 2 Sep 2008 10:12:11 -0400 Subject: usb-storage: report underflow with no sense data This patch (as1118) addresses a problem with certain USB mass-storage devices. These devices sometimes return less data than asked for and then provide no sense data to explain the problem. Currently usb-storage leaves it up to the SCSI layer to decide how this should be handled, and the SCSI layer interprets the lack of sense data to mean that nothing went wrong. But if we got less data than required then something definitely _did_ go wrong, and we should say so. The patch tells the SCSI layer to retry the command when this sort of thing happens. Retrying may not solve the underlying problem, but it's better than believing that data was transferred when it wasn't. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 3523a0bfa0ff..79108d5d3171 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -663,7 +663,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) } /* Did we transfer less than the minimum amount required? */ - if (srb->result == SAM_STAT_GOOD && + if ((srb->result == SAM_STAT_GOOD || srb->sense_buffer[2] == 0) && scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow) srb->result = (DID_ERROR << 16) | (SUGGEST_RETRY << 24); -- cgit v1.2.3 From 4a511bc3f5829bc18428bcf11c25417a79d09396 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 3 Sep 2008 16:38:32 -0400 Subject: OHCI: Allow broken controllers to auto-stop This patch (as1134) attempts to improve the way we handle OHCI controllers with broken Root Hub Status Change interrupt support. In these controllers the RHSC interrupt bit essentially never turns off, making RHSC interrupts useless -- they have to remain permanently disabled. Such controllers should still be allowed to turn off their root hubs when no devices are attached. Polling for new connections can continue while the root hub is suspended. The patch implements this feature. (It won't have much effect unless CONFIG_PM is enabled and CONFIG_USB_SUSPEND is disabled, but since the overhead is very small we may as well do it.) Signed-off-by: Alan Stern Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hub.c | 60 ++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 7ea9a7b31155..a150e85c901a 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -362,18 +362,23 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, int any_connected) { int poll_rh = 1; - int rhsc; + int rhsc_status, rhsc_enable; - rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC; - switch (ohci->hc_control & OHCI_CTRL_HCFS) { + /* Some broken controllers never turn off RHCS in the interrupt + * status register. For their sake we won't re-enable RHSC + * interrupts if the interrupt bit is already active. + */ + rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) & + OHCI_INTR_RHSC; + rhsc_enable = ohci_readl(ohci, &ohci->regs->intrenable) & + OHCI_INTR_RHSC; + switch (ohci->hc_control & OHCI_CTRL_HCFS) { case OHCI_USB_OPER: - /* If no status changes are pending, enable status-change - * interrupts. - */ - if (!rhsc && !changed) { - rhsc = OHCI_INTR_RHSC; - ohci_writel(ohci, rhsc, &ohci->regs->intrenable); + /* If no status changes are pending, enable RHSC interrupts. */ + if (!rhsc_enable && !rhsc_status && !changed) { + rhsc_enable = OHCI_INTR_RHSC; + ohci_writel(ohci, rhsc_enable, &ohci->regs->intrenable); } /* Keep on polling until we know a device is connected @@ -383,7 +388,7 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, if (any_connected || !device_may_wakeup(&ohci_to_hcd(ohci) ->self.root_hub->dev)) { - if (rhsc) + if (rhsc_enable) poll_rh = 0; } else { ohci->autostop = 1; @@ -396,34 +401,36 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, ohci->autostop = 0; ohci->next_statechange = jiffies + STATECHANGE_DELAY; - } else if (rhsc && time_after_eq(jiffies, + } else if (time_after_eq(jiffies, ohci->next_statechange) && !ohci->ed_rm_list && !(ohci->hc_control & OHCI_SCHED_ENABLES)) { ohci_rh_suspend(ohci, 1); - poll_rh = 0; + if (rhsc_enable) + poll_rh = 0; } } break; - /* if there is a port change, autostart or ask to be resumed */ case OHCI_USB_SUSPEND: case OHCI_USB_RESUME: + /* if there is a port change, autostart or ask to be resumed */ if (changed) { if (ohci->autostop) ohci_rh_resume(ohci); else usb_hcd_resume_root_hub(ohci_to_hcd(ohci)); } else { - if (!rhsc && (ohci->autostop || + if (!rhsc_enable && !rhsc_status && (ohci->autostop || ohci_to_hcd(ohci)->self.root_hub-> - do_remote_wakeup)) - ohci_writel(ohci, OHCI_INTR_RHSC, + do_remote_wakeup)) { + rhsc_enable = OHCI_INTR_RHSC; + ohci_writel(ohci, rhsc_enable, &ohci->regs->intrenable); - - /* everything is idle, no need for polling */ - poll_rh = 0; + } + if (rhsc_enable) + poll_rh = 0; } break; } @@ -443,12 +450,16 @@ static inline int ohci_rh_resume(struct ohci_hcd *ohci) static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, int any_connected) { + int rhsc_status; + /* If RHSC is enabled, don't poll */ if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC) return 0; - /* If no status changes are pending, enable status-change interrupts */ - if (!changed) { + /* If no status changes are pending, enable RHSC interrupts */ + rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) & + OHCI_INTR_RHSC; + if (!changed && !rhsc_status) { ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); return 0; } @@ -492,13 +503,6 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) length++; } - /* Some broken controllers never turn off RHCS in the interrupt - * status register. For their sake we won't re-enable RHSC - * interrupts if the flag is already set. - */ - if (ohci_readl(ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC) - changed = 1; - /* look at each port */ for (i = 0; i < ohci->num_ports; i++) { u32 status = roothub_portstatus (ohci, i); -- cgit v1.2.3 From d1b1944085ab2345fae4a5fbb614f1a4d0732d3e Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 2 Sep 2008 14:16:11 +0200 Subject: USB: Documentation/usb/anchors.txt #2 This adds Documentation for the extensions of the anchor API. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/anchors.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Documentation/usb/anchors.txt b/Documentation/usb/anchors.txt index 5e6b64c20d25..6f24f566955a 100644 --- a/Documentation/usb/anchors.txt +++ b/Documentation/usb/anchors.txt @@ -52,6 +52,11 @@ Therefore no guarantee is made that the URBs have been unlinked when the call returns. They may be unlinked later but will be unlinked in finite time. +usb_scuttle_anchored_urbs() +--------------------------- + +All URBs of an anchor are unanchored en masse. + usb_wait_anchor_empty_timeout() ------------------------------- @@ -59,4 +64,16 @@ This function waits for all URBs associated with an anchor to finish or a timeout, whichever comes first. Its return value will tell you whether the timeout was reached. +usb_anchor_empty() +------------------ + +Returns true if no URBs are associated with an anchor. Locking +is the caller's responsibility. + +usb_get_from_anchor() +--------------------- +Returns the oldest anchored URB of an anchor. The URB is unanchored +and returned with a reference. As you may mix URBs to several +destinations in one anchor you have no guarantee the chronologically +first submitted URB is returned. \ No newline at end of file -- cgit v1.2.3 From bc45df950d30b9b23bd8373dcc22e58c4fb075ed Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Mon, 8 Sep 2008 10:14:47 +0200 Subject: usb core: fix USB_OTG_BLACKLIST_HUB typo Signed-off-by: Peter Korsgaard Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index cc9f397e8398..e1759d17ac5d 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -134,5 +134,5 @@ config USB_OTG_BLACKLIST_HUB If you say Y here, then Linux will refuse to enumerate external hubs. OTG hosts are allowed to reduce hardware and software costs by not supporting external hubs. So - are "Emedded Hosts" that don't offer OTG support. + are "Embedded Hosts" that don't offer OTG support. -- cgit v1.2.3 From 682650437e7acef01e914a7fb6ef16da16bb69c5 Mon Sep 17 00:00:00 2001 From: Paulius Zaleckas Date: Wed, 10 Sep 2008 17:18:46 +0300 Subject: USB: ftdi_sio: fix 'product' parameter description Signed-off-by: Paulius Zaleckas Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ef3dc1a61b61..89dab5c3682c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2459,5 +2459,5 @@ module_param(vendor, ushort, 0); MODULE_PARM_DESC(vendor, "User specified vendor ID (default=" __MODULE_STRING(FTDI_VID)")"); module_param(product, ushort, 0); -MODULE_PARM_DESC(vendor, "User specified product ID"); +MODULE_PARM_DESC(product, "User specified product ID"); -- cgit v1.2.3 From 399d31da4e2f701ba91cdb4b39e074d6e16174a9 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 15 Sep 2008 17:29:28 +0200 Subject: USB: RESET_RESUME needs to block autosuspend when remote wakeup is needed Reset upon resumption will wipe the input buffer and is therefore a reason to not suspend if remote wakeup is requested because the driver needs that data. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 5a7fa6f09958..e935be7eb468 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1070,7 +1070,8 @@ static int autosuspend_check(struct usb_device *udev, int reschedule) struct usb_driver *driver; driver = to_usb_driver(intf->dev.driver); - if (!driver->reset_resume) + if (!driver->reset_resume || + intf->needs_remote_wakeup) return -EOPNOTSUPP; } } -- cgit v1.2.3 From 7384a922b5a716b4e9dbcdce738f2b2104892008 Mon Sep 17 00:00:00 2001 From: Kevin Lloyd Date: Tue, 16 Sep 2008 21:05:24 -0700 Subject: USB Serial: Sierra: debug message fix This patch moves dbg calls to dev_dbg where possible. It also fixes some issues with a previous submission aiming to do the same thing. Signed-off-by: Kevin Lloyd Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 69 +++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 8b9eaf383679..6794e5721df6 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -247,7 +247,7 @@ static int sierra_send_setup(struct tty_struct *tty, struct sierra_port_private *portdata; __u16 interface = 0; - dbg("%s", __func__); + dev_dbg(&port->dev, "%s", __func__); portdata = usb_get_serial_port_data(port); @@ -284,7 +284,7 @@ static int sierra_send_setup(struct tty_struct *tty, static void sierra_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { - dbg("%s", __func__); + dev_dbg(&port->dev, "%s", __func__); tty_termios_copy_hw(tty->termios, old_termios); sierra_send_setup(tty, port); } @@ -295,6 +295,7 @@ static int sierra_tiocmget(struct tty_struct *tty, struct file *file) unsigned int value; struct sierra_port_private *portdata; + dev_dbg(&port->dev, "%s", __func__); portdata = usb_get_serial_port_data(port); value = ((portdata->rts_state) ? TIOCM_RTS : 0) | @@ -334,14 +335,14 @@ static void sierra_outdat_callback(struct urb *urb) int status = urb->status; unsigned long flags; - dbg("%s - port %d", __func__, port->number); + dev_dbg(&port->dev, "%s - port %d", __func__, port->number); /* free up the transfer buffer, as usb_free_urb() does not do this */ kfree(urb->transfer_buffer); if (status) - dbg("%s - nonzero write bulk status received: %d", - __func__, status); + dev_dbg(&port->dev, "%s - nonzero write bulk status " + "received: %d", __func__, status); spin_lock_irqsave(&portdata->lock, flags); --portdata->outstanding_urbs; @@ -363,12 +364,12 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, portdata = usb_get_serial_port_data(port); - dbg("%s: write (%d chars)", __func__, count); + dev_dbg(&port->dev, "%s: write (%d chars)", __func__, count); spin_lock_irqsave(&portdata->lock, flags); if (portdata->outstanding_urbs > N_OUT_URB) { spin_unlock_irqrestore(&portdata->lock, flags); - dbg("%s - write limit hit\n", __func__); + dev_dbg(&port->dev, "%s - write limit hit\n", __func__); return 0; } portdata->outstanding_urbs++; @@ -437,8 +438,8 @@ static void sierra_indat_callback(struct urb *urb) port = urb->context; if (status) { - dbg("%s: nonzero status: %d on endpoint %02x.", - __func__, status, endpoint); + dev_dbg(&port->dev, "%s: nonzero status: %d on" + " endpoint %02x.", __func__, status, endpoint); } else { if (urb->actual_length) { tty = tty_port_tty_get(&port->port); @@ -447,7 +448,8 @@ static void sierra_indat_callback(struct urb *urb) tty_flip_buffer_push(tty); tty_kref_put(tty); } else - dbg("%s: empty read urb received", __func__); + dev_dbg(&port->dev, "%s: empty read urb" + " received", __func__); /* Resubmit urb so we continue receiving */ if (port->port.count && status != -ESHUTDOWN) { @@ -468,15 +470,17 @@ static void sierra_instat_callback(struct urb *urb) struct sierra_port_private *portdata = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; - dbg("%s", __func__); - dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); + dev_dbg(&port->dev, "%s", __func__); + dev_dbg(&port->dev, "%s: urb %p port %p has data %p", __func__, + urb, port, portdata); if (status == 0) { struct usb_ctrlrequest *req_pkt = (struct usb_ctrlrequest *)urb->transfer_buffer; if (!req_pkt) { - dbg("%s: NULL req_pkt\n", __func__); + dev_dbg(&port->dev, "%s: NULL req_pkt\n", + __func__); return; } if ((req_pkt->bRequestType == 0xA1) && @@ -487,7 +491,8 @@ static void sierra_instat_callback(struct urb *urb) sizeof(struct usb_ctrlrequest)); struct tty_struct *tty; - dbg("%s: signal x%x", __func__, signals); + dev_dbg(&port->dev, "%s: signal x%x", __func__, + signals); old_dcd_state = portdata->dcd_state; portdata->cts_state = 1; @@ -501,19 +506,20 @@ static void sierra_instat_callback(struct urb *urb) tty_hangup(tty); tty_kref_put(tty); } else { - dbg("%s: type %x req %x", __func__, - req_pkt->bRequestType, req_pkt->bRequest); + dev_dbg(&port->dev, "%s: type %x req %x", + __func__, req_pkt->bRequestType, + req_pkt->bRequest); } } else - dbg("%s: error %d", __func__, status); + dev_dbg(&port->dev, "%s: error %d", __func__, status); /* Resubmit urb so we continue receiving IRQ data */ if (status != -ESHUTDOWN) { urb->dev = serial->dev; err = usb_submit_urb(urb, GFP_ATOMIC); if (err) - dbg("%s: resubmit intr urb failed. (%d)", - __func__, err); + dev_dbg(&port->dev, "%s: resubmit intr urb " + "failed. (%d)", __func__, err); } } @@ -523,14 +529,14 @@ static int sierra_write_room(struct tty_struct *tty) struct sierra_port_private *portdata = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __func__, port->number); + dev_dbg(&port->dev, "%s - port %d", __func__, port->number); /* try to give a good number back based on if we have any free urbs at * this point in time */ spin_lock_irqsave(&portdata->lock, flags); if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) { spin_unlock_irqrestore(&portdata->lock, flags); - dbg("%s - write limit hit\n", __func__); + dev_dbg(&port->dev, "%s - write limit hit\n", __func__); return 0; } spin_unlock_irqrestore(&portdata->lock, flags); @@ -549,7 +555,7 @@ static int sierra_open(struct tty_struct *tty, portdata = usb_get_serial_port_data(port); - dbg("%s", __func__); + dev_dbg(&port->dev, "%s", __func__); /* Set some sane defaults */ portdata->rts_state = 1; @@ -561,8 +567,8 @@ static int sierra_open(struct tty_struct *tty, if (!urb) continue; if (urb->dev != serial->dev) { - dbg("%s: dev %p != %p", __func__, - urb->dev, serial->dev); + dev_dbg(&port->dev, "%s: dev %p != %p", + __func__, urb->dev, serial->dev); continue; } @@ -601,7 +607,7 @@ static void sierra_close(struct tty_struct *tty, struct usb_serial *serial = port->serial; struct sierra_port_private *portdata; - dbg("%s", __func__); + dev_dbg(&port->dev, "%s", __func__); portdata = usb_get_serial_port_data(port); portdata->rts_state = 0; @@ -630,7 +636,7 @@ static int sierra_startup(struct usb_serial *serial) int i; int j; - dbg("%s", __func__); + dev_dbg(&serial->dev->dev, "%s", __func__); /* Set Device mode to D0 */ sierra_set_power_state(serial->dev, 0x0000); @@ -644,8 +650,9 @@ static int sierra_startup(struct usb_serial *serial) port = serial->port[i]; portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); if (!portdata) { - dbg("%s: kmalloc for sierra_port_private (%d) failed!.", - __func__, i); + dev_dbg(&port->dev, "%s: kmalloc for " + "sierra_port_private (%d) failed!.", + __func__, i); return -ENOMEM; } spin_lock_init(&portdata->lock); @@ -665,8 +672,8 @@ static int sierra_startup(struct usb_serial *serial) for (j = 0; j < N_IN_URB; ++j) { urb = usb_alloc_urb(0, GFP_KERNEL); if (urb == NULL) { - dbg("%s: alloc for in port failed.", - __func__); + dev_dbg(&port->dev, "%s: alloc for in " + "port failed.", __func__); continue; } /* Fill URB using supplied data. */ @@ -688,7 +695,7 @@ static void sierra_shutdown(struct usb_serial *serial) struct usb_serial_port *port; struct sierra_port_private *portdata; - dbg("%s", __func__); + dev_dbg(&serial->dev->dev, "%s", __func__); for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; -- cgit v1.2.3 From 81ab5b8ee6b8cd5fe8cfdf0eea84eea0aa7b4da9 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Sat, 20 Sep 2008 14:41:47 -0700 Subject: USB: Fix doc for usb_autopm_enable Correct errors in the descriptions for usb_autopm_enable and usb_autopm_disable in the USB PM doc. Signed-off-by: Geoff Levand Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/power-management.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt index 9d31140e3f5b..e48ea1d51010 100644 --- a/Documentation/usb/power-management.txt +++ b/Documentation/usb/power-management.txt @@ -350,12 +350,12 @@ without holding the mutex. There also are a couple of utility routines drivers can use: - usb_autopm_enable() sets pm_usage_cnt to 1 and then calls - usb_autopm_set_interface(), which will attempt an autoresume. - - usb_autopm_disable() sets pm_usage_cnt to 0 and then calls + usb_autopm_enable() sets pm_usage_cnt to 0 and then calls usb_autopm_set_interface(), which will attempt an autosuspend. + usb_autopm_disable() sets pm_usage_cnt to 1 and then calls + usb_autopm_set_interface(), which will attempt an autoresume. + The conventional usage pattern is that a driver calls usb_autopm_get_interface() in its open routine and usb_autopm_put_interface() in its close or release routine. But -- cgit v1.2.3 From 0b14c3881d4b91272b779f4037e263d392de058f Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Sat, 20 Sep 2008 14:41:47 -0700 Subject: USB: Fix spelling in usb/serial.h Fixes a minor typo in the comments for usb_set_serial_data. Signed-off-by: Geoff Levand Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/serial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 655341d0f534..0b8617a9176d 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -192,7 +192,7 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data) * The driver.owner field should be set to the module owner of this driver. * The driver.name field should be set to the name of this driver (remember * it will show up in sysfs, so it needs to be short and to the point. - * Useing the module name is a good idea.) + * Using the module name is a good idea.) */ struct usb_serial_driver { const char *description; -- cgit v1.2.3 From 8296345a35551414b07419f4c9223734c1fc5437 Mon Sep 17 00:00:00 2001 From: SangSu Park Date: Mon, 22 Sep 2008 15:41:15 -0700 Subject: USB: g_printer: fix handling zero-length packet g_printer doesn't have to check whether the data size is a multiple of MaxPacketSize, because device controller driver already make that check. Signed-off-by: SangSu Park Cc: Alan Stern Cc: David Brownell Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/printer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 2b3b9e1dd2ee..00b7ed5013a6 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -1278,8 +1278,7 @@ unknown: /* respond with data transfer before status phase? */ if (value >= 0) { req->length = value; - req->zero = value < wLength - && (value % gadget->ep0->maxpacket) == 0; + req->zero = value < wLength; value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); if (value < 0) { DBG(dev, "ep_queue --> %d\n", value); -- cgit v1.2.3 From 549c41e0ac0a3eb68cfdaeb43c1a314e2a6c289a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 19 Sep 2008 02:00:02 +0300 Subject: usb: gadget: workaround storage command size issues Try to workaround issues with bad SCSI implementations by ignoring the command size error. Signed-off-by: Felipe Balbi Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/file_storage.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 0c632d22a631..e0f616f39ba0 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -2676,11 +2676,24 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, /* Verify the length of the command itself */ if (cmnd_size != fsg->cmnd_size) { - /* Special case workaround: MS-Windows issues REQUEST SENSE - * with cbw->Length == 12 (it should be 6). */ - if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12) + /* Special case workaround: There are plenty of buggy SCSI + * implementations. Many have issues with cbw->Length + * field passing a wrong command size. For those cases we + * always try to work around the problem by using the length + * sent by the host side provided it is at least as large + * as the correct command length. + * Examples of such cases would be MS-Windows, which issues + * REQUEST SENSE with cbw->Length == 12 where it should + * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and + * REQUEST SENSE with cbw->Length == 10 where it should + * be 6 as well. + */ + if (cmnd_size <= fsg->cmnd_size) { + DBG(fsg, "%s is buggy! Expected length %d " + "but we got %d\n", name, + cmnd_size, fsg->cmnd_size); cmnd_size = fsg->cmnd_size; - else { + } else { fsg->phase_error = 1; return -EINVAL; } -- cgit v1.2.3 From 3c04e20ea95f9a8555456000e0ff340bdc46dea8 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Thu, 18 Sep 2008 23:06:21 +0800 Subject: USB: ehci-dbg: increase debug buffer size for periodic file This patch is based on the following ideas: 1. Some usb devices (such as usb video class) have endpoints of high interval attribute, so reading "periodic" file need more debug buffer to accommodate the qh or itd schedule information. For example, 4KB buffer is not enough for a single interrupt qh of 2ms period. 2. print a %p need 16 byte buffer on 64-bits arch, but 8 byte on 32-bits arch. Add a extra bonus for 64-bits arch. Signed-off-by: Ming Lei Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-dbg.c | 44 +++++++++++++++++++++++++------------------- drivers/usb/host/ehci-hcd.c | 1 + 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index b0f8ed5a7fb9..9534ff3f5e7b 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -358,7 +358,8 @@ struct debug_buffer { struct usb_bus *bus; struct mutex mutex; /* protect filling of buffer */ size_t count; /* number of characters filled into buffer */ - char *page; + char *output_buf; + size_t alloc_size; }; #define speed_char(info1) ({ char tmp; \ @@ -488,8 +489,8 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf) hcd = bus_to_hcd(buf->bus); ehci = hcd_to_ehci (hcd); - next = buf->page; - size = PAGE_SIZE; + next = buf->output_buf; + size = buf->alloc_size; *next = 0; @@ -510,7 +511,7 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf) } spin_unlock_irqrestore (&ehci->lock, flags); - return strlen(buf->page); + return strlen(buf->output_buf); } #define DBG_SCHED_LIMIT 64 @@ -531,8 +532,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) hcd = bus_to_hcd(buf->bus); ehci = hcd_to_ehci (hcd); - next = buf->page; - size = PAGE_SIZE; + next = buf->output_buf; + size = buf->alloc_size; temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size); size -= temp; @@ -649,7 +650,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) spin_unlock_irqrestore (&ehci->lock, flags); kfree (seen); - return PAGE_SIZE - size; + return buf->alloc_size - size; } #undef DBG_SCHED_LIMIT @@ -665,8 +666,8 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) hcd = bus_to_hcd(buf->bus); ehci = hcd_to_ehci (hcd); - next = buf->page; - size = PAGE_SIZE; + next = buf->output_buf; + size = buf->alloc_size; spin_lock_irqsave (&ehci->lock, flags); @@ -808,7 +809,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) done: spin_unlock_irqrestore (&ehci->lock, flags); - return PAGE_SIZE - size; + return buf->alloc_size - size; } static struct debug_buffer *alloc_buffer(struct usb_bus *bus, @@ -822,6 +823,7 @@ static struct debug_buffer *alloc_buffer(struct usb_bus *bus, buf->bus = bus; buf->fill_func = fill_func; mutex_init(&buf->mutex); + buf->alloc_size = PAGE_SIZE; } return buf; @@ -831,10 +833,10 @@ static int fill_buffer(struct debug_buffer *buf) { int ret = 0; - if (!buf->page) - buf->page = (char *)get_zeroed_page(GFP_KERNEL); + if (!buf->output_buf) + buf->output_buf = (char *)vmalloc(buf->alloc_size); - if (!buf->page) { + if (!buf->output_buf) { ret = -ENOMEM; goto out; } @@ -867,7 +869,7 @@ static ssize_t debug_output(struct file *file, char __user *user_buf, mutex_unlock(&buf->mutex); ret = simple_read_from_buffer(user_buf, len, offset, - buf->page, buf->count); + buf->output_buf, buf->count); out: return ret; @@ -879,8 +881,8 @@ static int debug_close(struct inode *inode, struct file *file) struct debug_buffer *buf = file->private_data; if (buf) { - if (buf->page) - free_page((unsigned long)buf->page); + if (buf->output_buf) + vfree(buf->output_buf); kfree(buf); } @@ -895,10 +897,14 @@ static int debug_async_open(struct inode *inode, struct file *file) static int debug_periodic_open(struct inode *inode, struct file *file) { - file->private_data = alloc_buffer(inode->i_private, - fill_periodic_buffer); + struct debug_buffer *buf; + buf = alloc_buffer(inode->i_private, fill_periodic_buffer); + if (!buf) + return -ENOMEM; - return file->private_data ? 0 : -ENOMEM; + buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE; + file->private_data = buf; + return 0; } static int debug_registers_open(struct inode *inode, struct file *file) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 8409e0705d63..7378aa137a4a 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From 3c4bb71f96c69ef3c81fda108c96b633a2000de2 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Thu, 18 Sep 2008 23:06:38 +0800 Subject: USB: ehci-dbg: fix reading less content of periodic file This patch fix 2 problems about reading periodic file: 1. The "..." after a interrupt qh is missed because buffer pointer is not moved. 2. After setting p.ptr as NULL, its next qh or itd will be omited and can't be stored in debug buffer. Signed-off-by: Ming Lei Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-dbg.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 9534ff3f5e7b..5d57773e730e 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -569,14 +569,16 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) for (temp = 0; temp < seen_count; temp++) { if (seen [temp].ptr != p.ptr) continue; - if (p.qh->qh_next.ptr) + if (p.qh->qh_next.ptr) { temp = scnprintf (next, size, " ..."); - p.ptr = NULL; + size -= temp; + next += temp; + } break; } /* show more info the first time around */ - if (temp == seen_count && p.ptr) { + if (temp == seen_count) { u32 scratch = hc32_to_cpup(ehci, &p.qh->hw_info1); struct ehci_qtd *qtd; -- cgit v1.2.3 From 8520f38099ccfdac2147a0852f84ee7a8ee5e197 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 22 Sep 2008 14:44:26 -0400 Subject: USB: change hub initialization sleeps to delayed_work This patch (as1137) changes the hub_activate() routine, replacing the power-power-up and debounce delays with delayed_work calls. The idea is that on systems where the USB stack is compiled into the kernel rather than built as modules, these delays will no longer block the boot thread. At least 100 ms is saved for each root hub, which can add up to a significant savings in total boot time. Arjan van de Ven was very pleased to see that this shaved 700 ms off his computer's boot time. Since his total boot time is on the order of two seconds, the improvement is considerable. Signed-off-by: Alan Stern Tested-by: Arjan van de Ven Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 91 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d99963873e37..b97110ca352d 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -77,6 +77,7 @@ struct usb_hub { unsigned has_indicators:1; u8 indicator[USB_MAXCHILDREN]; struct delayed_work leds; + struct delayed_work init_work; }; @@ -515,10 +516,14 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) } EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer); -static void hub_power_on(struct usb_hub *hub) +/* If do_delay is false, return the number of milliseconds the caller + * needs to delay. + */ +static unsigned hub_power_on(struct usb_hub *hub, bool do_delay) { int port1; unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; + unsigned delay; u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); @@ -537,7 +542,10 @@ static void hub_power_on(struct usb_hub *hub) set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER); /* Wait at least 100 msec for power to become stable */ - msleep(max(pgood_delay, (unsigned) 100)); + delay = max(pgood_delay, (unsigned) 100); + if (do_delay) + msleep(delay); + return delay; } static int hub_hub_status(struct usb_hub *hub, @@ -599,21 +607,55 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1) } enum hub_activation_type { - HUB_INIT, HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME + HUB_INIT, HUB_INIT2, HUB_INIT3, + HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME, }; +static void hub_init_func2(struct work_struct *ws); +static void hub_init_func3(struct work_struct *ws); + static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) { struct usb_device *hdev = hub->hdev; int port1; int status; bool need_debounce_delay = false; + unsigned delay; + + /* Continue a partial initialization */ + if (type == HUB_INIT2) + goto init2; + if (type == HUB_INIT3) + goto init3; /* After a resume, port power should still be on. * For any other type of activation, turn it on. */ - if (type != HUB_RESUME) - hub_power_on(hub); + if (type != HUB_RESUME) { + + /* Speed up system boot by using a delayed_work for the + * hub's initial power-up delays. This is pretty awkward + * and the implementation looks like a home-brewed sort of + * setjmp/longjmp, but it saves at least 100 ms for each + * root hub (assuming usbcore is compiled into the kernel + * rather than as a module). It adds up. + * + * This can't be done for HUB_RESUME or HUB_RESET_RESUME + * because for those activation types the ports have to be + * operational when we return. In theory this could be done + * for HUB_POST_RESET, but it's easier not to. + */ + if (type == HUB_INIT) { + delay = hub_power_on(hub, false); + PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func2); + schedule_delayed_work(&hub->init_work, + msecs_to_jiffies(delay)); + return; /* Continues at init2: below */ + } else { + hub_power_on(hub, true); + } + } + init2: /* Check each port and set hub->change_bits to let khubd know * which ports need attention. @@ -692,9 +734,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) * If any port-status changes do occur during this delay, khubd * will see them later and handle them normally. */ - if (need_debounce_delay) - msleep(HUB_DEBOUNCE_STABLE); - + if (need_debounce_delay) { + delay = HUB_DEBOUNCE_STABLE; + + /* Don't do a long sleep inside a workqueue routine */ + if (type == HUB_INIT2) { + PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3); + schedule_delayed_work(&hub->init_work, + msecs_to_jiffies(delay)); + return; /* Continues at init3: below */ + } else { + msleep(delay); + } + } + init3: hub->quiescing = 0; status = usb_submit_urb(hub->urb, GFP_NOIO); @@ -707,6 +760,21 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) kick_khubd(hub); } +/* Implement the continuations for the delays above */ +static void hub_init_func2(struct work_struct *ws) +{ + struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work); + + hub_activate(hub, HUB_INIT2); +} + +static void hub_init_func3(struct work_struct *ws) +{ + struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work); + + hub_activate(hub, HUB_INIT3); +} + enum hub_quiescing_type { HUB_DISCONNECT, HUB_PRE_RESET, HUB_SUSPEND }; @@ -716,6 +784,8 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) struct usb_device *hdev = hub->hdev; int i; + cancel_delayed_work_sync(&hub->init_work); + /* khubd and related activity won't re-trigger */ hub->quiescing = 1; @@ -1099,6 +1169,7 @@ descriptor_error: hub->intfdev = &intf->dev; hub->hdev = hdev; INIT_DELAYED_WORK(&hub->leds, led_work); + INIT_DELAYED_WORK(&hub->init_work, NULL); usb_get_intf(intf); usb_set_intfdata (intf, hub); @@ -3035,7 +3106,7 @@ static void hub_events(void) i); clear_port_feature(hdev, i, USB_PORT_FEAT_C_OVER_CURRENT); - hub_power_on(hub); + hub_power_on(hub, true); } if (portchange & USB_PORT_STAT_C_RESET) { @@ -3070,7 +3141,7 @@ static void hub_events(void) dev_dbg (hub_dev, "overcurrent change\n"); msleep(500); /* Cool down */ clear_hub_feature(hdev, C_HUB_OVER_CURRENT); - hub_power_on(hub); + hub_power_on(hub, true); } } -- cgit v1.2.3 From bb4e3b5ac81a9601775e62649038934acafa78e2 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 22 Sep 2008 15:00:10 -0700 Subject: usbmon: fix tiny race exposed by the fastboot patches usbmon registers the notifier chain, takes the bus lock and then goes to scan the existing devices for hooking up. Unfortunately, if usb_mon gets initialized while USB bus discovery is going on, it's possible that usbmon gets a notifier on one cpu (which runs without USB locks), and the scan is going on and also finds the new bus, resulting in a double sysfs registration, which then produces a WARNING. Pete Zaitcev did the bug diagnostics on this one Signed-off-by: Arjan van de Ven Acked-by: Pete Zaitcev Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mon/mon_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 442d8076b201..5e0ab4201c00 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -361,12 +361,12 @@ static int __init mon_init(void) } // MOD_INC_USE_COUNT(which_module?); - usb_register_notify(&mon_nb); mutex_lock(&usb_bus_list_lock); list_for_each_entry (ubus, &usb_bus_list, bus_list) { mon_bus_init(ubus); } + usb_register_notify(&mon_nb); mutex_unlock(&usb_bus_list_lock); return 0; -- cgit v1.2.3 From cede969fe21adece300300a455580635590deb47 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 22 Sep 2008 15:00:07 -0700 Subject: usb: remove code associated with !CONFIG_PPC_MERGE Now that arch/ppc is gone we don't need CONFIG_PPC_MERGE anymore remove the dead code associated with !CONFIG_PPC_MERGE. Signed-off-by: Kumar Gala Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 5 - drivers/usb/host/ehci-ppc-soc.c | 201 ---------------------------------------- drivers/usb/host/ehci.h | 9 -- drivers/usb/host/ohci.h | 8 -- 4 files changed, 223 deletions(-) delete mode 100644 drivers/usb/host/ehci-ppc-soc.c diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 7378aa137a4a..c6f9961eed3c 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1021,11 +1021,6 @@ MODULE_LICENSE ("GPL"); #define PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver #endif -#if defined(CONFIG_440EPX) && !defined(CONFIG_PPC_MERGE) -#include "ehci-ppc-soc.c" -#define PLATFORM_DRIVER ehci_ppc_soc_driver -#endif - #ifdef CONFIG_USB_EHCI_HCD_PPC_OF #include "ehci-ppc-of.c" #define OF_PLATFORM_DRIVER ehci_hcd_ppc_of_driver diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c deleted file mode 100644 index 529590eb4037..000000000000 --- a/drivers/usb/host/ehci-ppc-soc.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * EHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 2006-2007 Stefan Roese , DENX Software Engineering - * - * Bus Glue for PPC On-Chip EHCI driver - * Tested on AMCC 440EPx - * - * Based on "ehci-au1xxx.c" by K.Boge - * - * This file is licenced under the GPL. - */ - -#include - -extern int usb_disabled(void); - -/* called during probe() after chip reset completes */ -static int ehci_ppc_soc_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; - - retval = ehci_halt(ehci); - if (retval) - return retval; - - retval = ehci_init(hcd); - if (retval) - return retval; - - ehci->sbrn = 0x20; - return ehci_reset(ehci); -} - -/** - * usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs - * Context: !in_interrupt() - * - * Allocates basic resources for this USB host controller, and - * then invokes the start() method for the HCD associated with it - * through the hotplug entry's driver_data. - * - */ -int usb_ehci_ppc_soc_probe(const struct hc_driver *driver, - struct usb_hcd **hcd_out, - struct platform_device *dev) -{ - int retval; - struct usb_hcd *hcd; - struct ehci_hcd *ehci; - - if (dev->resource[1].flags != IORESOURCE_IRQ) { - pr_debug("resource[1] is not IORESOURCE_IRQ"); - retval = -ENOMEM; - } - hcd = usb_create_hcd(driver, &dev->dev, "PPC-SOC EHCI"); - if (!hcd) - return -ENOMEM; - hcd->rsrc_start = dev->resource[0].start; - hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - pr_debug("request_mem_region failed"); - retval = -EBUSY; - goto err1; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - pr_debug("ioremap failed"); - retval = -ENOMEM; - goto err2; - } - - ehci = hcd_to_ehci(hcd); - ehci->big_endian_mmio = 1; - ehci->big_endian_desc = 1; - ehci->caps = hcd->regs; - ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); - - /* cache this readonly data; minimize chip reads */ - ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - -#if defined(CONFIG_440EPX) - /* - * 440EPx Errata USBH_3 - * Fix: Enable Break Memory Transfer (BMT) in INSNREG3 - */ - out_be32((void *)((ulong)(&ehci->regs->command) + 0x8c), (1 << 0)); - ehci_dbg(ehci, "Break Memory Transfer (BMT) has beed enabled!\n"); -#endif - - retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED); - if (retval == 0) - return retval; - - iounmap(hcd->regs); -err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err1: - usb_put_hcd(hcd); - return retval; -} - -/* may be called without controller electrically present */ -/* may be called with controller, bus, and devices active */ - -/** - * usb_ehci_hcd_ppc_soc_remove - shutdown processing for PPC-SoC-based HCDs - * @dev: USB Host Controller being removed - * Context: !in_interrupt() - * - * Reverses the effect of usb_ehci_hcd_ppc_soc_probe(), first invoking - * the HCD's stop() method. It is always called from a thread - * context, normally "rmmod", "apmd", or something similar. - * - */ -void usb_ehci_ppc_soc_remove(struct usb_hcd *hcd, struct platform_device *dev) -{ - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); -} - -static const struct hc_driver ehci_ppc_soc_hc_driver = { - .description = hcd_name, - .product_desc = "PPC-SOC EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - - /* - * basic lifecycle operations - */ - .reset = ehci_ppc_soc_setup, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, -}; - -static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd = NULL; - int ret; - - pr_debug("In ehci_hcd_ppc_soc_drv_probe\n"); - - if (usb_disabled()) - return -ENODEV; - - /* FIXME we only want one one probe() not two */ - ret = usb_ehci_ppc_soc_probe(&ehci_ppc_soc_hc_driver, &hcd, pdev); - return ret; -} - -static int ehci_hcd_ppc_soc_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - /* FIXME we only want one one remove() not two */ - usb_ehci_ppc_soc_remove(hcd, pdev); - return 0; -} - -MODULE_ALIAS("platform:ppc-soc-ehci"); -static struct platform_driver ehci_ppc_soc_driver = { - .probe = ehci_hcd_ppc_soc_drv_probe, - .remove = ehci_hcd_ppc_soc_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = "ppc-soc-ehci", - } -}; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index b697a13364ec..fb1770d6e200 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -604,16 +604,7 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) /* * Big-endian read/write functions are arch-specific. * Other arches can be added if/when they're needed. - * - * REVISIT: arch/powerpc now has readl/writel_be, so the - * definition below can die once the 4xx support is - * finally ported over. */ -#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE) -#define readl_be(addr) in_be32((__force unsigned *)addr) -#define writel_be(val, addr) out_be32((__force unsigned *)addr, val) -#endif - #if defined(CONFIG_ARM) && defined(CONFIG_ARCH_IXP4XX) #define readl_be(addr) __raw_readl((__force unsigned *)addr) #define writel_be(val, addr) __raw_writel(val, (__force unsigned *)addr) diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index faf622eafce7..222011f6172c 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -540,15 +540,7 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci) * Big-endian read/write functions are arch-specific. * Other arches can be added if/when they're needed. * - * REVISIT: arch/powerpc now has readl/writel_be, so the - * definition below can die once the STB04xxx support is - * finally ported over. */ -#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE) -#define readl_be(addr) in_be32((__force unsigned *)addr) -#define writel_be(val, addr) out_be32((__force unsigned *)addr, val) -#endif - static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs) { -- cgit v1.2.3 From 02582b92f60fa33b68b90263013e98550286db0a Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 15 Sep 2008 12:09:31 +0200 Subject: MUSB: Add sanity check for maximum number of endpoints There is no check if platform code passes in more endpoints (num_eps) than the maximum number of enpoints (MUSB_C_NUM_EPS.) The result is that allocate_instance() happily writes past the end of 'struct musb' corrupting memory. This patch adds a BUG() if the platform code requests more than the max. Signed-off-by: Kevin Hilman Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 128e949db47c..bd82253a3329 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1806,6 +1806,7 @@ allocate_instance(struct device *dev, musb->ctrl_base = mbase; musb->nIrq = -ENODEV; musb->config = config; + BUG_ON(musb->config->num_eps > MUSB_C_NUM_EPS); for (epnum = 0, ep = musb->endpoints; epnum < musb->config->num_eps; epnum++, ep++) { -- cgit v1.2.3 From 36e893d25aa2abcae0f11ef263de0e8322641386 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 12 Sep 2008 09:39:06 -0700 Subject: usb gadget: USB_GADGET_VBUS_DRAW Kconfig option Offer a "how much VBUS power to request" configuration option for USB gadgets that aren't using board-specific customization of their gadget or (composite) configuration drivers. Also remove a couple pointless "depends on USB_GADGET" bits from the Kconfig text; booleans inside an "if USB_GADGET" will already have that dependency. Based on a patch from Justin Clacherty. Signed-off-by: David Brownell Cc: Justin Clacherty Tested-by: Robert Jarzmik Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 23 ++++++++++++++++++++--- drivers/usb/gadget/cdc2.c | 1 - drivers/usb/gadget/composite.c | 4 ++-- drivers/usb/gadget/ether.c | 2 -- drivers/usb/gadget/f_loopback.c | 1 - drivers/usb/gadget/f_sourcesink.c | 1 - drivers/usb/gadget/file_storage.c | 2 +- drivers/usb/gadget/gmidi.c | 2 +- drivers/usb/gadget/printer.c | 3 +-- drivers/usb/gadget/serial.c | 1 - 10 files changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index c0dfd9be3115..1a72715bce8a 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -45,7 +45,7 @@ if USB_GADGET config USB_GADGET_DEBUG boolean "Debugging messages (DEVELOPMENT)" - depends on USB_GADGET && DEBUG_KERNEL + depends on DEBUG_KERNEL help Many controller and gadget drivers will print some debugging messages if you use this option to ask for those messages. @@ -59,7 +59,7 @@ config USB_GADGET_DEBUG config USB_GADGET_DEBUG_FILES boolean "Debugging information files (DEVELOPMENT)" - depends on USB_GADGET && PROC_FS + depends on PROC_FS help Some of the drivers in the "gadget" framework can expose debugging information in files such as /proc/driver/udc @@ -70,7 +70,7 @@ config USB_GADGET_DEBUG_FILES config USB_GADGET_DEBUG_FS boolean "Debugging information files in debugfs (DEVELOPMENT)" - depends on USB_GADGET && DEBUG_FS + depends on DEBUG_FS help Some of the drivers in the "gadget" framework can expose debugging information in files under /sys/kernel/debug/. @@ -79,6 +79,23 @@ config USB_GADGET_DEBUG_FS Enable these files by choosing "Y" here. If in doubt, or to conserve kernel memory, say "N". +config USB_GADGET_VBUS_DRAW + int "Maximum VBUS Power usage (2-500 mA)" + range 2 500 + default 2 + help + Some devices need to draw power from USB when they are + configured, perhaps to operate circuitry or to recharge + batteries. This is in addition to any local power supply, + such as an AC adapter or batteries. + + Enter the maximum power your device draws through USB, in + milliAmperes. The permitted range of values is 2 - 500 mA; + 0 mA would be legal, but can make some hosts misbehave. + + This value will be used except for system-specific gadget + drivers that have more specific information. + config USB_GADGET_SELECTED boolean diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index a724fc149850..5495b171cf29 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -155,7 +155,6 @@ static struct usb_configuration cdc_config_driver = { .bConfigurationValue = 1, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 1, /* 2 mA, minimal */ }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f79fdb839cb8..f2da0269e1b1 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -245,7 +245,7 @@ static int config_buf(struct usb_configuration *config, c->bConfigurationValue = config->bConfigurationValue; c->iConfiguration = config->iConfiguration; c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; - c->bMaxPower = config->bMaxPower; + c->bMaxPower = config->bMaxPower ? : (CONFIG_USB_GADGET_VBUS_DRAW / 2); /* There may be e.g. OTG descriptors */ if (config->descriptors) { @@ -432,7 +432,7 @@ static int set_config(struct usb_composite_dev *cdev, } /* when we return, be sure our power usage is valid */ - power = 2 * c->bMaxPower; + power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW; done: usb_gadget_vbus_draw(gadget, power); return result; diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 944c8e889ab4..37252d0012a7 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -242,7 +242,6 @@ static struct usb_configuration rndis_config_driver = { .bConfigurationValue = 2, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 1, /* 2 mA, minimal */ }; /*-------------------------------------------------------------------------*/ @@ -271,7 +270,6 @@ static struct usb_configuration eth_config_driver = { .bConfigurationValue = 1, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 1, /* 2 mA, minimal */ }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 87dde012dacc..8affe1dfc2c1 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c @@ -352,7 +352,6 @@ static struct usb_configuration loopback_driver = { .bind = loopback_bind_config, .bConfigurationValue = 2, .bmAttributes = USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 1, /* 2 mA, minimal */ /* .iConfiguration = DYNAMIC */ }; diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index f18c3a14d72a..dc84d26d2835 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c @@ -552,7 +552,6 @@ static struct usb_configuration sourcesink_driver = { .setup = sourcesink_setup, .bConfigurationValue = 3, .bmAttributes = USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 1, /* 2 mA, minimal */ /* .iConfiguration = DYNAMIC */ }; diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index e0f616f39ba0..c4e62a6297d7 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -851,7 +851,7 @@ config_desc = { .bConfigurationValue = CONFIG_VALUE, .iConfiguration = STRING_CONFIG, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 1, // self-powered + .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, }; static struct usb_otg_descriptor diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 6eee760410d6..60d3f9e9b51f 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -222,7 +222,7 @@ static struct usb_config_descriptor config_desc = { * power properties of the device. Is it selfpowered? */ .bmAttributes = USB_CONFIG_ATT_ONE, - .bMaxPower = 1, + .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, }; /* B.3.1 Standard AC Interface Descriptor */ diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 00b7ed5013a6..5a3034fdfe47 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -252,7 +252,7 @@ static struct usb_config_descriptor config_desc = { .bConfigurationValue = DEV_CONFIG_VALUE, .iConfiguration = 0, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 1 /* Self-Powered */ + .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, }; static struct usb_interface_descriptor intf_desc = { @@ -1476,7 +1476,6 @@ autoconf_fail: if (gadget->is_otg) { otg_desc.bmAttributes |= USB_OTG_HNP, config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; - config_desc.bMaxPower = 4; } spin_lock_init(&dev->lock); diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 2dee848b2f59..37879af1c433 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -159,7 +159,6 @@ static struct usb_configuration serial_config_driver = { /* .bConfigurationValue = f(use_acm) */ /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 1, /* 2 mA, minimal */ }; static int __init gs_bind(struct usb_composite_dev *cdev) -- cgit v1.2.3 From f9e9cff613b8239ce9159735aa662c9c85b478bf Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Fri, 12 Sep 2008 09:02:23 -0700 Subject: USB: Fix s3c2410_udc usb speed handling The new composite framework revealed a weakness in the s3c2410_udc driver gadget register function. Instead of checking if speed asked for was USB_LOW_SPEED upon usb_gadget_register() to deny service, it checked only for USB_FULL_SPEED, thus denying service to usb high speed capable gadgets (like g_ether). Signed-off-by: Yauhen Kharuzhy Cc: stable Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/s3c2410_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 29d13ebe7500..48f51b12d2e2 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1651,7 +1651,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) return -EBUSY; if (!driver->bind || !driver->setup - || driver->speed != USB_SPEED_FULL) { + || driver->speed < USB_SPEED_FULL) { printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n", driver->bind, driver->setup, driver->speed); return -EINVAL; -- cgit v1.2.3 From eaa3246e7dbddd7a029bef22e8b80cbab03466a2 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 11 Sep 2008 11:53:19 +0300 Subject: musb: io: only define read/write stubs if they're not defined yet For those archs which don't provide read/write friends we provide our own implementation so musb driver won't break compilation. This is temporary fix until a better solution comes from upstream. Idealy, would provide those calls if the architecture did not provide them yet. In that case being possible to remove all those stubs from musb_io.h Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_io.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h index 6bbedae83af8..223f0a514094 100644 --- a/drivers/usb/musb/musb_io.h +++ b/drivers/usb/musb/musb_io.h @@ -37,7 +37,9 @@ #include -#ifndef CONFIG_ARM +#if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \ + && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \ + && !defined(CONFIG_PPC64) static inline void readsl(const void __iomem *addr, void *buf, int len) { insl((unsigned long)addr, buf, len); } static inline void readsw(const void __iomem *addr, void *buf, int len) -- cgit v1.2.3 From ae5ad2963939d24eb77b8fa725d0703dc0f97a47 Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Thu, 11 Sep 2008 11:53:20 +0300 Subject: OMAP:MUSB: Fixes the TT programming. Fixes enumeration failures when a USB device attached to a LS hub is connected to OMAP EVM via HS hub. This is fixed by correctly programming hub address register in enqueue path. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_host.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 8b4be012669a..fcd72b54c851 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1873,7 +1873,11 @@ static int musb_urb_enqueue( /* set up tt info if needed */ if (urb->dev->tt) { qh->h_port_reg = (u8) urb->dev->ttport; - qh->h_addr_reg |= 0x80; + if (urb->dev->tt->hub) + qh->h_addr_reg = + (u8) urb->dev->tt->hub->devnum; + if (urb->dev->tt->multi) + qh->h_addr_reg |= 0x80; } } } -- cgit v1.2.3 From 2492e6747f2441562b1341cef1d46e076f346a1f Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Thu, 11 Sep 2008 11:53:21 +0300 Subject: OMAP:MUSB: Corrects urb unlink function path Fixes kernel panic while ISO IN transfer is aborted.Replaced usb_hcd_unlink_urb_from_ep() from musb_giveback() to __musb_giveback() to make sure urb is unlinked before giveback when __musb_giveback() is called from musb_urb_dequeue(). Acquired musb->lock() before usb_hcd_unlink_urb_from_ep() within in enqueue path. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_host.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index fcd72b54c851..17b5c189250e 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -291,6 +291,7 @@ __acquires(musb->lock) urb->actual_length, urb->transfer_buffer_length ); + usb_hcd_unlink_urb_from_ep(musb_to_hcd(musb), urb); spin_unlock(&musb->lock); usb_hcd_giveback_urb(musb_to_hcd(musb), urb, status); spin_lock(&musb->lock); @@ -353,8 +354,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) break; } - usb_hcd_unlink_urb_from_ep(musb_to_hcd(musb), urb); - qh->is_ready = 0; __musb_giveback(musb, urb, status); qh->is_ready = ready; @@ -1791,7 +1790,9 @@ static int musb_urb_enqueue( */ qh = kzalloc(sizeof *qh, mem_flags); if (!qh) { + spin_lock_irqsave(&musb->lock, flags); usb_hcd_unlink_urb_from_ep(hcd, urb); + spin_unlock_irqrestore(&musb->lock, flags); return -ENOMEM; } @@ -1907,7 +1908,9 @@ static int musb_urb_enqueue( done: if (ret != 0) { + spin_lock_irqsave(&musb->lock, flags); usb_hcd_unlink_urb_from_ep(hcd, urb); + spin_unlock_irqrestore(&musb->lock, flags); kfree(qh); } return ret; -- cgit v1.2.3 From 64ca44a65adf131c4df5124fe0fcdc3896f0f0dc Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Thu, 11 Sep 2008 11:53:22 +0300 Subject: usb: musb: do not mess up count number and CSR0 register value Signed-off-by: Bryan Wu Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_gadget_ep0.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index a57652fff39c..3f5e30ddfa27 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -437,7 +437,7 @@ static void ep0_rxstate(struct musb *musb) { void __iomem *regs = musb->control_ep->regs; struct usb_request *req; - u16 tmp; + u16 count, csr; req = next_ep0_request(musb); @@ -449,35 +449,35 @@ static void ep0_rxstate(struct musb *musb) unsigned len = req->length - req->actual; /* read the buffer */ - tmp = musb_readb(regs, MUSB_COUNT0); - if (tmp > len) { + count = musb_readb(regs, MUSB_COUNT0); + if (count > len) { req->status = -EOVERFLOW; - tmp = len; + count = len; } - musb_read_fifo(&musb->endpoints[0], tmp, buf); - req->actual += tmp; - tmp = MUSB_CSR0_P_SVDRXPKTRDY; - if (tmp < 64 || req->actual == req->length) { + musb_read_fifo(&musb->endpoints[0], count, buf); + req->actual += count; + csr = MUSB_CSR0_P_SVDRXPKTRDY; + if (count < 64 || req->actual == req->length) { musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; - tmp |= MUSB_CSR0_P_DATAEND; + csr |= MUSB_CSR0_P_DATAEND; } else req = NULL; } else - tmp = MUSB_CSR0_P_SVDRXPKTRDY | MUSB_CSR0_P_SENDSTALL; + csr = MUSB_CSR0_P_SVDRXPKTRDY | MUSB_CSR0_P_SENDSTALL; /* Completion handler may choose to stall, e.g. because the * message just received holds invalid data. */ if (req) { - musb->ackpend = tmp; + musb->ackpend = csr; musb_g_ep0_giveback(musb, req); if (!musb->ackpend) return; musb->ackpend = 0; } musb_ep_select(musb->mregs, 0); - musb_writew(regs, MUSB_CSR0, tmp); + musb_writew(regs, MUSB_CSR0, csr); } /* -- cgit v1.2.3 From c767c1c6f1febbd1351cc152bba6e37889322d17 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 11 Sep 2008 11:53:23 +0300 Subject: usb: musb_hdrc build fixes Minor musb_hdrc updates: - so it'll build on DaVinci, given relevant platform updates; * remove support for an un-shipped OTG prototype * rely on gpiolib framework conversion for the I2C GPIOs * the mechanism has been removed - catch comments up to the recent removal of the per-SOC header with the silicon configuration data; - and remove two inappropriate "inline" declarations which just bloat host side code. There are still some more ==> changes needed in this driver, catching up to the relocation of most of the include/asm-arm/arch-* contents. Signed-off-by: David Brownell Signed-off-by: Felipe Balbi Cc: stable [2.6.27] Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/Kconfig | 4 ---- drivers/usb/musb/cppi_dma.h | 4 ++-- drivers/usb/musb/davinci.c | 20 ++++---------------- drivers/usb/musb/musb_core.c | 8 ++++---- drivers/usb/musb/musb_host.c | 6 +++--- 5 files changed, 13 insertions(+), 29 deletions(-) diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 58b2b8fc9439..4b9542bbb35c 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -33,10 +33,6 @@ config USB_MUSB_SOC default y if ARCH_DAVINCI default y if ARCH_OMAP2430 default y if ARCH_OMAP34XX - help - Use a static file to describe how the - controller is configured (endpoints, mechanisms, etc) on the - current iteration of a given system-on-chip. comment "DaVinci 644x USB support" depends on USB_MUSB_HDRC && ARCH_DAVINCI diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h index fc5216b5d2c5..729b4071787b 100644 --- a/drivers/usb/musb/cppi_dma.h +++ b/drivers/usb/musb/cppi_dma.h @@ -119,8 +119,8 @@ struct cppi { void __iomem *mregs; /* Mentor regs */ void __iomem *tibase; /* TI/CPPI regs */ - struct cppi_channel tx[MUSB_C_NUM_EPT - 1]; - struct cppi_channel rx[MUSB_C_NUM_EPR - 1]; + struct cppi_channel tx[4]; + struct cppi_channel rx[4]; struct dma_pool *pool; diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 75baf181a8cd..dfb3bcbe00fc 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -39,7 +40,7 @@ #include "musb_core.h" #ifdef CONFIG_MACH_DAVINCI_EVM -#include +#define GPIO_nVBUS_DRV 87 #endif #include "davinci.h" @@ -138,7 +139,6 @@ static int vbus_state = -1; /* VBUS SWITCHING IS BOARD-SPECIFIC */ #ifdef CONFIG_MACH_DAVINCI_EVM -#ifndef CONFIG_MACH_DAVINCI_EVM_OTG /* I2C operations are always synchronous, and require a task context. * With unloaded systems, using the shared workqueue seems to suffice @@ -146,12 +146,11 @@ static int vbus_state = -1; */ static void evm_deferred_drvvbus(struct work_struct *ignored) { - davinci_i2c_expander_op(0x3a, USB_DRVVBUS, vbus_state); + gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); vbus_state = !vbus_state; } static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); -#endif /* modified board */ #endif /* EVM */ static void davinci_source_power(struct musb *musb, int is_on, int immediate) @@ -165,21 +164,10 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate) #ifdef CONFIG_MACH_DAVINCI_EVM if (machine_is_davinci_evm()) { -#ifdef CONFIG_MACH_DAVINCI_EVM_OTG - /* modified EVM board switching VBUS with GPIO(6) not I2C - * NOTE: PINMUX0.RGB888 (bit23) must be clear - */ - if (is_on) - gpio_set(GPIO(6)); - else - gpio_clear(GPIO(6)); - immediate = 1; -#else if (immediate) - davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on); + gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); else schedule_work(&evm_vbus_work); -#endif } #endif if (immediate) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index bd82253a3329..d5af6b0d8af5 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -82,9 +82,9 @@ /* * This gets many kinds of configuration information: * - Kconfig for everything user-configurable - * - for SOC or family details * - platform_device for addressing, irq, and platform_data * - platform_data is mostly for board-specific informarion + * (plus recentrly, SOC or family details) * * Most of the conditional compilation will (someday) vanish. */ @@ -974,9 +974,9 @@ static void musb_shutdown(struct platform_device *pdev) /* * The silicon either has hard-wired endpoint configurations, or else * "dynamic fifo" sizing. The driver has support for both, though at this - * writing only the dynamic sizing is very well tested. We use normal - * idioms to so both modes are compile-tested, but dead code elimination - * leaves only the relevant one in the object file. + * writing only the dynamic sizing is very well tested. Since we switched + * away from compile-time hardware parameters, we can no longer rely on + * dead code elimination to leave only the relevant one in the object file. * * We don't currently use dynamic fifo setup capability to do anything * more than selecting one of a bunch of predefined configurations. diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 17b5c189250e..3133990f04ec 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -108,7 +108,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum, /* * Clear TX fifo. Needed to avoid BABBLE errors. */ -static inline void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) +static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) { void __iomem *epio = ep->regs; u16 csr; @@ -435,7 +435,7 @@ musb_advance_schedule(struct musb *musb, struct urb *urb, } } -static inline u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr) +static u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr) { /* we don't want fifo to fill itself again; * ignore dma (various models), @@ -1004,7 +1004,7 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) /* * Handle default endpoint interrupt as host. Only called in IRQ time - * from the LinuxIsr() interrupt service routine. + * from musb_interrupt(). * * called with controller irqlocked */ -- cgit v1.2.3 From 458e6a511f9dc91e5af5e64740b0a5c9650a25fb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 11 Sep 2008 11:53:24 +0300 Subject: usb: musb: general cleanup to musbhsdma.c Basically getting rid of CaMeLcAsE, but also adding missing lines and spaces. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musbhsdma.c | 306 ++++++++++++++++++++++--------------------- 1 file changed, 155 insertions(+), 151 deletions(-) diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 9ba8fb7fcd24..8c734ef2c1ed 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -45,8 +45,8 @@ #define MUSB_HSDMA_ADDRESS 0x8 #define MUSB_HSDMA_COUNT 0xc -#define MUSB_HSDMA_CHANNEL_OFFSET(_bChannel, _offset) \ - (MUSB_HSDMA_BASE + (_bChannel << 4) + _offset) +#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \ + (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset) /* control register (16-bit): */ #define MUSB_HSDMA_ENABLE_SHIFT 0 @@ -67,23 +67,23 @@ struct musb_dma_controller; struct musb_dma_channel { - struct dma_channel Channel; + struct dma_channel channel; struct musb_dma_controller *controller; - u32 dwStartAddress; + u32 start_addr; u32 len; - u16 wMaxPacketSize; - u8 bIndex; + u16 max_packet_sz; + u8 idx; u8 epnum; u8 transmit; }; struct musb_dma_controller { - struct dma_controller Controller; - struct musb_dma_channel aChannel[MUSB_HSDMA_CHANNELS]; - void *pDmaPrivate; - void __iomem *pCoreBase; - u8 bChannelCount; - u8 bmUsedChannels; + struct dma_controller controller; + struct musb_dma_channel channel[MUSB_HSDMA_CHANNELS]; + void *private_data; + void __iomem *base; + u8 channel_count; + u8 used_channels; u8 irq; }; @@ -93,91 +93,91 @@ static int dma_controller_start(struct dma_controller *c) return 0; } -static void dma_channel_release(struct dma_channel *pChannel); +static void dma_channel_release(struct dma_channel *channel); static int dma_controller_stop(struct dma_controller *c) { - struct musb_dma_controller *controller = - container_of(c, struct musb_dma_controller, Controller); - struct musb *musb = (struct musb *) controller->pDmaPrivate; - struct dma_channel *pChannel; - u8 bBit; + struct musb_dma_controller *controller = container_of(c, + struct musb_dma_controller, controller); + struct musb *musb = controller->private_data; + struct dma_channel *channel; + u8 bit; - if (controller->bmUsedChannels != 0) { + if (controller->used_channels != 0) { dev_err(musb->controller, "Stopping DMA controller while channel active\n"); - for (bBit = 0; bBit < MUSB_HSDMA_CHANNELS; bBit++) { - if (controller->bmUsedChannels & (1 << bBit)) { - pChannel = &controller->aChannel[bBit].Channel; - dma_channel_release(pChannel); + for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) { + if (controller->used_channels & (1 << bit)) { + channel = &controller->channel[bit].channel; + dma_channel_release(channel); - if (!controller->bmUsedChannels) + if (!controller->used_channels) break; } } } + return 0; } static struct dma_channel *dma_channel_allocate(struct dma_controller *c, struct musb_hw_ep *hw_ep, u8 transmit) { - u8 bBit; - struct dma_channel *pChannel = NULL; - struct musb_dma_channel *pImplChannel = NULL; - struct musb_dma_controller *controller = - container_of(c, struct musb_dma_controller, Controller); - - for (bBit = 0; bBit < MUSB_HSDMA_CHANNELS; bBit++) { - if (!(controller->bmUsedChannels & (1 << bBit))) { - controller->bmUsedChannels |= (1 << bBit); - pImplChannel = &(controller->aChannel[bBit]); - pImplChannel->controller = controller; - pImplChannel->bIndex = bBit; - pImplChannel->epnum = hw_ep->epnum; - pImplChannel->transmit = transmit; - pChannel = &(pImplChannel->Channel); - pChannel->private_data = pImplChannel; - pChannel->status = MUSB_DMA_STATUS_FREE; - pChannel->max_len = 0x10000; + struct musb_dma_controller *controller = container_of(c, + struct musb_dma_controller, controller); + struct musb_dma_channel *musb_channel = NULL; + struct dma_channel *channel = NULL; + u8 bit; + + for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) { + if (!(controller->used_channels & (1 << bit))) { + controller->used_channels |= (1 << bit); + musb_channel = &(controller->channel[bit]); + musb_channel->controller = controller; + musb_channel->idx = bit; + musb_channel->epnum = hw_ep->epnum; + musb_channel->transmit = transmit; + channel = &(musb_channel->channel); + channel->private_data = musb_channel; + channel->status = MUSB_DMA_STATUS_FREE; + channel->max_len = 0x10000; /* Tx => mode 1; Rx => mode 0 */ - pChannel->desired_mode = transmit; - pChannel->actual_len = 0; + channel->desired_mode = transmit; + channel->actual_len = 0; break; } } - return pChannel; + + return channel; } -static void dma_channel_release(struct dma_channel *pChannel) +static void dma_channel_release(struct dma_channel *channel) { - struct musb_dma_channel *pImplChannel = - (struct musb_dma_channel *) pChannel->private_data; + struct musb_dma_channel *musb_channel = channel->private_data; - pChannel->actual_len = 0; - pImplChannel->dwStartAddress = 0; - pImplChannel->len = 0; + channel->actual_len = 0; + musb_channel->start_addr = 0; + musb_channel->len = 0; - pImplChannel->controller->bmUsedChannels &= - ~(1 << pImplChannel->bIndex); + musb_channel->controller->used_channels &= + ~(1 << musb_channel->idx); - pChannel->status = MUSB_DMA_STATUS_UNKNOWN; + channel->status = MUSB_DMA_STATUS_UNKNOWN; } -static void configure_channel(struct dma_channel *pChannel, +static void configure_channel(struct dma_channel *channel, u16 packet_sz, u8 mode, dma_addr_t dma_addr, u32 len) { - struct musb_dma_channel *pImplChannel = - (struct musb_dma_channel *) pChannel->private_data; - struct musb_dma_controller *controller = pImplChannel->controller; - void __iomem *mbase = controller->pCoreBase; - u8 bChannel = pImplChannel->bIndex; + struct musb_dma_channel *musb_channel = channel->private_data; + struct musb_dma_controller *controller = musb_channel->controller; + void __iomem *mbase = controller->base; + u8 bchannel = musb_channel->idx; u16 csr = 0; DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n", - pChannel, packet_sz, dma_addr, len, mode); + channel, packet_sz, dma_addr, len, mode); if (mode) { csr |= 1 << MUSB_HSDMA_MODE1_SHIFT; @@ -195,180 +195,183 @@ static void configure_channel(struct dma_channel *pChannel, } } - csr |= (pImplChannel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT) + csr |= (musb_channel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT) | (1 << MUSB_HSDMA_ENABLE_SHIFT) | (1 << MUSB_HSDMA_IRQENABLE_SHIFT) - | (pImplChannel->transmit + | (musb_channel->transmit ? (1 << MUSB_HSDMA_TRANSMIT_SHIFT) : 0); /* address/count */ musb_writel(mbase, - MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_ADDRESS), + MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), dma_addr); musb_writel(mbase, - MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_COUNT), + MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), len); /* control (this should start things) */ musb_writew(mbase, - MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_CONTROL), + MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL), csr); } -static int dma_channel_program(struct dma_channel *pChannel, +static int dma_channel_program(struct dma_channel *channel, u16 packet_sz, u8 mode, dma_addr_t dma_addr, u32 len) { - struct musb_dma_channel *pImplChannel = - (struct musb_dma_channel *) pChannel->private_data; + struct musb_dma_channel *musb_channel = channel->private_data; DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n", - pImplChannel->epnum, - pImplChannel->transmit ? "Tx" : "Rx", + musb_channel->epnum, + musb_channel->transmit ? "Tx" : "Rx", packet_sz, dma_addr, len, mode); - BUG_ON(pChannel->status == MUSB_DMA_STATUS_UNKNOWN || - pChannel->status == MUSB_DMA_STATUS_BUSY); + BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN || + channel->status == MUSB_DMA_STATUS_BUSY); - pChannel->actual_len = 0; - pImplChannel->dwStartAddress = dma_addr; - pImplChannel->len = len; - pImplChannel->wMaxPacketSize = packet_sz; - pChannel->status = MUSB_DMA_STATUS_BUSY; + channel->actual_len = 0; + musb_channel->start_addr = dma_addr; + musb_channel->len = len; + musb_channel->max_packet_sz = packet_sz; + channel->status = MUSB_DMA_STATUS_BUSY; if ((mode == 1) && (len >= packet_sz)) - configure_channel(pChannel, packet_sz, 1, dma_addr, len); + configure_channel(channel, packet_sz, 1, dma_addr, len); else - configure_channel(pChannel, packet_sz, 0, dma_addr, len); + configure_channel(channel, packet_sz, 0, dma_addr, len); return true; } -static int dma_channel_abort(struct dma_channel *pChannel) +static int dma_channel_abort(struct dma_channel *channel) { - struct musb_dma_channel *pImplChannel = - (struct musb_dma_channel *) pChannel->private_data; - u8 bChannel = pImplChannel->bIndex; - void __iomem *mbase = pImplChannel->controller->pCoreBase; + struct musb_dma_channel *musb_channel = channel->private_data; + void __iomem *mbase = musb_channel->controller->base; + + u8 bchannel = musb_channel->idx; u16 csr; - if (pChannel->status == MUSB_DMA_STATUS_BUSY) { - if (pImplChannel->transmit) { + if (channel->status == MUSB_DMA_STATUS_BUSY) { + if (musb_channel->transmit) { csr = musb_readw(mbase, - MUSB_EP_OFFSET(pImplChannel->epnum, + MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR)); csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE); musb_writew(mbase, - MUSB_EP_OFFSET(pImplChannel->epnum, - MUSB_TXCSR), + MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR), csr); } else { csr = musb_readw(mbase, - MUSB_EP_OFFSET(pImplChannel->epnum, + MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR)); csr &= ~(MUSB_RXCSR_AUTOCLEAR | MUSB_RXCSR_DMAENAB | MUSB_RXCSR_DMAMODE); musb_writew(mbase, - MUSB_EP_OFFSET(pImplChannel->epnum, - MUSB_RXCSR), + MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR), csr); } musb_writew(mbase, - MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_CONTROL), + MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL), 0); musb_writel(mbase, - MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_ADDRESS), + MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), 0); musb_writel(mbase, - MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_COUNT), + MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), 0); - pChannel->status = MUSB_DMA_STATUS_FREE; + channel->status = MUSB_DMA_STATUS_FREE; } + return 0; } static irqreturn_t dma_controller_irq(int irq, void *private_data) { - struct musb_dma_controller *controller = - (struct musb_dma_controller *)private_data; - struct musb_dma_channel *pImplChannel; - struct musb *musb = controller->pDmaPrivate; - void __iomem *mbase = controller->pCoreBase; - struct dma_channel *pChannel; - u8 bChannel; - u16 csr; - u32 dwAddress; - u8 int_hsdma; + struct musb_dma_controller *controller = private_data; + struct musb *musb = controller->private_data; + struct musb_dma_channel *musb_channel; + struct dma_channel *channel; + + void __iomem *mbase = controller->base; + irqreturn_t retval = IRQ_NONE; + unsigned long flags; + u8 bchannel; + u8 int_hsdma; + + u32 addr; + u16 csr; + spin_lock_irqsave(&musb->lock, flags); int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR); if (!int_hsdma) goto done; - for (bChannel = 0; bChannel < MUSB_HSDMA_CHANNELS; bChannel++) { - if (int_hsdma & (1 << bChannel)) { - pImplChannel = (struct musb_dma_channel *) - &(controller->aChannel[bChannel]); - pChannel = &pImplChannel->Channel; + for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { + if (int_hsdma & (1 << bchannel)) { + musb_channel = (struct musb_dma_channel *) + &(controller->channel[bchannel]); + channel = &musb_channel->channel; csr = musb_readw(mbase, - MUSB_HSDMA_CHANNEL_OFFSET(bChannel, + MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL)); - if (csr & (1 << MUSB_HSDMA_BUSERROR_SHIFT)) - pImplChannel->Channel.status = + if (csr & (1 << MUSB_HSDMA_BUSERROR_SHIFT)) { + musb_channel->channel.status = MUSB_DMA_STATUS_BUS_ABORT; - else { + } else { u8 devctl; - dwAddress = musb_readl(mbase, + addr = musb_readl(mbase, MUSB_HSDMA_CHANNEL_OFFSET( - bChannel, + bchannel, MUSB_HSDMA_ADDRESS)); - pChannel->actual_len = dwAddress - - pImplChannel->dwStartAddress; + channel->actual_len = addr + - musb_channel->start_addr; DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n", - pChannel, pImplChannel->dwStartAddress, - dwAddress, pChannel->actual_len, - pImplChannel->len, - (pChannel->actual_len - < pImplChannel->len) ? + channel, musb_channel->start_addr, + addr, channel->actual_len, + musb_channel->len, + (channel->actual_len + < musb_channel->len) ? "=> reconfig 0" : "=> complete"); devctl = musb_readb(mbase, MUSB_DEVCTL); - pChannel->status = MUSB_DMA_STATUS_FREE; + channel->status = MUSB_DMA_STATUS_FREE; /* completed */ if ((devctl & MUSB_DEVCTL_HM) - && (pImplChannel->transmit) - && ((pChannel->desired_mode == 0) - || (pChannel->actual_len & - (pImplChannel->wMaxPacketSize - 1))) + && (musb_channel->transmit) + && ((channel->desired_mode == 0) + || (channel->actual_len & + (musb_channel->max_packet_sz - 1))) ) { /* Send out the packet */ musb_ep_select(mbase, - pImplChannel->epnum); + musb_channel->epnum); musb_writew(mbase, MUSB_EP_OFFSET( - pImplChannel->epnum, + musb_channel->epnum, MUSB_TXCSR), MUSB_TXCSR_TXPKTRDY); - } else + } else { musb_dma_completion( musb, - pImplChannel->epnum, - pImplChannel->transmit); + musb_channel->epnum, + musb_channel->transmit); + } } } } @@ -380,9 +383,9 @@ done: void dma_controller_destroy(struct dma_controller *c) { - struct musb_dma_controller *controller; + struct musb_dma_controller *controller = container_of(c, + struct musb_dma_controller, controller); - controller = container_of(c, struct musb_dma_controller, Controller); if (!controller) return; @@ -393,7 +396,7 @@ void dma_controller_destroy(struct dma_controller *c) } struct dma_controller *__init -dma_controller_create(struct musb *musb, void __iomem *pCoreBase) +dma_controller_create(struct musb *musb, void __iomem *base) { struct musb_dma_controller *controller; struct device *dev = musb->controller; @@ -405,29 +408,30 @@ dma_controller_create(struct musb *musb, void __iomem *pCoreBase) return NULL; } - controller = kzalloc(sizeof(struct musb_dma_controller), GFP_KERNEL); + controller = kzalloc(sizeof(*controller), GFP_KERNEL); if (!controller) return NULL; - controller->bChannelCount = MUSB_HSDMA_CHANNELS; - controller->pDmaPrivate = musb; - controller->pCoreBase = pCoreBase; + controller->channel_count = MUSB_HSDMA_CHANNELS; + controller->private_data = musb; + controller->base = base; - controller->Controller.start = dma_controller_start; - controller->Controller.stop = dma_controller_stop; - controller->Controller.channel_alloc = dma_channel_allocate; - controller->Controller.channel_release = dma_channel_release; - controller->Controller.channel_program = dma_channel_program; - controller->Controller.channel_abort = dma_channel_abort; + controller->controller.start = dma_controller_start; + controller->controller.stop = dma_controller_stop; + controller->controller.channel_alloc = dma_channel_allocate; + controller->controller.channel_release = dma_channel_release; + controller->controller.channel_program = dma_channel_program; + controller->controller.channel_abort = dma_channel_abort; if (request_irq(irq, dma_controller_irq, IRQF_DISABLED, - musb->controller->bus_id, &controller->Controller)) { + musb->controller->bus_id, &controller->controller)) { dev_err(dev, "request_irq %d failed!\n", irq); - dma_controller_destroy(&controller->Controller); + dma_controller_destroy(&controller->controller); + return NULL; } controller->irq = irq; - return &controller->Controller; + return &controller->controller; } -- cgit v1.2.3 From 28c2c51c078296151549f4f0e823e804f773861b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 11 Sep 2008 11:53:25 +0300 Subject: usb: musb: remove dead code from procfs When removing the procfs file, I forgot to remove some code that created and removed that file. Here's a patch to fix it. Ideally this patch will be melded into the patch removing the procfs file, don't know if it's possible still. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index d5af6b0d8af5..4a35745b30be 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2055,15 +2055,6 @@ bad_config: } - return 0; - -fail: - if (musb->clock) - clk_put(musb->clock); - device_init_wakeup(dev, 0); - musb_free(musb); - return status; - #ifdef CONFIG_SYSFS status = device_create_file(dev, &dev_attr_mode); status = device_create_file(dev, &dev_attr_vbus); @@ -2072,12 +2063,31 @@ fail: #endif /* CONFIG_USB_GADGET_MUSB_HDRC */ status = 0; #endif + if (status) + goto fail2; - return status; + return 0; fail2: +#ifdef CONFIG_SYSFS + device_remove_file(musb->controller, &dev_attr_mode); + device_remove_file(musb->controller, &dev_attr_vbus); +#ifdef CONFIG_USB_MUSB_OTG + device_remove_file(musb->controller, &dev_attr_srp); +#endif +#endif musb_platform_exit(musb); - goto fail; +fail: + dev_err(musb->controller, + "musb_init_controller failed with status %d\n", status); + + if (musb->clock) + clk_put(musb->clock); + device_init_wakeup(dev, 0); + musb_free(musb); + + return status; + } /*-------------------------------------------------------------------------*/ -- cgit v1.2.3 From 9b466c3b8208f395cb3492e32b254a81c5b31780 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 4 Sep 2008 16:29:55 -0700 Subject: USB: ohci-omap: handle other omap15xx chips Sync up USB parts of the ohci-omap support in mainline with the OMAP tree. This patch supports another first generation OMAP1 part: not just the OMAP 1510 (and its catalog version, the OMAP 5910), but also OMAP 310. From: Tony Lindgren Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-omap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 522185629624..91697bdb399f 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -231,7 +231,7 @@ static int ohci_omap_init(struct usb_hcd *hcd) omap_ohci_clock_power(1); - if (cpu_is_omap1510()) { + if (cpu_is_omap15xx()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } @@ -319,7 +319,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver, if (IS_ERR(usb_host_ck)) return PTR_ERR(usb_host_ck); - if (!cpu_is_omap1510()) + if (!cpu_is_omap15xx()) usb_dc_ck = clk_get(0, "usb_dc_ck"); else usb_dc_ck = clk_get(0, "lb_ck"); -- cgit v1.2.3 From f1c9e151b18ade3be5b1865d288a490bff4339e6 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 4 Sep 2008 16:25:14 -0700 Subject: USB: omap_udc: sync with OMAP tree Sync up USB parts of the omap_udc support in mainline with the OMAP tree. This patch addresses some OMAP2 differences ... there's another, with respect to the double-buffering issue with PIO-IN in omap_ep_setup() (which is now out of sync with the comments), but it's not clear right now how to address that. From: Tony Lindgren Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 2 +- drivers/usb/gadget/omap_udc.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 1a72715bce8a..dd4cd5a51370 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -190,7 +190,7 @@ config USB_LH7A40X config USB_GADGET_OMAP boolean "OMAP USB Device Controller" depends on ARCH_OMAP - select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 + select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG help Many Texas Instruments OMAP processors have flexible full speed USB device controllers, with support for up to 30 diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index bb54cca4c543..34e9e393f929 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2313,6 +2313,13 @@ static int proc_otg_show(struct seq_file *s) tmp = omap_readl(OTG_REV); if (cpu_is_omap24xx()) { + /* + * REVISIT: Not clear how this works on OMAP2. trans + * is ANDed to produce bits 7 and 8, which might make + * sense for USB_TRANSCEIVER_CTRL on OMAP1, + * but with CONTROL_DEVCONF, these bits have something to + * do with the frame adjustment counter and McBSP2. + */ ctrl_name = "control_devconf"; trans = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); } else { -- cgit v1.2.3 From 29bac7b7661bbbdbbd32bc1e6cedca22f260da7f Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 6 Sep 2008 21:33:49 -0700 Subject: usb gadget: cdc ethernet notification bugfix Bugfix for the new CDC Ethernet code: as part of activating the network interface's USB link, make sure its link management code knows whether the interface is open or not. Without this fix, the link won't work right when it's brought up before the link is active ... because the initial notification it sends will have the wrong link state (down, not up). Makes it hard to bridge these links (on the host side), among other things. Signed-off-by: David Brownell Cc: stable [2.6.27] Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/u_ether.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index dbd575a194f3..66948b72bb9b 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -873,6 +873,13 @@ struct net_device *gether_connect(struct gether *link) spin_lock(&dev->lock); dev->port_usb = link; link->ioport = dev; + if (netif_running(dev->net)) { + if (link->open) + link->open(link); + } else { + if (link->close) + link->close(link); + } spin_unlock(&dev->lock); netif_carrier_on(dev->net); -- cgit v1.2.3 From cbc30118d7a376dab4113f299c0c8f035737a5c3 Mon Sep 17 00:00:00 2001 From: Stephen Ware Date: Tue, 30 Sep 2008 11:39:38 -0700 Subject: usb: vstusb.c : new driver for spectrometers used by Vernier Software & Technology, Inc. This patch adds the vstusb driver to the drivers/usb/misc directory. This driver provides support for Vernier Software & Technology spectrometers, all made by Ocean Optics. The driver provides both IOCTL and read()/write() methods for sending raw data to spectrometers across the bulk channel. Each method allows for a configured timeout. From: Stephen Ware Signed-off-by: Dennis O'Brien Signed-off-by: Greg Kroah-Hartman --- Documentation/ioctl-number.txt | 1 + drivers/usb/misc/Kconfig | 15 + drivers/usb/misc/Makefile | 1 + drivers/usb/misc/vstusb.c | 768 +++++++++++++++++++++++++++++++++++++++++ include/linux/usb/Kbuild | 1 + include/linux/usb/vstusb.h | 71 ++++ 6 files changed, 857 insertions(+) create mode 100644 drivers/usb/misc/vstusb.c create mode 100644 include/linux/usb/vstusb.h diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt index f8deb85eef6e..b880ce5dbd33 100644 --- a/Documentation/ioctl-number.txt +++ b/Documentation/ioctl-number.txt @@ -92,6 +92,7 @@ Code Seq# Include File Comments 'J' 00-1F drivers/scsi/gdth_ioctl.h 'K' all linux/kd.h 'L' 00-1F linux/loop.h +'L' 20-2F driver/usb/misc/vstusb.h 'L' E0-FF linux/ppdd.h encrypted disk device driver 'M' all linux/soundcard.h diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 25e1157ab176..e463db5d8188 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -280,3 +280,18 @@ config USB_ISIGHTFW The firmware for this driver must be extracted from the MacOS driver beforehand. Tools for doing so are available at http://bersace03.free.fr + +config USB_VST + tristate "USB VST driver" + depends on USB + help + This driver is intended for Vernier Software Technologies + bulk usb devices such as their Ocean-Optics spectrometers or + Labquest. + It is a bulk channel driver with configurable read and write + timeouts. + + To compile this driver as a module, choose M here: the + module will be called vstusb. + + diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 39ce4a16b3d4..1334f7bdd7be 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_USB_TEST) += usbtest.o obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o obj-$(CONFIG_USB_USS720) += uss720.o obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o +obj-$(CONFIG_USB_VST) += vstusb.o obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ diff --git a/drivers/usb/misc/vstusb.c b/drivers/usb/misc/vstusb.c new file mode 100644 index 000000000000..5ad75e4a0323 --- /dev/null +++ b/drivers/usb/misc/vstusb.c @@ -0,0 +1,768 @@ +/***************************************************************************** + * File: drivers/usb/misc/vstusb.c + * + * Purpose: Support for the bulk USB Vernier Spectrophotometers + * + * Author: Johnnie Peters + * Axian Consulting + * Beaverton, OR, USA 97005 + * + * Modified by: EQware Engineering, Inc. + * Oregon City, OR, USA 97045 + * + * Copyright: 2007, 2008 + * Vernier Software & Technology + * Beaverton, OR, USA 97005 + * + * Web: www.vernier.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + *****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_VERSION "VST USB Driver Version 1.5" +#define DRIVER_DESC "Vernier Software Technology Bulk USB Driver" + +#ifdef CONFIG_USB_DYNAMIC_MINORS + #define VSTUSB_MINOR_BASE 0 +#else + #define VSTUSB_MINOR_BASE 199 +#endif + +#define USB_VENDOR_OCEANOPTICS 0x2457 +#define USB_VENDOR_VERNIER 0x08F7 /* Vernier Software & Technology */ + +#define USB_PRODUCT_USB2000 0x1002 +#define USB_PRODUCT_ADC1000_FW 0x1003 /* firmware download (renumerates) */ +#define USB_PRODUCT_ADC1000 0x1004 +#define USB_PRODUCT_HR2000_FW 0x1009 /* firmware download (renumerates) */ +#define USB_PRODUCT_HR2000 0x100A +#define USB_PRODUCT_HR4000_FW 0x1011 /* firmware download (renumerates) */ +#define USB_PRODUCT_HR4000 0x1012 +#define USB_PRODUCT_USB650 0x1014 /* "Red Tide" */ +#define USB_PRODUCT_QE65000 0x1018 +#define USB_PRODUCT_USB4000 0x1022 +#define USB_PRODUCT_USB325 0x1024 /* "Vernier Spectrometer" */ + +#define USB_PRODUCT_LABPRO 0x0001 +#define USB_PRODUCT_LABQUEST 0x0005 + +static struct usb_device_id id_table[] = { + { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB2000)}, + { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_HR4000)}, + { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB650)}, + { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB4000)}, + { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB325)}, + { USB_DEVICE(USB_VENDOR_VERNIER, USB_PRODUCT_LABQUEST)}, + { USB_DEVICE(USB_VENDOR_VERNIER, USB_PRODUCT_LABPRO)}, + {}, +}; + +MODULE_DEVICE_TABLE(usb, id_table); + +struct vstusb_device { + struct mutex lock; + struct usb_device *usb_dev; + char present; + char isopen; + struct usb_anchor submitted; + int rd_pipe; + int rd_timeout_ms; + int wr_pipe; + int wr_timeout_ms; +}; + +static struct usb_driver vstusb_driver; + +static int vstusb_open(struct inode *inode, struct file *file) +{ + struct vstusb_device *vstdev; + struct usb_interface *interface; + + interface = usb_find_interface(&vstusb_driver, iminor(inode)); + + if (!interface) { + printk(KERN_ERR KBUILD_MODNAME + ": %s - error, can't find device for minor %d\n", + __func__, iminor(inode)); + return -ENODEV; + } + + vstdev = usb_get_intfdata(interface); + + if (!vstdev) + return -ENODEV; + + /* lock this device */ + mutex_lock(&vstdev->lock); + + /* can only open one time */ + if ((!vstdev->present) || (vstdev->isopen)) { + mutex_unlock(&vstdev->lock); + return -EBUSY; + } + + vstdev->isopen = 1; + + /* save device in the file's private structure */ + file->private_data = vstdev; + + dev_dbg(&vstdev->usb_dev->dev, "%s: opened\n", __func__); + + mutex_unlock(&vstdev->lock); + + return 0; +} + +static int vstusb_close(struct inode *inode, struct file *file) +{ + struct vstusb_device *vstdev; + + vstdev = file->private_data; + + if (vstdev == NULL) + return -ENODEV; + + mutex_lock(&vstdev->lock); + + vstdev->isopen = 0; + file->private_data = NULL; + + /* if device is no longer present */ + if (!vstdev->present) { + mutex_unlock(&vstdev->lock); + kfree(vstdev); + } else + mutex_unlock(&vstdev->lock); + + return 0; +} + +static void usb_api_blocking_completion(struct urb *urb) +{ + struct completion *completeit = urb->context; + + complete(completeit); +} + +static int vstusb_fill_and_send_urb(struct urb *urb, + struct usb_device *usb_dev, + unsigned int pipe, void *data, + unsigned int len, struct completion *done) +{ + struct usb_host_endpoint *ep; + struct usb_host_endpoint **hostep; + unsigned int pipend; + + int status; + + hostep = usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out; + pipend = usb_pipeendpoint(pipe); + ep = hostep[pipend]; + + if (!ep || (len == 0)) + return -EINVAL; + + if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT) { + pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); + usb_fill_int_urb(urb, usb_dev, pipe, data, len, + (usb_complete_t)usb_api_blocking_completion, + NULL, ep->desc.bInterval); + } else + usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, + (usb_complete_t)usb_api_blocking_completion, + NULL); + + init_completion(done); + urb->context = done; + urb->actual_length = 0; + status = usb_submit_urb(urb, GFP_KERNEL); + + return status; +} + +static int vstusb_complete_urb(struct urb *urb, struct completion *done, + int timeout, int *actual_length) +{ + unsigned long expire; + int status; + + expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; + if (!wait_for_completion_interruptible_timeout(done, expire)) { + usb_kill_urb(urb); + status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status; + + dev_dbg(&urb->dev->dev, + "%s timed out on ep%d%s len=%d/%d, urb status = %d\n", + current->comm, + usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe) ? "in" : "out", + urb->actual_length, + urb->transfer_buffer_length, + urb->status); + + } else { + if (signal_pending(current)) { + /* if really an error */ + if (urb->status && !((urb->status == -ENOENT) || + (urb->status == -ECONNRESET) || + (urb->status == -ESHUTDOWN))) { + status = -EINTR; + usb_kill_urb(urb); + } else { + status = 0; + } + + dev_dbg(&urb->dev->dev, + "%s: signal pending on ep%d%s len=%d/%d," + "urb status = %d\n", + current->comm, + usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe) ? "in" : "out", + urb->actual_length, + urb->transfer_buffer_length, + urb->status); + + } else { + status = urb->status; + } + } + + if (actual_length) + *actual_length = urb->actual_length; + + return status; +} + +static ssize_t vstusb_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct vstusb_device *vstdev; + int cnt = -1; + void *buf; + int retval = 0; + + struct urb *urb; + struct usb_device *dev; + unsigned int pipe; + int timeout; + + DECLARE_COMPLETION_ONSTACK(done); + + vstdev = file->private_data; + + if (vstdev == NULL) + return -ENODEV; + + /* verify that we actually want to read some data */ + if (count == 0) + return -EINVAL; + + /* lock this object */ + if (mutex_lock_interruptible(&vstdev->lock)) + return -ERESTARTSYS; + + /* anyone home */ + if (!vstdev->present) { + mutex_unlock(&vstdev->lock); + printk(KERN_ERR KBUILD_MODNAME + ": %s: device not present\n", __func__); + return -ENODEV; + } + + /* pull out the necessary data */ + dev = vstdev->usb_dev; + pipe = usb_rcvbulkpipe(dev, vstdev->rd_pipe); + timeout = vstdev->rd_timeout_ms; + + buf = kmalloc(count, GFP_KERNEL); + if (buf == NULL) { + mutex_unlock(&vstdev->lock); + return -ENOMEM; + } + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + kfree(buf); + mutex_unlock(&vstdev->lock); + return -ENOMEM; + } + + usb_anchor_urb(urb, &vstdev->submitted); + retval = vstusb_fill_and_send_urb(urb, dev, pipe, buf, count, &done); + mutex_unlock(&vstdev->lock); + if (retval) { + usb_unanchor_urb(urb); + dev_err(&dev->dev, "%s: error %d filling and sending urb %d\n", + __func__, retval, pipe); + goto exit; + } + + retval = vstusb_complete_urb(urb, &done, timeout, &cnt); + if (retval) { + dev_err(&dev->dev, "%s: error %d completing urb %d\n", + __func__, retval, pipe); + goto exit; + } + + if (copy_to_user(buffer, buf, cnt)) { + dev_err(&dev->dev, "%s: can't copy_to_user\n", __func__); + retval = -EFAULT; + } else { + retval = cnt; + dev_dbg(&dev->dev, "%s: read %d bytes from pipe %d\n", + __func__, cnt, pipe); + } + +exit: + usb_free_urb(urb); + kfree(buf); + return retval; +} + +static ssize_t vstusb_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct vstusb_device *vstdev; + int cnt = -1; + void *buf; + int retval = 0; + + struct urb *urb; + struct usb_device *dev; + unsigned int pipe; + int timeout; + + DECLARE_COMPLETION_ONSTACK(done); + + vstdev = file->private_data; + + if (vstdev == NULL) + return -ENODEV; + + /* verify that we actually have some data to write */ + if (count == 0) + return retval; + + /* lock this object */ + if (mutex_lock_interruptible(&vstdev->lock)) + return -ERESTARTSYS; + + /* anyone home */ + if (!vstdev->present) { + mutex_unlock(&vstdev->lock); + printk(KERN_ERR KBUILD_MODNAME + ": %s: device not present\n", __func__); + return -ENODEV; + } + + /* pull out the necessary data */ + dev = vstdev->usb_dev; + pipe = usb_sndbulkpipe(dev, vstdev->wr_pipe); + timeout = vstdev->wr_timeout_ms; + + buf = kmalloc(count, GFP_KERNEL); + if (buf == NULL) { + mutex_unlock(&vstdev->lock); + return -ENOMEM; + } + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + kfree(buf); + mutex_unlock(&vstdev->lock); + return -ENOMEM; + } + + if (copy_from_user(buf, buffer, count)) { + dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__); + retval = -EFAULT; + goto exit; + } + + usb_anchor_urb(urb, &vstdev->submitted); + retval = vstusb_fill_and_send_urb(urb, dev, pipe, buf, count, &done); + mutex_unlock(&vstdev->lock); + if (retval) { + usb_unanchor_urb(urb); + dev_err(&dev->dev, "%s: error %d filling and sending urb %d\n", + __func__, retval, pipe); + goto exit; + } + + retval = vstusb_complete_urb(urb, &done, timeout, &cnt); + if (retval) { + dev_err(&dev->dev, "%s: error %d completing urb %d\n", + __func__, retval, pipe); + goto exit; + } else { + retval = cnt; + dev_dbg(&dev->dev, "%s: sent %d bytes to pipe %d\n", + __func__, cnt, pipe); + } + +exit: + usb_free_urb(urb); + kfree(buf); + return retval; +} + +static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int retval = 0; + int cnt = -1; + void __user *data = (void __user *)arg; + struct vstusb_args usb_data; + + struct vstusb_device *vstdev; + void *buffer = NULL; /* must be initialized. buffer is + * referenced on exit but not all + * ioctls allocate it */ + + struct urb *urb = NULL; /* must be initialized. urb is + * referenced on exit but not all + * ioctls allocate it */ + struct usb_device *dev; + unsigned int pipe; + int timeout; + + DECLARE_COMPLETION_ONSTACK(done); + + vstdev = file->private_data; + + if (_IOC_TYPE(cmd) != VST_IOC_MAGIC) { + dev_warn(&vstdev->usb_dev->dev, + "%s: ioctl command %x, bad ioctl magic %x, " + "expected %x\n", __func__, cmd, + _IOC_TYPE(cmd), VST_IOC_MAGIC); + return -EINVAL; + } + + if (vstdev == NULL) + return -ENODEV; + + if (copy_from_user(&usb_data, data, sizeof(struct vstusb_args))) { + dev_err(&vstdev->usb_dev->dev, "%s: can't copy_from_user\n", + __func__); + return -EFAULT; + } + + /* lock this object */ + if (mutex_lock_interruptible(&vstdev->lock)) { + retval = -ERESTARTSYS; + goto exit; + } + + /* anyone home */ + if (!vstdev->present) { + mutex_unlock(&vstdev->lock); + dev_err(&vstdev->usb_dev->dev, "%s: device not present\n", + __func__); + retval = -ENODEV; + goto exit; + } + + /* pull out the necessary data */ + dev = vstdev->usb_dev; + + switch (cmd) { + + case IOCTL_VSTUSB_CONFIG_RW: + + vstdev->rd_pipe = usb_data.rd_pipe; + vstdev->rd_timeout_ms = usb_data.rd_timeout_ms; + vstdev->wr_pipe = usb_data.wr_pipe; + vstdev->wr_timeout_ms = usb_data.wr_timeout_ms; + + mutex_unlock(&vstdev->lock); + + dev_dbg(&dev->dev, "%s: setting pipes/timeouts, " + "rdpipe = %d, rdtimeout = %d, " + "wrpipe = %d, wrtimeout = %d\n", __func__, + vstdev->rd_pipe, vstdev->rd_timeout_ms, + vstdev->wr_pipe, vstdev->wr_timeout_ms); + break; + + case IOCTL_VSTUSB_SEND_PIPE: + + if (usb_data.count == 0) { + mutex_unlock(&vstdev->lock); + retval = -EINVAL; + goto exit; + } + + buffer = kmalloc(usb_data.count, GFP_KERNEL); + if (buffer == NULL) { + mutex_unlock(&vstdev->lock); + retval = -ENOMEM; + goto exit; + } + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + mutex_unlock(&vstdev->lock); + retval = -ENOMEM; + goto exit; + } + + timeout = usb_data.timeout_ms; + + pipe = usb_sndbulkpipe(dev, usb_data.pipe); + + if (copy_from_user(buffer, usb_data.buffer, usb_data.count)) { + dev_err(&dev->dev, "%s: can't copy_from_user\n", + __func__); + mutex_unlock(&vstdev->lock); + retval = -EFAULT; + goto exit; + } + + usb_anchor_urb(urb, &vstdev->submitted); + retval = vstusb_fill_and_send_urb(urb, dev, pipe, buffer, + usb_data.count, &done); + mutex_unlock(&vstdev->lock); + if (retval) { + usb_unanchor_urb(urb); + dev_err(&dev->dev, + "%s: error %d filling and sending urb %d\n", + __func__, retval, pipe); + goto exit; + } + + retval = vstusb_complete_urb(urb, &done, timeout, &cnt); + if (retval) { + dev_err(&dev->dev, "%s: error %d completing urb %d\n", + __func__, retval, pipe); + } + + break; + case IOCTL_VSTUSB_RECV_PIPE: + + if (usb_data.count == 0) { + mutex_unlock(&vstdev->lock); + retval = -EINVAL; + goto exit; + } + + buffer = kmalloc(usb_data.count, GFP_KERNEL); + if (buffer == NULL) { + mutex_unlock(&vstdev->lock); + retval = -ENOMEM; + goto exit; + } + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + mutex_unlock(&vstdev->lock); + retval = -ENOMEM; + goto exit; + } + + timeout = usb_data.timeout_ms; + + pipe = usb_rcvbulkpipe(dev, usb_data.pipe); + + usb_anchor_urb(urb, &vstdev->submitted); + retval = vstusb_fill_and_send_urb(urb, dev, pipe, buffer, + usb_data.count, &done); + mutex_unlock(&vstdev->lock); + if (retval) { + usb_unanchor_urb(urb); + dev_err(&dev->dev, + "%s: error %d filling and sending urb %d\n", + __func__, retval, pipe); + goto exit; + } + + retval = vstusb_complete_urb(urb, &done, timeout, &cnt); + if (retval) { + dev_err(&dev->dev, "%s: error %d completing urb %d\n", + __func__, retval, pipe); + goto exit; + } + + if (copy_to_user(usb_data.buffer, buffer, cnt)) { + dev_err(&dev->dev, "%s: can't copy_to_user\n", + __func__); + retval = -EFAULT; + goto exit; + } + + usb_data.count = cnt; + if (copy_to_user(data, &usb_data, sizeof(struct vstusb_args))) { + dev_err(&dev->dev, "%s: can't copy_to_user\n", + __func__); + retval = -EFAULT; + } else { + dev_dbg(&dev->dev, "%s: recv %d bytes from pipe %d\n", + __func__, usb_data.count, usb_data.pipe); + } + + break; + + default: + mutex_unlock(&vstdev->lock); + dev_warn(&dev->dev, "ioctl_vstusb: invalid ioctl cmd %x\n", + cmd); + return -EINVAL; + break; + } +exit: + usb_free_urb(urb); + kfree(buffer); + return retval; +} + +static const struct file_operations vstusb_fops = { + .owner = THIS_MODULE, + .read = vstusb_read, + .write = vstusb_write, + .unlocked_ioctl = vstusb_ioctl, + .compat_ioctl = vstusb_ioctl, + .open = vstusb_open, + .release = vstusb_close, +}; + +static struct usb_class_driver usb_vstusb_class = { + .name = "usb/vstusb%d", + .fops = &vstusb_fops, + .minor_base = VSTUSB_MINOR_BASE, +}; + +static int vstusb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct vstusb_device *vstdev; + int i; + int retval = 0; + + /* allocate memory for our device state and intialize it */ + + vstdev = kzalloc(sizeof(*vstdev), GFP_KERNEL); + if (vstdev == NULL) + return -ENOMEM; + + mutex_init(&vstdev->lock); + + i = dev->descriptor.bcdDevice; + + dev_dbg(&intf->dev, "Version %1d%1d.%1d%1d found at address %d\n", + (i & 0xF000) >> 12, (i & 0xF00) >> 8, + (i & 0xF0) >> 4, (i & 0xF), dev->devnum); + + vstdev->present = 1; + vstdev->isopen = 0; + vstdev->usb_dev = dev; + init_usb_anchor(&vstdev->submitted); + + usb_set_intfdata(intf, vstdev); + retval = usb_register_dev(intf, &usb_vstusb_class); + if (retval) { + dev_err(&intf->dev, + "%s: Not able to get a minor for this device.\n", + __func__); + usb_set_intfdata(intf, NULL); + kfree(vstdev); + return retval; + } + + /* let the user know what node this device is now attached to */ + dev_info(&intf->dev, + "VST USB Device #%d now attached to major %d minor %d\n", + (intf->minor - VSTUSB_MINOR_BASE), USB_MAJOR, intf->minor); + + dev_info(&intf->dev, "%s, %s\n", DRIVER_DESC, DRIVER_VERSION); + + return retval; +} + +static void vstusb_disconnect(struct usb_interface *intf) +{ + struct vstusb_device *vstdev = usb_get_intfdata(intf); + + usb_deregister_dev(intf, &usb_vstusb_class); + usb_set_intfdata(intf, NULL); + + if (vstdev) { + + mutex_lock(&vstdev->lock); + vstdev->present = 0; + + usb_kill_anchored_urbs(&vstdev->submitted); + + /* if the device is not opened, then we clean up right now */ + if (!vstdev->isopen) { + mutex_unlock(&vstdev->lock); + kfree(vstdev); + } else + mutex_unlock(&vstdev->lock); + + } +} + +static int vstusb_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct vstusb_device *vstdev = usb_get_intfdata(intf); + int time; + if (!vstdev) + return 0; + + mutex_lock(&vstdev->lock); + time = usb_wait_anchor_empty_timeout(&vstdev->submitted, 1000); + if (!time) + usb_kill_anchored_urbs(&vstdev->submitted); + mutex_unlock(&vstdev->lock); + + return 0; +} + +static int vstusb_resume(struct usb_interface *intf) +{ + return 0; +} + +static struct usb_driver vstusb_driver = { + .name = "vstusb", + .probe = vstusb_probe, + .disconnect = vstusb_disconnect, + .suspend = vstusb_suspend, + .resume = vstusb_resume, + .id_table = id_table, +}; + +static int __init vstusb_init(void) +{ + int rc; + + rc = usb_register(&vstusb_driver); + if (rc) + printk(KERN_ERR "%s: failed to register (%d)", __func__, rc); + + return rc; +} + +static void __exit vstusb_exit(void) +{ + usb_deregister(&vstusb_driver); +} + +module_init(vstusb_init); +module_exit(vstusb_exit); + +MODULE_AUTHOR("Dennis O'Brien/Stephen Ware"); +MODULE_DESCRIPTION(DRIVER_VERSION); +MODULE_LICENSE("GPL"); diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild index 29fd73b0bffc..54c446309a2a 100644 --- a/include/linux/usb/Kbuild +++ b/include/linux/usb/Kbuild @@ -5,3 +5,4 @@ header-y += gadgetfs.h header-y += midi.h header-y += g_printer.h header-y += tmc.h +header-y += vstusb.h diff --git a/include/linux/usb/vstusb.h b/include/linux/usb/vstusb.h new file mode 100644 index 000000000000..1cfac67191ff --- /dev/null +++ b/include/linux/usb/vstusb.h @@ -0,0 +1,71 @@ +/***************************************************************************** + * File: drivers/usb/misc/vstusb.h + * + * Purpose: Support for the bulk USB Vernier Spectrophotometers + * + * Author: EQware Engineering, Inc. + * Oregon City, OR, USA 97045 + * + * Copyright: 2007, 2008 + * Vernier Software & Technology + * Beaverton, OR, USA 97005 + * + * Web: www.vernier.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + *****************************************************************************/ +/***************************************************************************** + * + * The vstusb module is a standard usb 'client' driver running on top of the + * standard usb host controller stack. + * + * In general, vstusb supports standard bulk usb pipes. It supports multiple + * devices and multiple pipes per device. + * + * The vstusb driver supports two interfaces: + * 1 - ioctl SEND_PIPE/RECV_PIPE - a general bulk write/read msg + * interface to any pipe with timeout support; + * 2 - standard read/write with ioctl config - offers standard read/write + * interface with ioctl configured pipes and timeouts. + * + * Both interfaces can be signal from other process and will abort its i/o + * operation. + * + * A timeout of 0 means NO timeout. The user can still terminate the read via + * signal. + * + * If using multiple threads with this driver, the user should ensure that + * any reads, writes, or ioctls are complete before closing the device. + * Changing read/write timeouts or pipes takes effect on next read/write. + * + *****************************************************************************/ + +struct vstusb_args { + union { + /* this struct is used for IOCTL_VSTUSB_SEND_PIPE, * + * IOCTL_VSTUSB_RECV_PIPE, and read()/write() fops */ + struct { + void __user *buffer; + size_t count; + unsigned int timeout_ms; + int pipe; + }; + + /* this one is used for IOCTL_VSTUSB_CONFIG_RW */ + struct { + int rd_pipe; + int rd_timeout_ms; + int wr_pipe; + int wr_timeout_ms; + }; + }; +}; + +#define VST_IOC_MAGIC 'L' +#define VST_IOC_FIRST 0x20 +#define IOCTL_VSTUSB_SEND_PIPE _IO(VST_IOC_MAGIC, VST_IOC_FIRST) +#define IOCTL_VSTUSB_RECV_PIPE _IO(VST_IOC_MAGIC, VST_IOC_FIRST + 1) +#define IOCTL_VSTUSB_CONFIG_RW _IO(VST_IOC_MAGIC, VST_IOC_FIRST + 2) -- cgit v1.2.3 From 925dff5dee04fb46d2e67c088c54b331f97672ee Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Thu, 25 Sep 2008 13:11:28 +0800 Subject: USB: ti_usb_3410_5052: removed duplicated include Removed duplicated #include in drivers/usb/serial/ti_usb_3410_5052.c. Signed-off-by: Huang Weiyi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ti_usb_3410_5052.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index c90237d48b0e..a9523b8348da 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -85,7 +85,6 @@ #include #include #include -#include #include "ti_usb_3410_5052.h" -- cgit v1.2.3 From e58dcebcd83b5902411e747ee7807219dee6bcf2 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 25 Sep 2008 16:59:57 -0400 Subject: USB: UHCI: improve scheduling of interrupt URBs This patch (as1140) adds a little intelligence to the interrupt-URB scheduler in uhci-hcd. Right now the scheduler is stupid; every URB having the same period is assigned to the same slot. Thus a large group of period-N URBs can fill their slot and cause -ENOSPC errors even when all the lower-period slots are empty. With the patch, if an URB doesn't fit in its assigned slot then the scheduler will try using lower-period slots. This will provide greater flexibility. As an example, the driver will be able to handle more than just three or four mice, which the current driver cannot. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-q.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 1f0c2cf26e5d..5631d89c8730 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -1065,13 +1065,18 @@ static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, } if (exponent < 0) return -EINVAL; - qh->period = 1 << exponent; - qh->skel = SKEL_INDEX(exponent); - /* For now, interrupt phase is fixed by the layout - * of the QH lists. */ - qh->phase = (qh->period / 2) & (MAX_PHASE - 1); - ret = uhci_check_bandwidth(uhci, qh); + /* If the slot is full, try a lower period */ + do { + qh->period = 1 << exponent; + qh->skel = SKEL_INDEX(exponent); + + /* For now, interrupt phase is fixed by the layout + * of the QH lists. + */ + qh->phase = (qh->period / 2) & (MAX_PHASE - 1); + ret = uhci_check_bandwidth(uhci, qh); + } while (ret != 0 && --exponent >= 0); if (ret) return ret; } else if (qh->period > urb->interval) -- cgit v1.2.3 From f0d781d59cb621e1795d510039df973d0f8b23fc Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Thu, 25 Sep 2008 17:25:44 +0800 Subject: USB: improve ehci_watchdog's side effect in CPU power management ehci_watchdog will wake up CPU very frequently so that CPU stays at C3 very short, average residence time is about 50 ms on Aspire One, but we expect it should be about 1 second or more, so this kind of periodic timer is very bad for power saving. We can't remove this timer because of some bad USB controller chipset, but at least we should reduce its side effect to as possible as low. This patch can make CPU stay at C3 longer, average residence time is about twice as long as original. Please consider to apply it, thanks Signed-off-by: Yi Yang Cc: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index fb1770d6e200..a6fd550b6903 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -181,14 +181,16 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) * the async ring; just the I/O watchdog. Note that if a * SHRINK were pending, OFF would never be requested. */ - if (timer_pending(&ehci->watchdog) - && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) - & ehci->actions)) - return; + enum ehci_timer_action oldactions = ehci->actions; if (!test_and_set_bit (action, &ehci->actions)) { unsigned long t; + if (timer_pending(&ehci->watchdog) + && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) + & oldactions)) + return; + switch (action) { case TIMER_IO_WATCHDOG: t = EHCI_IO_JIFFIES; @@ -204,7 +206,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; break; } - mod_timer(&ehci->watchdog, t + jiffies); + mod_timer(&ehci->watchdog, round_jiffies(t + jiffies)); } } -- cgit v1.2.3 From ce5dee50edc8b1ac8028c17040d40a78c4b33232 Mon Sep 17 00:00:00 2001 From: Julien Brunel Date: Wed, 24 Sep 2008 18:00:36 +0200 Subject: USB: isp1760: Use an IS_ERR test rather than a NULL test In case of error, the function isp1760_register returns an ERR pointer, but never returns a NULL pointer. So after a call to this function, a NULL test should be replaced by an IS_ERR test. Moreover, we have noticed that: (1) the result of isp1760_register is assigned through the function pci_set_drvdata without an error test, (2) if the call to isp1760_register fails, the current function (isp1761_pci_probe) returns 0, and if it succeeds, it returns -ENOMEM, which seems odd. Thus, we suggest to move the test before the call to pci_set_drvdata to correct (1), and to turn it into a non IS_ERR test to correct (2). The semantic match that finds this problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @bad_null_test@ expression x,E; statement S1, S2; @@ x = isp1760_register(...) ... when != x = E * if (x == NULL) S1 else S2 // Signed-off-by: Julien Brunel Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-if.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 051ef7b6bdc6..ad44bd60df98 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -232,9 +232,10 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev, hcd = isp1760_register(pci_mem_phy0, length, dev->irq, IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev), devflags); - pci_set_drvdata(dev, hcd); - if (!hcd) + if (!IS_ERR(hcd)) { + pci_set_drvdata(dev, hcd); return 0; + } clean: status = -ENODEV; iounmap(iobase); -- cgit v1.2.3 From c0f082c5367a02e8493d779e16ad336167e14718 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 29 Sep 2008 10:58:35 -0700 Subject: USB: ftdi-elan: Always pass usb_bulk_msg() a timeout in milliseconds. The kernel doc for usb_bulk_msg() says the timeout for a bulk message should be specified in milliseconds. The ftdi-elan driver converts milliseconds to jiffies before passing the timeout to usb_bulk_msg(). This is mostly harmless, since it will just lead to very long timeouts, but was obviously not the intent of the original author. Signed-off-by: Sarah Sharp Acked-by: Tony Olech Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ftdi-elan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 97c280971532..79a7668ef264 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -698,7 +698,7 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer, int retval = usb_bulk_msg(ftdi->udev, usb_rcvbulkpipe(ftdi->udev, ftdi->bulk_in_endpointAddr), ftdi->bulk_in_buffer, ftdi->bulk_in_size, - &packet_bytes, msecs_to_jiffies(50)); + &packet_bytes, 50); if (packet_bytes > 2) { ftdi->bulk_in_left = packet_bytes - 2; ftdi->bulk_in_last = 1; @@ -960,7 +960,7 @@ static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi) int retval = usb_bulk_msg(ftdi->udev, usb_rcvbulkpipe(ftdi->udev, ftdi->bulk_in_endpointAddr), ftdi->bulk_in_buffer, ftdi->bulk_in_size, - &packet_bytes, msecs_to_jiffies(500)); + &packet_bytes, 500); char diag[30 *3 + 4]; char *d = diag; int m = packet_bytes; @@ -1880,7 +1880,7 @@ static int ftdi_elan_flush_input_fifo(struct usb_ftdi *ftdi) int retval = usb_bulk_msg(ftdi->udev, usb_rcvbulkpipe(ftdi->udev, ftdi->bulk_in_endpointAddr), ftdi->bulk_in_buffer, ftdi->bulk_in_size, - &packet_bytes, msecs_to_jiffies(100)); + &packet_bytes, 100); if (packet_bytes > 2) { char diag[30 *3 + 4]; char *d = diag; @@ -2067,7 +2067,7 @@ static int ftdi_elan_synchronize(struct usb_ftdi *ftdi) usb_rcvbulkpipe(ftdi->udev, ftdi->bulk_in_endpointAddr), ftdi->bulk_in_buffer, ftdi->bulk_in_size, - &packet_bytes, msecs_to_jiffies(500)); + &packet_bytes, 500); if (packet_bytes > 2) { char diag[30 *3 + 4]; char *d = diag; @@ -2176,7 +2176,7 @@ static int ftdi_elan_stuck_waiting(struct usb_ftdi *ftdi) int retval = usb_bulk_msg(ftdi->udev, usb_rcvbulkpipe(ftdi->udev, ftdi->bulk_in_endpointAddr), ftdi->bulk_in_buffer, ftdi->bulk_in_size, - &packet_bytes, msecs_to_jiffies(1000)); + &packet_bytes, 1000); if (packet_bytes > 2) { char diag[30 *3 + 4]; char *d = diag; -- cgit v1.2.3 From 1987625226a918cd20c334ffce5e2a224cba0718 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 25 Aug 2008 22:40:25 +0200 Subject: USB: anchor API changes needed for btusb This extends the anchor API as btusb needs for autosuspend. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/urb.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/usb.h | 3 +++ 2 files changed, 73 insertions(+) diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index eebc070c3cc7..175d528f4029 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -716,3 +716,73 @@ int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor, msecs_to_jiffies(timeout)); } EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout); + +/** + * usb_get_from_anchor - get an anchor's oldest urb + * @anchor: the anchor whose urb you want + * + * this will take the oldest urb from an anchor, + * unanchor and return it + */ +struct urb *usb_get_from_anchor(struct usb_anchor *anchor) +{ + struct urb *victim; + unsigned long flags; + + spin_lock_irqsave(&anchor->lock, flags); + if (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.next, struct urb, + anchor_list); + usb_get_urb(victim); + spin_unlock_irqrestore(&anchor->lock, flags); + usb_unanchor_urb(victim); + } else { + spin_unlock_irqrestore(&anchor->lock, flags); + victim = NULL; + } + + return victim; +} + +EXPORT_SYMBOL_GPL(usb_get_from_anchor); + +/** + * usb_scuttle_anchored_urbs - unanchor all an anchor's urbs + * @anchor: the anchor whose urbs you want to unanchor + * + * use this to get rid of all an anchor's urbs + */ +void usb_scuttle_anchored_urbs(struct usb_anchor *anchor) +{ + struct urb *victim; + unsigned long flags; + + spin_lock_irqsave(&anchor->lock, flags); + while (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.prev, struct urb, + anchor_list); + usb_get_urb(victim); + spin_unlock_irqrestore(&anchor->lock, flags); + /* this may free the URB */ + usb_unanchor_urb(victim); + usb_put_urb(victim); + spin_lock_irqsave(&anchor->lock, flags); + } + spin_unlock_irqrestore(&anchor->lock, flags); +} + +EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs); + +/** + * usb_anchor_empty - is an anchor empty + * @anchor: the anchor you want to query + * + * returns 1 if the anchor has no urbs associated with it + */ +int usb_anchor_empty(struct usb_anchor *anchor) +{ + return list_empty(&anchor->urb_list); +} + +EXPORT_SYMBOL_GPL(usb_anchor_empty); + diff --git a/include/linux/usb.h b/include/linux/usb.h index d97927970f54..8fa973bede5e 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1469,6 +1469,9 @@ extern void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor); extern void usb_unanchor_urb(struct urb *urb); extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor, unsigned int timeout); +extern struct urb *usb_get_from_anchor(struct usb_anchor *anchor); +extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor); +extern int usb_anchor_empty(struct usb_anchor *anchor); /** * usb_urb_dir_in - check if an URB describes an IN transfer -- cgit v1.2.3 From 2b70f07343389cb474235def00b021a645ede916 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 2 Oct 2008 11:47:15 -0400 Subject: USB: EHCI, OHCI, UHCI: remove version numbers This patch (as1145) removes the essentially useless driver-version strings from ehci-hcd, ohci-hcd, and uhci-hcd. It also unifies the form of the banner lines they display upon loading and adds a missing test for usb_disabled() to ehci-hcd. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-dbg.c | 4 ++-- drivers/usb/host/ehci-hcd.c | 13 +++++++------ drivers/usb/host/ohci-dbg.c | 2 +- drivers/usb/host/ohci-hcd.c | 7 ++----- drivers/usb/host/ohci-pnx4008.c | 2 +- drivers/usb/host/uhci-hcd.c | 7 +++---- 6 files changed, 16 insertions(+), 19 deletions(-) diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 5d57773e730e..0cb53ca8d343 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -675,7 +675,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { size = scnprintf (next, size, - "bus %s, device %s (driver " DRIVER_VERSION ")\n" + "bus %s, device %s\n" "%s\n" "SUSPENDED (no register access)\n", hcd->self.controller->bus->name, @@ -687,7 +687,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) /* Capability Registers */ i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); temp = scnprintf (next, size, - "bus %s, device %s (driver " DRIVER_VERSION ")\n" + "bus %s, device %s\n" "%s\n" "EHCI %x.%02x, hcd state %d\n", hcd->self.controller->bus->name, diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c6f9961eed3c..fcbc1f2b2377 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -60,7 +60,6 @@ * providing early devices for those host controllers to talk to! */ -#define DRIVER_VERSION "10 Dec 2004" #define DRIVER_AUTHOR "David Brownell" #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" @@ -621,9 +620,9 @@ static int ehci_run (struct usb_hcd *hcd) temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); ehci_info (ehci, - "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", + "USB %x.%x started, EHCI %x.%02x%s\n", ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), - temp >> 8, temp & 0xff, DRIVER_VERSION, + temp >> 8, temp & 0xff, ignore_oc ? ", overcurrent ignored" : ""); ehci_writel(ehci, INTR_MASK, @@ -995,9 +994,7 @@ static int ehci_get_frame (struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC - -MODULE_DESCRIPTION (DRIVER_INFO); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR (DRIVER_AUTHOR); MODULE_LICENSE ("GPL"); @@ -1045,6 +1042,10 @@ static int __init ehci_hcd_init(void) { int retval = 0; + if (usb_disabled()) + return -ENODEV; + + printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name); pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", hcd_name, sizeof(struct ehci_qh), sizeof(struct ehci_qtd), diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 7cef1d2f7ccc..d3269656aa4d 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -649,7 +649,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) ohci_dbg_sw (ohci, &next, &size, "bus %s, device %s\n" "%s\n" - "%s version " DRIVER_VERSION "\n", + "%s\n", hcd->self.controller->bus->name, dev_name(hcd->self.controller), hcd->product_desc, diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 89901962cbfd..0afeda836df3 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -46,7 +46,6 @@ #include "../core/hcd.h" -#define DRIVER_VERSION "2006 August 04" #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell" #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" @@ -984,10 +983,8 @@ static int ohci_restart (struct ohci_hcd *ohci) /*-------------------------------------------------------------------------*/ -#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC - MODULE_AUTHOR (DRIVER_AUTHOR); -MODULE_DESCRIPTION (DRIVER_INFO); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE ("GPL"); #ifdef CONFIG_PCI @@ -1095,7 +1092,7 @@ static int __init ohci_hcd_mod_init(void) if (usb_disabled()) return -ENODEV; - printk (KERN_DEBUG "%s: " DRIVER_INFO "\n", hcd_name); + printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name); pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, sizeof (struct ed), sizeof (struct td)); diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 658a2a978c32..e306ca6aef3d 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c @@ -331,7 +331,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) int ret = 0, irq; - dev_dbg(&pdev->dev, "%s: " DRIVER_INFO " (pnx4008)\n", hcd_name); + dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (pnx4008)\n", hcd_name); if (usb_disabled()) { err("USB is disabled"); ret = -ENODEV; diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 3a7bfe7a8874..2dddb258b0db 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -53,7 +53,6 @@ /* * Version Information */ -#define DRIVER_VERSION "v3.0" #define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \ Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \ Alan Stern" @@ -951,12 +950,12 @@ static int __init uhci_hcd_init(void) { int retval = -ENOMEM; - printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "%s\n", - ignore_oc ? ", overcurrent ignored" : ""); - if (usb_disabled()) return -ENODEV; + printk(KERN_INFO "uhci_hcd: " DRIVER_DESC "%s\n", + ignore_oc ? ", overcurrent ignored" : ""); + if (DEBUG_CONFIGURED) { errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); if (!errbuf) -- cgit v1.2.3 From 9beeee6584b9aa4f9192055512411484a2a624df Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 2 Oct 2008 11:48:13 -0400 Subject: USB: EHCI: log a warning if ehci-hcd is not loaded first This patch (as1139) adds a warning to the system log whenever ehci-hcd is loaded after ohci-hcd or uhci-hcd. Nowadays most distributions are pretty good about not doing this; maybe the warning will help convince anyone still doing it wrong. Signed-off-by: Alan Stern Cc: stable [2.6.27] Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 4 ++++ drivers/usb/core/hcd.h | 6 ++++++ drivers/usb/host/ehci-hcd.c | 15 +++++++++++++-- drivers/usb/host/ohci-hcd.c | 3 +++ drivers/usb/host/uhci-hcd.c | 3 +++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index c8035a8216bd..fc9018e72a09 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -81,6 +81,10 @@ /*-------------------------------------------------------------------------*/ +/* Keep track of which host controller drivers are loaded */ +unsigned long usb_hcds_loaded; +EXPORT_SYMBOL_GPL(usb_hcds_loaded); + /* host controllers we manage */ LIST_HEAD (usb_bus_list); EXPORT_SYMBOL_GPL (usb_bus_list); diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index e710ce04e228..2dcde61c465e 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -482,4 +482,10 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, */ extern struct rw_semaphore ehci_cf_port_reset_rwsem; +/* Keep track of which host controller drivers are loaded */ +#define USB_UHCI_LOADED 0 +#define USB_OHCI_LOADED 1 +#define USB_EHCI_LOADED 2 +extern unsigned long usb_hcds_loaded; + #endif /* __KERNEL__ */ diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index fcbc1f2b2377..358df2a6c396 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1046,6 +1046,12 @@ static int __init ehci_hcd_init(void) return -ENODEV; printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name); + set_bit(USB_EHCI_LOADED, &usb_hcds_loaded); + if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) || + test_bit(USB_OHCI_LOADED, &usb_hcds_loaded)) + printk(KERN_WARNING "Warning! ehci_hcd should always be loaded" + " before uhci_hcd and ohci_hcd, not after\n"); + pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", hcd_name, sizeof(struct ehci_qh), sizeof(struct ehci_qtd), @@ -1053,8 +1059,10 @@ static int __init ehci_hcd_init(void) #ifdef DEBUG ehci_debug_root = debugfs_create_dir("ehci", NULL); - if (!ehci_debug_root) - return -ENOENT; + if (!ehci_debug_root) { + retval = -ENOENT; + goto err_debug; + } #endif #ifdef PLATFORM_DRIVER @@ -1102,6 +1110,8 @@ clean0: debugfs_remove(ehci_debug_root); ehci_debug_root = NULL; #endif +err_debug: + clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); return retval; } module_init(ehci_hcd_init); @@ -1123,6 +1133,7 @@ static void __exit ehci_hcd_cleanup(void) #ifdef DEBUG debugfs_remove(ehci_debug_root); #endif + clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); } module_exit(ehci_hcd_cleanup); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 0afeda836df3..8647dab0d7f9 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1095,6 +1095,7 @@ static int __init ohci_hcd_mod_init(void) printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name); pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, sizeof (struct ed), sizeof (struct td)); + set_bit(USB_OHCI_LOADED, &usb_hcds_loaded); #ifdef DEBUG ohci_debug_root = debugfs_create_dir("ohci", NULL); @@ -1181,6 +1182,7 @@ static int __init ohci_hcd_mod_init(void) error_debug: #endif + clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded); return retval; } module_init(ohci_hcd_mod_init); @@ -1211,6 +1213,7 @@ static void __exit ohci_hcd_mod_exit(void) #ifdef DEBUG debugfs_remove(ohci_debug_root); #endif + clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded); } module_exit(ohci_hcd_mod_exit); diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 2dddb258b0db..cf5e4cf7ea42 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -955,6 +955,7 @@ static int __init uhci_hcd_init(void) printk(KERN_INFO "uhci_hcd: " DRIVER_DESC "%s\n", ignore_oc ? ", overcurrent ignored" : ""); + set_bit(USB_UHCI_LOADED, &usb_hcds_loaded); if (DEBUG_CONFIGURED) { errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); @@ -987,6 +988,7 @@ debug_failed: errbuf_failed: + clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded); return retval; } @@ -996,6 +998,7 @@ static void __exit uhci_hcd_cleanup(void) kmem_cache_destroy(uhci_up_cachep); debugfs_remove(uhci_debugfs_root); kfree(errbuf); + clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded); } module_init(uhci_hcd_init); -- cgit v1.2.3 From bb78a825fa91621e52b9a5409fd9ef07895275bf Mon Sep 17 00:00:00 2001 From: Jon K Hellan Date: Fri, 3 Oct 2008 10:36:16 +0200 Subject: USB: Option / AnyData new modem, same ID The AnyData ADU-310 series of wireless modems uses the same product ID as the ADU-E100 series. Signed-off-by: Jon K Hellan Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index fa8ec3af5f38..45b8fc392c5e 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -301,7 +301,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */ - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, -- cgit v1.2.3 From 2da41d5f6c036e7a6e496a7e601a685f8b87acb0 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 6 Oct 2008 11:24:26 -0400 Subject: USB: snoop processes opening usbfs device files This patch (as1148) adds a new "snoop" message to usbfs when a device file is opened, identifying the process responsible. This comes in extremely handy when trying to determine which program is doing some unwanted USB access. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 7a4fa791dc19..528befdcc781 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -624,6 +624,8 @@ static int usbdev_open(struct inode *inode, struct file *file) smp_wmb(); list_add_tail(&ps->list, &dev->filelist); file->private_data = ps; + snoop(&dev->dev, "opened by process %d: %s\n", task_pid_nr(current), + current->comm); out: if (ret) { kfree(ps); -- cgit v1.2.3 From eafe5b99f2135488b21cf17a262c54997c44f784 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 6 Oct 2008 11:25:53 -0400 Subject: USB: EHCI: fix remote-wakeup support for ARC/TDI core This patch (as1147) fixes the remote-wakeup support for EHCI controllers using the ARC/TDI "embedded-TT" core. These controllers turn off the RESUME bit by themselves when a port resume is complete; hence we need to keep separate track of which ports are suspended or in the process of resuming. The patch also makes a couple of small improvements in ehci_irq(), replacing reads of the command register with the value already stored in a local variable. Signed-off-by: Alan Stern Tested-by: Thomas Reitmayr CC: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 14 ++++++++------ drivers/usb/host/ehci-hub.c | 27 +++++++++++++++++++-------- drivers/usb/host/ehci.h | 2 ++ 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 358df2a6c396..d343afacb0b0 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -706,7 +706,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) pcd_status = status; /* resume root hub? */ - if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN)) + if (!(cmd & CMD_RUN)) usb_hcd_resume_root_hub(hcd); while (i--) { @@ -715,8 +715,11 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) if (pstatus & PORT_OWNER) continue; - if (!(pstatus & PORT_RESUME) - || ehci->reset_done [i] != 0) + if (!(test_bit(i, &ehci->suspended_ports) && + ((pstatus & PORT_RESUME) || + !(pstatus & PORT_SUSPEND)) && + (pstatus & PORT_PE) && + ehci->reset_done[i] == 0)) continue; /* start 20 msec resume signaling from this port, @@ -731,9 +734,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* PCI errors [4.15.2.4] */ if (unlikely ((status & STS_FATAL) != 0)) { - dbg_cmd (ehci, "fatal", ehci_readl(ehci, - &ehci->regs->command)); - dbg_status (ehci, "fatal", status); + dbg_cmd(ehci, "fatal", cmd); + dbg_status(ehci, "fatal", status); if (status & STS_HALT) { ehci_err (ehci, "fatal error\n"); dead: diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 740835bb8575..218f9660d7ee 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -236,10 +236,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd) temp = ehci_readl(ehci, &ehci->regs->port_status [i]); temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); if (test_bit(i, &ehci->bus_suspended) && - (temp & PORT_SUSPEND)) { - ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); + (temp & PORT_SUSPEND)) temp |= PORT_RESUME; - } ehci_writel(ehci, temp, &ehci->regs->port_status [i]); } i = HCS_N_PORTS (ehci->hcs_params); @@ -482,10 +480,9 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) * controller by the user. */ - if ((temp & mask) != 0 - || ((temp & PORT_RESUME) != 0 - && time_after_eq(jiffies, - ehci->reset_done[i]))) { + if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend) + || (ehci->reset_done[i] && time_after_eq( + jiffies, ehci->reset_done[i]))) { if (i < 7) buf [0] |= 1 << (i + 1); else @@ -688,6 +685,7 @@ static int ehci_hub_control ( /* resume completed? */ else if (time_after_eq(jiffies, ehci->reset_done[wIndex])) { + clear_bit(wIndex, &ehci->suspended_ports); set_bit(wIndex, &ehci->port_c_suspend); ehci->reset_done[wIndex] = 0; @@ -734,6 +732,9 @@ static int ehci_hub_control ( ehci_readl(ehci, status_reg)); } + if (!(temp & (PORT_RESUME|PORT_RESET))) + ehci->reset_done[wIndex] = 0; + /* transfer dedicated ports to the companion hc */ if ((temp & PORT_CONNECT) && test_bit(wIndex, &ehci->companion_ports)) { @@ -757,8 +758,17 @@ static int ehci_hub_control ( } if (temp & PORT_PE) status |= 1 << USB_PORT_FEAT_ENABLE; - if (temp & (PORT_SUSPEND|PORT_RESUME)) + + /* maybe the port was unsuspended without our knowledge */ + if (temp & (PORT_SUSPEND|PORT_RESUME)) { status |= 1 << USB_PORT_FEAT_SUSPEND; + } else if (test_bit(wIndex, &ehci->suspended_ports)) { + clear_bit(wIndex, &ehci->suspended_ports); + ehci->reset_done[wIndex] = 0; + if (temp & PORT_PE) + set_bit(wIndex, &ehci->port_c_suspend); + } + if (temp & PORT_OC) status |= 1 << USB_PORT_FEAT_OVER_CURRENT; if (temp & PORT_RESET) @@ -803,6 +813,7 @@ static int ehci_hub_control ( || (temp & PORT_RESET) != 0) goto error; ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); + set_bit(wIndex, &ehci->suspended_ports); break; case USB_PORT_FEAT_POWER: if (HCS_PPC (ehci->hcs_params)) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index a6fd550b6903..b11798d17ae5 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -99,6 +99,8 @@ struct ehci_hcd { /* one per controller */ owned by the companion during a bus suspend */ unsigned long port_c_suspend; /* which ports have the change-suspend feature turned on */ + unsigned long suspended_ports; /* which ports are + suspended */ /* per-HC memory pools (could be per-bus, but ...) */ struct dma_pool *qh_pool; /* qh per active urb */ -- cgit v1.2.3 From 49e7cc84a86784ef2ab4e651f1824093be8f5b2b Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 6 Oct 2008 14:45:46 -0700 Subject: USB: Export if an interface driver supports autosuspend. Create a new sysfs file per interface named supports_autosuspend. This file returns true if an interface driver's .supports_autosuspend flag is set. It also returns true if the interface is unclaimed (since the USB core will autosuspend a device if an interface is not claimed). This new sysfs file will be useful for user space scripts to test whether a USB device correctly auto-suspends. Signed-off-by: Sarah Sharp Cc: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-usb | 16 ++++++++++++++++ drivers/usb/core/sysfs.c | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index 11a3c1682cec..df6c8a0159f1 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -85,3 +85,19 @@ Description: Users: PowerTOP http://www.lesswatts.org/projects/powertop/ + +What: /sys/bus/usb/device/-...:-/supports_autosuspend +Date: January 2008 +KernelVersion: 2.6.27 +Contact: Sarah Sharp +Description: + When read, this file returns 1 if the interface driver + for this interface supports autosuspend. It also + returns 1 if no driver has claimed this interface, as an + unclaimed interface will not stop the device from being + autosuspended if all other interface drivers are idle. + The file returns 0 if autosuspend support has not been + added to the driver. +Users: + USB PM tool + git://git.moblin.org/users/sarah/usb-pm-tool/ diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 5e1f5d55bf04..f66fba11fbd5 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -743,6 +743,29 @@ static ssize_t show_modalias(struct device *dev, } static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); +static ssize_t show_supports_autosuspend(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf; + struct usb_device *udev; + int ret; + + intf = to_usb_interface(dev); + udev = interface_to_usbdev(intf); + + usb_lock_device(udev); + /* Devices will be autosuspended even when an interface isn't claimed */ + if (!intf->dev.driver || + to_usb_driver(intf->dev.driver)->supports_autosuspend) + ret = sprintf(buf, "%u\n", 1); + else + ret = sprintf(buf, "%u\n", 0); + usb_unlock_device(udev); + + return ret; +} +static DEVICE_ATTR(supports_autosuspend, S_IRUGO, show_supports_autosuspend, NULL); + static struct attribute *intf_attrs[] = { &dev_attr_bInterfaceNumber.attr, &dev_attr_bAlternateSetting.attr, @@ -751,6 +774,7 @@ static struct attribute *intf_attrs[] = { &dev_attr_bInterfaceSubClass.attr, &dev_attr_bInterfaceProtocol.attr, &dev_attr_modalias.attr, + &dev_attr_supports_autosuspend.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- cgit v1.2.3 From fd7c519dd40a0d561280bb797386143fb2026949 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 10 Oct 2008 16:24:45 +0200 Subject: USB: hub.c: Add initial_descriptor_timeout module parameter for usbcore This patch adds initial_descriptor_timeout module parameter for usbcore.ko to allow modify initial 64-byte USB_REQ_GET_DESCRIPTOR timeout for non-standard devices. For example, the SATA8000 device from DATAST0R Technology Corp requires about 10 seconds to send reply (probably it waits until inserted disk is ready for operation). Also, this patch adds missing usbcore parameters to Documentation/kernel-parameters.txt. Signed-off-by: Jaroslav Kysela Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 19 +++++++++++++++++++ drivers/usb/core/hub.c | 11 ++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index dd28a0d56981..d4f4875fc7c6 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2253,6 +2253,25 @@ and is between 256 and 4096 characters. It is defined in the file autosuspended. Devices for which the delay is set to a negative value won't be autosuspended at all. + usbcore.usbfs_snoop= + [USB] Set to log all usbfs traffic (default 0 = off). + + usbcore.blinkenlights= + [USB] Set to cycle leds on hubs (default 0 = off). + + usbcore.old_scheme_first= + [USB] Start with the old device initialization + scheme (default 0 = off). + + usbcore.use_both_schemes= + [USB] Try the other device initialization scheme + if the first one fails (default 1 = enabled). + + usbcore.initial_descriptor_timeout= + [USB] Specifies timeout for the initial 64-byte + USB_REQ_GET_DESCRIPTOR request in milliseconds + (default 5000 = 5.0 seconds). + usbhid.mousepoll= [USBHID] The interval which mice are to be polled at. diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b97110ca352d..d73ce262c365 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -100,6 +100,15 @@ static int blinkenlights = 0; module_param (blinkenlights, bool, S_IRUGO); MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs"); +/* + * Device SATA8000 FW1.0 from DATAST0R Technology Corp requires about + * 10 seconds to send reply for the initial 64-byte descriptor request. + */ +/* define initial 64-byte descriptor request timeout in milliseconds */ +static int initial_descriptor_timeout = USB_CTRL_GET_TIMEOUT; +module_param(initial_descriptor_timeout, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(initial_descriptor_timeout, "initial 64-byte descriptor request timeout in milliseconds (default 5000 - 5.0 seconds)"); + /* * As of 2.6.10 we introduce a new USB device initialization scheme which * closely resembles the way Windows works. Hopefully it will be compatible @@ -2538,7 +2547,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, USB_DT_DEVICE << 8, 0, buf, GET_DESCRIPTOR_BUFSIZE, - USB_CTRL_GET_TIMEOUT); + initial_descriptor_timeout); switch (buf->bMaxPacketSize0) { case 8: case 16: case 32: case 64: case 255: if (buf->bDescriptorType == -- cgit v1.2.3 From 8b6346ec899713a90890c9e832f7eff91ea73504 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 10 Oct 2008 06:41:16 -0400 Subject: USB: option: add Pantech cards Add some Pantech mobile broadband IDs. Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 45b8fc392c5e..0d18a40a154e 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -213,6 +213,12 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po #define ERICSSON_VENDOR_ID 0x0bdb #define ERICSSON_PRODUCT_F3507G 0x1900 +/* Pantech products */ +#define PANTECH_VENDOR_ID 0x106c +#define PANTECH_PRODUCT_PC5740 0x3701 +#define PANTECH_PRODUCT_PC5750 0x3702 /* PX-500 */ +#define PANTECH_PRODUCT_UM150 0x3711 + static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -333,6 +339,9 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) }, + { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5740) }, + { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5750) }, + { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_UM150) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); -- cgit v1.2.3 From 71b7497c078a97e2afb774ad7c1f8ff5bdda8a60 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 9 Oct 2008 15:40:23 -0400 Subject: USB: OHCI: fix endless polling behavior This patch (as1149) fixes an obscure problem in OHCI polling. In the current code, if the RHSC interrupt status flag turns on at a time when RHSC interrupts are disabled, it will remain on forever: The interrupt handler is the only place where RHSC status gets turned back off; The interrupt handler won't turn RHSC status off because it doesn't turn off status flags if the corresponding interrupt isn't enabled; RHSC interrupts will never get enabled because ohci_root_hub_state_changes() doesn't reenable RHSC if RHSC status is on! As a result we will continue polling indefinitely instead of reverting to interrupt-driven operation, and the root hub will not autosuspend. This particular sequence of events is not at all unusual; in fact plugging a USB device into an OHCI controller will usually cause it to occur. Of course, this is a bug. The proper thing to do is to turn off RHSC status just before reading the actual port status values. That way either a port status change will be detected (if it occurs before the status read) or it will turn RHSC back on. Possibly both, but that won't hurt anything. We can still check for systems in which RHSC is totally broken, by re-reading RHSC after clearing it and before reading the port statuses. (This re-read has to be done anyway, to post the earlier write.) If RHSC is on but no port-change statuses are set, then we know that RHSC is broken and we can avoid re-enabling it. Signed-off-by: Alan Stern Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hub.c | 51 ++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index a150e85c901a..32bbce9718f0 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -359,17 +359,15 @@ static void ohci_finish_controller_resume(struct usb_hcd *hcd) /* Carry out polling-, autostop-, and autoresume-related state changes */ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, - int any_connected) + int any_connected, int rhsc_status) { int poll_rh = 1; - int rhsc_status, rhsc_enable; + int rhsc_enable; /* Some broken controllers never turn off RHCS in the interrupt * status register. For their sake we won't re-enable RHSC * interrupts if the interrupt bit is already active. */ - rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) & - OHCI_INTR_RHSC; rhsc_enable = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC; @@ -421,14 +419,23 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, ohci_rh_resume(ohci); else usb_hcd_resume_root_hub(ohci_to_hcd(ohci)); + + /* If remote wakeup is disabled, stop polling */ + } else if (!ohci->autostop && + !ohci_to_hcd(ohci)->self.root_hub-> + do_remote_wakeup) { + poll_rh = 0; + } else { - if (!rhsc_enable && !rhsc_status && (ohci->autostop || - ohci_to_hcd(ohci)->self.root_hub-> - do_remote_wakeup)) { + /* If no status changes are pending, + * enable RHSC interrupts + */ + if (!rhsc_enable && !rhsc_status) { rhsc_enable = OHCI_INTR_RHSC; ohci_writel(ohci, rhsc_enable, &ohci->regs->intrenable); } + /* Keep polling until RHSC is enabled */ if (rhsc_enable) poll_rh = 0; } @@ -448,22 +455,22 @@ static inline int ohci_rh_resume(struct ohci_hcd *ohci) * autostop isn't used when CONFIG_PM is turned off. */ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, - int any_connected) + int any_connected, int rhsc_status) { - int rhsc_status; - /* If RHSC is enabled, don't poll */ if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC) return 0; - /* If no status changes are pending, enable RHSC interrupts */ - rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) & - OHCI_INTR_RHSC; - if (!changed && !rhsc_status) { - ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); - return 0; - } - return 1; + /* If status changes are pending, continue polling. + * Conversely, if no status changes are pending but the RHSC + * status bit was set, then RHSC may be broken so continue polling. + */ + if (changed || rhsc_status) + return 1; + + /* It's safe to re-enable RHSC interrupts */ + ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); + return 0; } #endif /* CONFIG_PM */ @@ -478,6 +485,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) struct ohci_hcd *ohci = hcd_to_ohci (hcd); int i, changed = 0, length = 1; int any_connected = 0; + int rhsc_status; unsigned long flags; spin_lock_irqsave (&ohci->lock, flags); @@ -503,6 +511,11 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) length++; } + /* Clear the RHSC status flag before reading the port statuses */ + ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrstatus); + rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) & + OHCI_INTR_RHSC; + /* look at each port */ for (i = 0; i < ohci->num_ports; i++) { u32 status = roothub_portstatus (ohci, i); @@ -521,7 +534,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) } hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed, - any_connected); + any_connected, rhsc_status); done: spin_unlock_irqrestore (&ohci->lock, flags); -- cgit v1.2.3 From 84dcd594952bf9b95b3901516a61e57abdf54d62 Mon Sep 17 00:00:00 2001 From: Stephen Ware Date: Wed, 8 Oct 2008 10:53:56 -0700 Subject: USB: fix up problems in the vtusb driver Add range check on buffer sizes passed in from user space (max is 8*PAGE_SIZE) which will work for the most common spectrometers even at pages as small as 1K. Add kref to vst device structure to preserve reference to the usb object until we truly are done with it. From: Stephen Ware From: Dennis O'Brien Signed-off-by: Dennis O'Brien Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/vstusb.c | 54 +++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/usb/misc/vstusb.c b/drivers/usb/misc/vstusb.c index 5ad75e4a0323..8648470c81ca 100644 --- a/drivers/usb/misc/vstusb.c +++ b/drivers/usb/misc/vstusb.c @@ -59,6 +59,8 @@ #define USB_PRODUCT_LABPRO 0x0001 #define USB_PRODUCT_LABQUEST 0x0005 +#define VST_MAXBUFFER (64*1024) + static struct usb_device_id id_table[] = { { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB2000)}, { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_HR4000)}, @@ -73,6 +75,7 @@ static struct usb_device_id id_table[] = { MODULE_DEVICE_TABLE(usb, id_table); struct vstusb_device { + struct kref kref; struct mutex lock; struct usb_device *usb_dev; char present; @@ -83,9 +86,18 @@ struct vstusb_device { int wr_pipe; int wr_timeout_ms; }; +#define to_vst_dev(d) container_of(d, struct vstusb_device, kref) static struct usb_driver vstusb_driver; +static void vstusb_delete(struct kref *kref) +{ + struct vstusb_device *vstdev = to_vst_dev(kref); + + usb_put_dev(vstdev->usb_dev); + kfree(vstdev); +} + static int vstusb_open(struct inode *inode, struct file *file) { struct vstusb_device *vstdev; @@ -114,6 +126,9 @@ static int vstusb_open(struct inode *inode, struct file *file) return -EBUSY; } + /* increment our usage count */ + kref_get(&vstdev->kref); + vstdev->isopen = 1; /* save device in the file's private structure */ @@ -126,7 +141,7 @@ static int vstusb_open(struct inode *inode, struct file *file) return 0; } -static int vstusb_close(struct inode *inode, struct file *file) +static int vstusb_release(struct inode *inode, struct file *file) { struct vstusb_device *vstdev; @@ -138,14 +153,12 @@ static int vstusb_close(struct inode *inode, struct file *file) mutex_lock(&vstdev->lock); vstdev->isopen = 0; - file->private_data = NULL; - /* if device is no longer present */ - if (!vstdev->present) { - mutex_unlock(&vstdev->lock); - kfree(vstdev); - } else - mutex_unlock(&vstdev->lock); + dev_dbg(&vstdev->usb_dev->dev, "%s: released\n", __func__); + + mutex_unlock(&vstdev->lock); + + kref_put(&vstdev->kref, vstusb_delete); return 0; } @@ -268,7 +281,7 @@ static ssize_t vstusb_read(struct file *file, char __user *buffer, return -ENODEV; /* verify that we actually want to read some data */ - if (count == 0) + if ((count == 0) || (count > VST_MAXBUFFER)) return -EINVAL; /* lock this object */ @@ -354,7 +367,7 @@ static ssize_t vstusb_write(struct file *file, const char __user *buffer, return -ENODEV; /* verify that we actually have some data to write */ - if (count == 0) + if ((count == 0) || (count > VST_MAXBUFFER)) return retval; /* lock this object */ @@ -498,7 +511,7 @@ static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case IOCTL_VSTUSB_SEND_PIPE: - if (usb_data.count == 0) { + if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) { mutex_unlock(&vstdev->lock); retval = -EINVAL; goto exit; @@ -551,7 +564,7 @@ static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; case IOCTL_VSTUSB_RECV_PIPE: - if (usb_data.count == 0) { + if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) { mutex_unlock(&vstdev->lock); retval = -EINVAL; goto exit; @@ -633,7 +646,7 @@ static const struct file_operations vstusb_fops = { .unlocked_ioctl = vstusb_ioctl, .compat_ioctl = vstusb_ioctl, .open = vstusb_open, - .release = vstusb_close, + .release = vstusb_release, }; static struct usb_class_driver usb_vstusb_class = { @@ -656,6 +669,10 @@ static int vstusb_probe(struct usb_interface *intf, if (vstdev == NULL) return -ENOMEM; + /* must do usb_get_dev() prior to kref_init() since the kref_put() + * release function will do a usb_put_dev() */ + usb_get_dev(dev); + kref_init(&vstdev->kref); mutex_init(&vstdev->lock); i = dev->descriptor.bcdDevice; @@ -676,7 +693,7 @@ static int vstusb_probe(struct usb_interface *intf, "%s: Not able to get a minor for this device.\n", __func__); usb_set_intfdata(intf, NULL); - kfree(vstdev); + kref_put(&vstdev->kref, vstusb_delete); return retval; } @@ -704,14 +721,11 @@ static void vstusb_disconnect(struct usb_interface *intf) usb_kill_anchored_urbs(&vstdev->submitted); - /* if the device is not opened, then we clean up right now */ - if (!vstdev->isopen) { - mutex_unlock(&vstdev->lock); - kfree(vstdev); - } else - mutex_unlock(&vstdev->lock); + mutex_unlock(&vstdev->lock); + kref_put(&vstdev->kref, vstusb_delete); } + } static int vstusb_suspend(struct usb_interface *intf, pm_message_t message) -- cgit v1.2.3 From 9c94155ea03e85aed66b6822477ea99f8681a3f1 Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:07 +0100 Subject: fsl_usb2_udc: Make dr_ep_setup function static. Make dr_ep_setup function static as it's never used outside this file. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 45ad556169f1..d140e1b1c906 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -315,7 +315,8 @@ static void dr_controller_stop(struct fsl_udc *udc) return; } -void dr_ep_setup(unsigned char ep_num, unsigned char dir, unsigned char ep_type) +static void dr_ep_setup(unsigned char ep_num, unsigned char dir, + unsigned char ep_type) { unsigned int tmp_epctrl = 0; -- cgit v1.2.3 From f6e4411fe7df19493e3a2fbc2543f718f75671f6 Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:08 +0100 Subject: fsl_usb2_udc: Remove check for udc == NULL in dr_controller_setup. Remove check for udc == NULL in dr_controller_setup. All callers of this function have already dereferenced udc at some point. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index d140e1b1c906..3b96aac27af9 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -185,10 +185,6 @@ static int dr_controller_setup(struct fsl_udc *udc) unsigned long timeout; #define FSL_UDC_RESET_TIMEOUT 1000 - /* before here, make sure dr_regs has been initialized */ - if (!udc) - return -EINVAL; - /* Stop and reset the usb controller */ tmp = fsl_readl(&dr_regs->usbcmd); tmp &= ~USB_CMD_RUN_STOP; -- cgit v1.2.3 From 7483cff8a3ea4c31a677a6ac1a4eb3d78adcb9cc Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:09 +0100 Subject: fsl_usb2_udc: Fix some sparse warnings and remove redundant code. Fix some sparse "integer used as NULL pointer" warnings. Remove some unnecessary volatiles and static initialization. Remove some unused struct members and reorder to improve packing. Remove a few unneeded includes. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 28 +++++++++------------------- drivers/usb/gadget/fsl_usb2_udc.h | 21 ++------------------- 2 files changed, 11 insertions(+), 38 deletions(-) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 3b96aac27af9..d242e7eb5a54 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -23,11 +23,8 @@ #include #include #include -#include -#include #include #include -#include #include #include #include @@ -44,11 +41,9 @@ #include #include -#include #include #include #include -#include #include "fsl_usb2_udc.h" @@ -61,8 +56,8 @@ static const char driver_name[] = "fsl-usb2-udc"; static const char driver_desc[] = DRIVER_DESC; -volatile static struct usb_dr_device *dr_regs = NULL; -volatile static struct usb_sys_interface *usb_sys_regs = NULL; +static struct usb_dr_device *dr_regs; +static struct usb_sys_interface *usb_sys_regs; /* it is initialized in probe() */ static struct fsl_udc *udc_controller = NULL; @@ -560,7 +555,7 @@ static int fsl_ep_disable(struct usb_ep *_ep) /* nuke all pending requests (does flush) */ nuke(ep, -ESHUTDOWN); - ep->desc = 0; + ep->desc = NULL; ep->stopped = 1; spin_unlock_irqrestore(&udc->lock, flags); @@ -1565,9 +1560,6 @@ static void port_change_irq(struct fsl_udc *udc) { u32 speed; - if (udc->bus_reset) - udc->bus_reset = 0; - /* Bus resetting is finished */ if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) { /* Get the speed */ @@ -1675,8 +1667,6 @@ static void reset_irq(struct fsl_udc *udc) if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) { VDBG("Bus reset"); - /* Bus is reseting */ - udc->bus_reset = 1; /* Reset all the queues, include XD, dTD, EP queue * head and TR Queue */ reset_queues(udc); @@ -1796,7 +1786,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) /* lock is needed but whether should use this lock or another */ spin_lock_irqsave(&udc_controller->lock, flags); - driver->driver.bus = 0; + driver->driver.bus = NULL; /* hook up the driver */ udc_controller->driver = driver; udc_controller->gadget.dev.driver = &driver->driver; @@ -1806,8 +1796,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) retval = driver->bind(&udc_controller->gadget); if (retval) { VDBG("bind to %s --> %d", driver->driver.name, retval); - udc_controller->gadget.dev.driver = 0; - udc_controller->driver = 0; + udc_controller->gadget.dev.driver = NULL; + udc_controller->driver = NULL; goto out; } @@ -1839,7 +1829,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) return -EINVAL; if (udc_controller->transceiver) - (void)otg_set_peripheral(udc_controller->transceiver, 0); + otg_set_peripheral(udc_controller->transceiver, NULL); /* stop DR, disable intr */ dr_controller_stop(udc_controller); @@ -1860,8 +1850,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) /* unbind gadget and unhook driver. */ driver->unbind(&udc_controller->gadget); - udc_controller->gadget.dev.driver = 0; - udc_controller->driver = 0; + udc_controller->gadget.dev.driver = NULL; + udc_controller->driver = NULL; printk("unregistered gadget driver '%s'\r\n", driver->driver.name); return 0; diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 6131752a38bc..e63ef12645f5 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h @@ -424,16 +424,6 @@ struct ep_td_struct { /* Controller dma boundary */ #define UDC_DMA_BOUNDARY 0x1000 -/* -----------------------------------------------------------------------*/ -/* ##### enum data -*/ -typedef enum { - e_ULPI, - e_UTMI_8BIT, - e_UTMI_16BIT, - e_SERIAL -} e_PhyInterface; - /*-------------------------------------------------------------------------*/ /* ### driver private data @@ -469,9 +459,9 @@ struct fsl_ep { #define EP_DIR_OUT 0 struct fsl_udc { - struct usb_gadget gadget; struct usb_gadget_driver *driver; + struct completion *done; /* to make sure release() is done */ struct fsl_ep *eps; unsigned int max_ep; unsigned int irq; @@ -492,20 +482,13 @@ struct fsl_udc { size_t ep_qh_size; /* size after alignment adjustment*/ dma_addr_t ep_qh_dma; /* dma address of QH */ - u32 max_pipes; /* Device max pipes */ - u32 max_use_endpts; /* Max endpointes to be used */ - u32 bus_reset; /* Device is bus reseting */ + u32 max_pipes; /* Device max pipes */ u32 resume_state; /* USB state to resume */ u32 usb_state; /* USB current state */ - u32 usb_next_state; /* USB next state */ u32 ep0_state; /* Endpoint zero state */ u32 ep0_dir; /* Endpoint zero direction: can be USB_DIR_IN or USB_DIR_OUT */ - u32 usb_sof_count; /* SOF count */ - u32 errors; /* USB ERRORs count */ u8 device_address; /* Device USB address */ - - struct completion *done; /* to make sure release() is done */ }; /*-------------------------------------------------------------------------*/ -- cgit v1.2.3 From bf7409a23b4589e65624ca6bcefe6229a16ea0ae Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:10 +0100 Subject: fsl_usb2_udc: Clean up whitespace in errors and warnings. VDBG always outputs a trailing \n. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index d242e7eb5a54..38ffb06f31ec 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -193,7 +193,7 @@ static int dr_controller_setup(struct fsl_udc *udc) timeout = jiffies + FSL_UDC_RESET_TIMEOUT; while (fsl_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) { if (time_after(jiffies, timeout)) { - ERR("udc reset timeout! \n"); + ERR("udc reset timeout!\n"); return -ETIMEDOUT; } cpu_relax(); @@ -702,7 +702,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, *is_last = 0; if ((*is_last) == 0) - VDBG("multi-dtd request!\n"); + VDBG("multi-dtd request!"); /* Fill in the transfer size; set active bit */ swap_temp = ((*length << DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE); @@ -765,11 +765,11 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* catch various bogus parameters */ if (!_req || !req->req.complete || !req->req.buf || !list_empty(&req->queue)) { - VDBG("%s, bad params\n", __func__); + VDBG("%s, bad params", __func__); return -EINVAL; } if (unlikely(!_ep || !ep->desc)) { - VDBG("%s, bad ep\n", __func__); + VDBG("%s, bad ep", __func__); return -EINVAL; } if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { @@ -1061,7 +1061,7 @@ static int fsl_vbus_session(struct usb_gadget *gadget, int is_active) udc = container_of(gadget, struct fsl_udc, gadget); spin_lock_irqsave(&udc->lock, flags); - VDBG("VBUS %s\n", is_active ? "on" : "off"); + VDBG("VBUS %s", is_active ? "on" : "off"); udc->vbus_active = (is_active != 0); if (can_pullup(udc)) fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP), @@ -1161,7 +1161,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) return -ENOMEM; if (status) - ERR("Can't queue ep0 status request \n"); + ERR("Can't queue ep0 status request\n"); list_add_tail(&req->queue, &ep->queue); return status; @@ -1247,7 +1247,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, goto stall; if (status) { - ERR("Can't respond to getstatus request \n"); + ERR("Can't respond to getstatus request\n"); goto stall; } list_add_tail(&req->queue, &ep->queue); @@ -1389,7 +1389,7 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0, udc->ep0_state = WAIT_FOR_SETUP; break; case WAIT_FOR_SETUP: - ERR("Unexpect ep0 packets \n"); + ERR("Unexpect ep0 packets\n"); break; default: ep0stall(udc); @@ -1468,7 +1468,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe, status = -EILSEQ; break; } else - ERR("Unknown error has occured (0x%x)!\r\n", + ERR("Unknown error has occured (0x%x)!\n", errors); } else if (le32_to_cpu(curr_td->size_ioc_sts) @@ -1487,7 +1487,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe, } } else { td_complete++; - VDBG("dTD transmitted successful "); + VDBG("dTD transmitted successful"); } if (j != curr_req->dtd_count - 1) @@ -1755,7 +1755,7 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) } if (irq_src & (USB_STS_ERR | USB_STS_SYS_ERR)) { - VDBG("Error IRQ %x ", irq_src); + VDBG("Error IRQ %x", irq_src); } spin_unlock_irqrestore(&udc->lock, flags); @@ -1806,12 +1806,12 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) udc_controller->usb_state = USB_STATE_ATTACHED; udc_controller->ep0_state = WAIT_FOR_SETUP; udc_controller->ep0_dir = 0; - printk(KERN_INFO "%s: bind to driver %s \n", + printk(KERN_INFO "%s: bind to driver %s\n", udc_controller->gadget.name, driver->driver.name); out: if (retval) - printk("retval %d \n", retval); + printk("gadget driver register failed %d\n", retval); return retval; } EXPORT_SYMBOL(usb_gadget_register_driver); @@ -1853,7 +1853,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) udc_controller->gadget.dev.driver = NULL; udc_controller->driver = NULL; - printk("unregistered gadget driver '%s'\r\n", driver->driver.name); + printk("unregistered gadget driver '%s'\n", driver->driver.name); return 0; } EXPORT_SYMBOL(usb_gadget_unregister_driver); @@ -2241,7 +2241,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) u32 dccparams; if (strcmp(pdev->name, driver_name)) { - VDBG("Wrong device\n"); + VDBG("Wrong device"); return -ENODEV; } @@ -2259,7 +2259,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) if (!request_mem_region(res->start, res->end - res->start + 1, driver_name)) { - ERR("request mem region for %s failed \n", pdev->name); + ERR("request mem region for %s failed\n", pdev->name); kfree(udc_controller); return -EBUSY; } @@ -2293,7 +2293,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED, driver_name, udc_controller); if (ret != 0) { - ERR("cannot request irq %d err %d \n", + ERR("cannot request irq %d err %d\n", udc_controller->irq, ret); goto err2; } @@ -2456,7 +2456,7 @@ module_init(udc_init); static void __exit udc_exit(void) { platform_driver_unregister(&udc_driver); - printk("%s unregistered \n", driver_desc); + printk("%s unregistered\n", driver_desc); } module_exit(udc_exit); -- cgit v1.2.3 From 9d9d88c80e80397a71745ab80e69edd95e1f6b41 Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:11 +0100 Subject: fsl_usb2_udc: Clean up whitespace in /proc debugging output. Missing spaces were causing the /proc debugging output to be rather unreadable. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 38ffb06f31ec..2bd2c9341f6d 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -1909,7 +1909,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, tmp_reg = fsl_readl(&dr_regs->usbsts); t = scnprintf(next, size, "USB Status Reg:\n" - "Dr Suspend: %d" "Reset Received: %d" "System Error: %s" + "Dr Suspend: %d Reset Received: %d System Error: %s " "USB Error Interrupt: %s\n\n", (tmp_reg & USB_STS_SUSPEND) ? 1 : 0, (tmp_reg & USB_STS_RESET) ? 1 : 0, @@ -1921,11 +1921,11 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, tmp_reg = fsl_readl(&dr_regs->usbintr); t = scnprintf(next, size, "USB Intrrupt Enable Reg:\n" - "Sleep Enable: %d" "SOF Received Enable: %d" + "Sleep Enable: %d SOF Received Enable: %d " "Reset Enable: %d\n" - "System Error Enable: %d" + "System Error Enable: %d " "Port Change Dectected Enable: %d\n" - "USB Error Intr Enable: %d" "USB Intr Enable: %d\n\n", + "USB Error Intr Enable: %d USB Intr Enable: %d\n\n", (tmp_reg & USB_INTR_DEVICE_SUSPEND) ? 1 : 0, (tmp_reg & USB_INTR_SOF_EN) ? 1 : 0, (tmp_reg & USB_INTR_RESET_EN) ? 1 : 0, @@ -1938,21 +1938,21 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, tmp_reg = fsl_readl(&dr_regs->frindex); t = scnprintf(next, size, - "USB Frame Index Reg:" "Frame Number is 0x%x\n\n", + "USB Frame Index Reg: Frame Number is 0x%x\n\n", (tmp_reg & USB_FRINDEX_MASKS)); size -= t; next += t; tmp_reg = fsl_readl(&dr_regs->deviceaddr); t = scnprintf(next, size, - "USB Device Address Reg:" "Device Addr is 0x%x\n\n", + "USB Device Address Reg: Device Addr is 0x%x\n\n", (tmp_reg & USB_DEVICE_ADDRESS_MASK)); size -= t; next += t; tmp_reg = fsl_readl(&dr_regs->endpointlistaddr); t = scnprintf(next, size, - "USB Endpoint List Address Reg:" + "USB Endpoint List Address Reg: " "Device Addr is 0x%x\n\n", (tmp_reg & USB_EP_LIST_ADDRESS_MASK)); size -= t; @@ -1961,11 +1961,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, tmp_reg = fsl_readl(&dr_regs->portsc1); t = scnprintf(next, size, "USB Port Status&Control Reg:\n" - "Port Transceiver Type : %s" "Port Speed: %s \n" - "PHY Low Power Suspend: %s" "Port Reset: %s" - "Port Suspend Mode: %s \n" "Over-current Change: %s" + "Port Transceiver Type : %s Port Speed: %s\n" + "PHY Low Power Suspend: %s Port Reset: %s " + "Port Suspend Mode: %s\n" + "Over-current Change: %s " "Port Enable/Disable Change: %s\n" - "Port Enabled/Disabled: %s" + "Port Enabled/Disabled: %s " "Current Connect Status: %s\n\n", ( { char *s; switch (tmp_reg & PORTSCX_PTS_FSLS) { @@ -2010,7 +2011,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, tmp_reg = fsl_readl(&dr_regs->usbmode); t = scnprintf(next, size, - "USB Mode Reg:" "Controller Mode is : %s\n\n", ( { + "USB Mode Reg: Controller Mode is: %s\n\n", ( { char *s; switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) { case USB_MODE_CTRL_MODE_IDLE: @@ -2029,7 +2030,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, tmp_reg = fsl_readl(&dr_regs->endptsetupstat); t = scnprintf(next, size, - "Endpoint Setup Status Reg:" "SETUP on ep 0x%x\n\n", + "Endpoint Setup Status Reg: SETUP on ep 0x%x\n\n", (tmp_reg & EP_SETUP_STATUS_MASK)); size -= t; next += t; @@ -2042,12 +2043,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, next += t; } tmp_reg = fsl_readl(&dr_regs->endpointprime); - t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n", tmp_reg); + t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n\n", tmp_reg); size -= t; next += t; tmp_reg = usb_sys_regs->snoop1; - t = scnprintf(next, size, "\nSnoop1 Reg : = [0x%x]\n\n", tmp_reg); + t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg); size -= t; next += t; @@ -2071,7 +2072,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, } else { list_for_each_entry(req, &ep->queue, queue) { t = scnprintf(next, size, - "req %p actual 0x%x length 0x%x buf %p\n", + "req %p actual 0x%x length 0x%x buf %p\n", &req->req, req->req.actual, req->req.length, req->req.buf); size -= t; @@ -2097,7 +2098,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, } else { list_for_each_entry(req, &ep->queue, queue) { t = scnprintf(next, size, - "req %p actual 0x%x length" + "req %p actual 0x%x length " "0x%x buf %p\n", &req->req, req->req.actual, req->req.length, req->req.buf); -- cgit v1.2.3 From e06da9a828aa1ef52d1338b7a3d07291a04d581e Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:12 +0100 Subject: fsl_usb2_udc: Initialize spinlock earlier. Move spinlock initialization earlier so we can turn shared irq handler debugging on safely. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 2bd2c9341f6d..7b8cdaec260b 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -2190,7 +2190,6 @@ static int __init struct_udc_setup(struct fsl_udc *udc, udc->usb_state = USB_STATE_POWERED; udc->ep0_dir = 0; udc->remote_wakeup = 0; /* default to 0 on reset */ - spin_lock_init(&udc->lock); return 0; } @@ -2252,6 +2251,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev) return -ENOMEM; } + spin_lock_init(&udc_controller->lock); + udc_controller->stopped = 1; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { kfree(udc_controller); -- cgit v1.2.3 From c93eebbe75a560bb27dc1f09fb1ab7a31d04b990 Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:13 +0100 Subject: fsl_usb2_udc: Rename the arguments of the fsl_writel macro. Rename the arguments of the fsl_writel macro to match their use. Remove a couple of unnecessary prototypes. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 7b8cdaec260b..99a420dbdbc0 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -71,16 +71,14 @@ fsl_ep0_desc = { .wMaxPacketSize = USB_MAX_CTRL_PAYLOAD, }; -static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state); -static int fsl_udc_resume(struct platform_device *pdev); static void fsl_ep_fifo_flush(struct usb_ep *_ep); #ifdef CONFIG_PPC32 #define fsl_readl(addr) in_le32(addr) -#define fsl_writel(addr, val32) out_le32(val32, addr) +#define fsl_writel(val32, addr) out_le32(addr, val32) #else #define fsl_readl(addr) readl(addr) -#define fsl_writel(addr, val32) writel(addr, val32) +#define fsl_writel(val32, addr) writel(val32, addr) #endif /******************************************************************** -- cgit v1.2.3 From 825bee3a3340e720485ef4bde98cbb62e18cb547 Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:14 +0100 Subject: fsl_usb2_udc: Uninline udc_reset_ep_queue. Uninline udc_reset_ep_queue and remove it's unused return value. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 99a420dbdbc0..204cf38c63fb 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -1165,16 +1165,12 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) return status; } -static inline int udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe) +static void udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe) { struct fsl_ep *ep = get_ep_by_pipe(udc, pipe); - if (!ep->name) - return 0; - - nuke(ep, -ESHUTDOWN); - - return 0; + if (ep->name) + nuke(ep, -ESHUTDOWN); } /* -- cgit v1.2.3 From 224b50390104af7602871894540d94cc759dc4c0 Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:15 +0100 Subject: fsl_usb2_udc: Make fsl_queue_td return type void. fsl_queue_td always returns 0. Make it void and remove checks for non-zero return in callers. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 204cf38c63fb..6f6272031344 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -592,7 +592,7 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req) } /*-------------------------------------------------------------------------*/ -static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) +static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) { int i = ep_index(ep) * 2 + ep_is_in(ep); u32 temp, bitmask, tmp_stat; @@ -649,7 +649,7 @@ static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) : (1 << (ep_index(ep))); fsl_writel(temp, &dr_regs->endpointprime); out: - return 0; + return; } /* Fill in the dTD structure @@ -1136,7 +1136,6 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) { struct fsl_req *req = udc->status_req; struct fsl_ep *ep; - int status = 0; if (direction == EP_DIR_IN) udc->ep0_dir = USB_DIR_IN; @@ -1154,15 +1153,13 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) req->dtd_count = 0; if (fsl_req_to_dtd(req) == 0) - status = fsl_queue_td(ep, req); + fsl_queue_td(ep, req); else return -ENOMEM; - if (status) - ERR("Can't queue ep0 status request\n"); list_add_tail(&req->queue, &ep->queue); - return status; + return 0; } static void udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe) @@ -1194,10 +1191,8 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, u16 index, u16 length) { u16 tmp = 0; /* Status, cpu endian */ - struct fsl_req *req; struct fsl_ep *ep; - int status = 0; ep = &udc->eps[0]; @@ -1236,14 +1231,10 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, /* prime the data phase */ if ((fsl_req_to_dtd(req) == 0)) - status = fsl_queue_td(ep, req); + fsl_queue_td(ep, req); else /* no mem */ goto stall; - if (status) { - ERR("Can't respond to getstatus request\n"); - goto stall; - } list_add_tail(&req->queue, &ep->queue); udc->ep0_state = DATA_STATE_XMIT; return; -- cgit v1.2.3 From 59097fb73cf60276053551308524f6c772f305a9 Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:16 +0100 Subject: fsl_usb2_udc: Add a wmb before priming endpoint. Add a wmb to fsl_queue_td before priming the endpoint. This ensures that the modifications to the QH are seen by the hardware. Added comment as suggested by Felipe Balbi. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 6f6272031344..0492441bc0ba 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -643,6 +643,9 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) | EP_QUEUE_HEAD_STATUS_HALT)); dQH->size_ioc_int_sts &= temp; + /* Ensure that updates to the QH will occure before priming. */ + wmb(); + /* Prime endpoint by writing 1 to ENDPTPRIME */ temp = ep_is_in(ep) ? (1 << (ep_index(ep) + 16)) -- cgit v1.2.3 From 23d7cd040e1f43113da3e8763becf576ab86b39a Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 12 Aug 2008 15:39:17 +0100 Subject: fsl_usb2_udc: Fix oops on probe failure. In some circumstances when fsl_udc_probe fails udc_controller is freed but the pointer remains non-NULL. fsl_udc_remove will then try and teardown the partly initialized and freed controller structure resulting in an oops. This patch ensures udc_controller is either NULL or fully initialized after fsl_udc_probe. Signed-off-by: Will Newton Acked-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 0492441bc0ba..091bb55c9aa7 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -2244,21 +2244,21 @@ static int __init fsl_udc_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { - kfree(udc_controller); - return -ENXIO; + ret = -ENXIO; + goto err_kfree; } if (!request_mem_region(res->start, res->end - res->start + 1, driver_name)) { ERR("request mem region for %s failed\n", pdev->name); - kfree(udc_controller); - return -EBUSY; + ret = -EBUSY; + goto err_kfree; } dr_regs = ioremap(res->start, res->end - res->start + 1); if (!dr_regs) { ret = -ENOMEM; - goto err1; + goto err_release_mem_region; } usb_sys_regs = (struct usb_sys_interface *) @@ -2269,7 +2269,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) if (!(dccparams & DCCPARAMS_DC)) { ERR("This SOC doesn't support device role\n"); ret = -ENODEV; - goto err2; + goto err_iounmap; } /* Get max device endpoints */ /* DEN is bidirectional ep number, max_ep doubles the number */ @@ -2278,7 +2278,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) udc_controller->irq = platform_get_irq(pdev, 0); if (!udc_controller->irq) { ret = -ENODEV; - goto err2; + goto err_iounmap; } ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED, @@ -2286,14 +2286,14 @@ static int __init fsl_udc_probe(struct platform_device *pdev) if (ret != 0) { ERR("cannot request irq %d err %d\n", udc_controller->irq, ret); - goto err2; + goto err_iounmap; } /* Initialize the udc structure including QH member and other member */ if (struct_udc_setup(udc_controller, pdev)) { ERR("Can't initialize udc data structure\n"); ret = -ENOMEM; - goto err3; + goto err_free_irq; } /* initialize usb hw reg except for regs for EP, @@ -2314,7 +2314,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) udc_controller->gadget.dev.parent = &pdev->dev; ret = device_register(&udc_controller->gadget.dev); if (ret < 0) - goto err3; + goto err_free_irq; /* setup QH and epctrl for ep0 */ ep0_setup(udc_controller); @@ -2344,20 +2344,22 @@ static int __init fsl_udc_probe(struct platform_device *pdev) DTD_ALIGNMENT, UDC_DMA_BOUNDARY); if (udc_controller->td_pool == NULL) { ret = -ENOMEM; - goto err4; + goto err_unregister; } create_proc_file(); return 0; -err4: +err_unregister: device_unregister(&udc_controller->gadget.dev); -err3: +err_free_irq: free_irq(udc_controller->irq, udc_controller); -err2: +err_iounmap: iounmap(dr_regs); -err1: +err_release_mem_region: release_mem_region(res->start, res->end - res->start + 1); +err_kfree: kfree(udc_controller); + udc_controller = NULL; return ret; } -- cgit v1.2.3 From 928dfa6c625c17d810ae3ee6c73dc37fc4b91bcd Mon Sep 17 00:00:00 2001 From: Li Yang Date: Wed, 24 Sep 2008 15:50:26 +0800 Subject: usb/fsl_qe_udc: fix response to get status request The original code didn't respond correctly to get status request on device and endpoint. Although normal operations can work without the fix. It is not compliant with USB spec chapter9 and fails USBCV ch9 tests. The patch fix this and a few style/typo problems. Signed-off-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_qe_udc.c | 101 ++++++++++++++++++++++++++-------------- drivers/usb/gadget/fsl_qe_udc.h | 1 + 2 files changed, 68 insertions(+), 34 deletions(-) diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index e9400e62f171..d9aad6894b3e 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -1138,7 +1138,7 @@ static int qe_ep_tx(struct qe_ep *ep, struct qe_frame *frame) } } -/* when an bd was transmitted, the function can * +/* when a bd was transmitted, the function can * handle the tx_req, not include ep0 */ static int txcomplete(struct qe_ep *ep, unsigned char restart) { @@ -1174,7 +1174,7 @@ static int txcomplete(struct qe_ep *ep, unsigned char restart) return 0; } -/* give a frame and a tx_req,send some data */ +/* give a frame and a tx_req, send some data */ static int qe_usb_senddata(struct qe_ep *ep, struct qe_frame *frame) { unsigned int size; @@ -1797,11 +1797,6 @@ static int qe_ep_set_halt(struct usb_ep *_ep, int value) goto out; } - if (ep->epnum != 0) { - status = 0; - goto out; - } - udc = ep->udc; /* Attempt to halt IN ep will fail if any transfer requests * are still queue */ @@ -1821,7 +1816,7 @@ static int qe_ep_set_halt(struct usb_ep *_ep, int value) udc->ep0_dir = 0; } out: - dev_vdbg(udc->dev, " %s %s halt stat %d\n", ep->ep.name, + dev_vdbg(udc->dev, "%s %s halt stat %d\n", ep->ep.name, value ? "set" : "clear", status); return status; @@ -1953,22 +1948,51 @@ static void ownercomplete(struct usb_ep *_ep, struct usb_request *_req) kfree(req); } -static void ch9getstatus(struct qe_udc *udc, u16 value, u16 index, - u16 length) +static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value, + u16 index, u16 length) { - u16 usb_status = 0; /* fix me to give correct status */ - + u16 usb_status = 0; struct qe_req *req; struct qe_ep *ep; int status = 0; ep = &udc->eps[0]; + if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) { + /* Get device status */ + usb_status = 1 << USB_DEVICE_SELF_POWERED; + } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { + /* Get interface status */ + /* We don't have interface information in udc driver */ + usb_status = 0; + } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) { + /* Get endpoint status */ + int pipe = index & USB_ENDPOINT_NUMBER_MASK; + struct qe_ep *target_ep = &udc->eps[pipe]; + u16 usep; + + /* stall if endpoint doesn't exist */ + if (!target_ep->desc) + goto stall; + + usep = in_be16(&udc->usb_regs->usb_usep[pipe]); + if (index & USB_DIR_IN) { + if (target_ep->dir != USB_DIR_IN) + goto stall; + if ((usep & USB_THS_MASK) == USB_THS_STALL) + usb_status = 1 << USB_ENDPOINT_HALT; + } else { + if (target_ep->dir != USB_DIR_OUT) + goto stall; + if ((usep & USB_RHS_MASK) == USB_RHS_STALL) + usb_status = 1 << USB_ENDPOINT_HALT; + } + } req = container_of(qe_alloc_request(&ep->ep, GFP_KERNEL), struct qe_req, req); req->req.length = 2; - req->req.buf = udc->nullbuf; - memcpy(req->req.buf, (u8 *)&usb_status, 2); + req->req.buf = udc->statusbuf; + *(u16 *)req->req.buf = cpu_to_le16(usb_status); req->req.status = -EINPROGRESS; req->req.actual = 0; req->req.complete = ownercomplete; @@ -1978,10 +2002,11 @@ static void ch9getstatus(struct qe_udc *udc, u16 value, u16 index, /* data phase */ status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC); - if (status) { - dev_err(udc->dev, "Can't respond to getstatus request \n"); - qe_ep0_stall(udc); - } + if (status == 0) + return; +stall: + dev_err(udc->dev, "Can't respond to getstatus request \n"); + qe_ep0_stall(udc); } /* only handle the setup request, suppose the device in normal status */ @@ -2007,7 +2032,8 @@ static void setup_received_handle(struct qe_udc *udc, if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) != (USB_DIR_IN | USB_TYPE_STANDARD)) break; - ch9getstatus(udc, wValue, wIndex, wLength); + ch9getstatus(udc, setup->bRequestType, wValue, wIndex, + wLength); return; case USB_REQ_SET_ADDRESS: @@ -2021,7 +2047,7 @@ static void setup_received_handle(struct qe_udc *udc, case USB_REQ_CLEAR_FEATURE: case USB_REQ_SET_FEATURE: /* Requests with no data phase, status phase from udc */ - if ((setup->bRequestType & USB_TYPE_MASK) + if ((setup->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) break; @@ -2055,7 +2081,7 @@ static void setup_received_handle(struct qe_udc *udc, if (setup->bRequestType & USB_DIR_IN) { udc->ep0_state = DATA_STATE_XMIT; udc->ep0_dir = USB_DIR_IN; - } else{ + } else { udc->ep0_state = DATA_STATE_RECV; udc->ep0_dir = USB_DIR_OUT; } @@ -2160,13 +2186,11 @@ static int tx_irq(struct qe_udc *udc) bd = ep->c_txbd; if (!(in_be32((u32 __iomem *)bd) & T_R) && (in_be32(&bd->buf))) { - /* Disable the TX Interrupt */ - /*confirm the transmitted bd*/ + /* confirm the transmitted bd */ if (ep->epnum == 0) res = qe_ep0_txconf(ep); else res = qe_ep_txconf(ep); - /* Enable the TX Interrupt */ } } } @@ -2205,7 +2229,6 @@ static irqreturn_t qe_udc_irq(int irq, void *_udc) irqreturn_t status = IRQ_NONE; unsigned long flags; - spin_lock_irqsave(&udc->lock, flags); irq_src = in_be16(&udc->usb_regs->usb_usber) & @@ -2520,10 +2543,9 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, udc_controller->gadget.dev.release = qe_udc_release; udc_controller->gadget.dev.parent = &ofdev->dev; - - /* EP:intialization qe_ep struct */ + /* initialize qe_ep struct */ for (i = 0; i < USB_MAX_ENDPOINTS ; i++) { - /*because the ep type isn't decide here so + /* because the ep type isn't decide here so * qe_ep_init() should be called in ep_enable() */ /* setup the qe_ep struct and link ep.ep.list @@ -2536,7 +2558,7 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, if (ret) goto err2; - /* create a buf for ZLP send */ + /* create a buf for ZLP send, need to remain zeroed */ udc_controller->nullbuf = kzalloc(256, GFP_KERNEL); if (udc_controller->nullbuf == NULL) { dev_dbg(udc_controller->dev, "cannot alloc nullbuf\n"); @@ -2544,6 +2566,13 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, goto err3; } + /* buffer for data of get_status request */ + udc_controller->statusbuf = kzalloc(2, GFP_KERNEL); + if (udc_controller->statusbuf == NULL) { + ret = -ENOMEM; + goto err4; + } + udc_controller->nullp = virt_to_phys((void *)udc_controller->nullbuf); if (udc_controller->nullp == DMA_ADDR_INVALID) { udc_controller->nullp = dma_map_single( @@ -2568,20 +2597,21 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, if (ret) { dev_err(udc_controller->dev, "cannot request irq %d err %d \n", udc_controller->usb_irq, ret); - goto err4; + goto err5; } ret = device_add(&udc_controller->gadget.dev); if (ret) - goto err5; + goto err6; dev_info(udc_controller->dev, - "QE/CPM USB controller initialized as device\n"); + "%s USB controller initialized as device\n", + (udc_controller->soc_type == PORT_QE) ? "QE" : "CPM"); return 0; -err5: +err6: free_irq(udc_controller->usb_irq, udc_controller); -err4: +err5: if (udc_controller->nullmap) { dma_unmap_single(udc_controller->gadget.dev.parent, udc_controller->nullp, 256, @@ -2592,6 +2622,8 @@ err4: udc_controller->nullp, 256, DMA_TO_DEVICE); } + kfree(udc_controller->statusbuf); +err4: kfree(udc_controller->nullbuf); err3: ep = &udc_controller->eps[0]; @@ -2642,6 +2674,7 @@ static int __devexit qe_udc_remove(struct of_device *ofdev) udc_controller->nullp, 256, DMA_TO_DEVICE); } + kfree(udc_controller->statusbuf); kfree(udc_controller->nullbuf); ep = &udc_controller->eps[0]; diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/fsl_qe_udc.h index b4c07a22e8e7..31b2710882e4 100644 --- a/drivers/usb/gadget/fsl_qe_udc.h +++ b/drivers/usb/gadget/fsl_qe_udc.h @@ -349,6 +349,7 @@ struct qe_udc { u32 c_end; u8 *nullbuf; + u8 *statusbuf; dma_addr_t nullp; u8 nullmap; u8 device_address; /* Device USB address */ -- cgit v1.2.3 From 15d5a9acb1df1e22a7ba60aaaad758d9d71e5ea7 Mon Sep 17 00:00:00 2001 From: Li Yang Date: Wed, 24 Sep 2008 15:50:27 +0800 Subject: usb/fsl_qe_udc: clear data toggle on clear halt request Fix to comply with USB spec. Signed-off-by: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_qe_udc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index d9aad6894b3e..1fe8b44787b3 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -1815,6 +1815,10 @@ static int qe_ep_set_halt(struct usb_ep *_ep, int value) udc->ep0_state = WAIT_FOR_SETUP; udc->ep0_dir = 0; } + + /* set data toggle to DATA0 on clear halt */ + if (value == 0) + ep->data01 = 0; out: dev_vdbg(udc->dev, "%s %s halt stat %d\n", ep->ep.name, value ? "set" : "clear", status); -- cgit v1.2.3 From 1817b1692a2eab022e805d32e910f4556c89dce8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Aug 2008 09:37:34 -0700 Subject: USB: remove warn() macro from usb input drivers USB should not be having it's own printk macros, so remove warn() and use the system-wide standard of dev_warn() wherever possible. In the few places that will not work out, use a basic printk(). Cc: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/joystick/iforce/iforce-ff.c | 36 ++++++++++++++++---------- drivers/input/joystick/iforce/iforce-main.c | 14 +++++----- drivers/input/joystick/iforce/iforce-packets.c | 8 +++--- drivers/input/joystick/iforce/iforce-usb.c | 2 +- drivers/input/misc/ati_remote.c | 14 +++++----- drivers/input/tablet/aiptek.c | 13 ++++++---- 6 files changed, 52 insertions(+), 35 deletions(-) diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c index 7839b7b6fa96..0de9a0943a9e 100644 --- a/drivers/input/joystick/iforce/iforce-ff.c +++ b/drivers/input/joystick/iforce/iforce-ff.c @@ -197,13 +197,16 @@ static unsigned char find_button(struct iforce *iforce, signed short button) * Analyse the changes in an effect, and tell if we need to send an condition * parameter packet */ -static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new) +static int need_condition_modifier(struct iforce *iforce, + struct ff_effect *old, + struct ff_effect *new) { int ret = 0; int i; if (new->type != FF_SPRING && new->type != FF_FRICTION) { - warn("bad effect type in need_condition_modifier"); + dev_warn(&iforce->dev->dev, "bad effect type in %s\n", + __func__); return 0; } @@ -222,10 +225,13 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new) * Analyse the changes in an effect, and tell if we need to send a magnitude * parameter packet */ -static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect) +static int need_magnitude_modifier(struct iforce *iforce, + struct ff_effect *old, + struct ff_effect *effect) { if (effect->type != FF_CONSTANT) { - warn("bad effect type in need_envelope_modifier"); + dev_warn(&iforce->dev->dev, "bad effect type in %s\n", + __func__); return 0; } @@ -236,7 +242,8 @@ static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effe * Analyse the changes in an effect, and tell if we need to send an envelope * parameter packet */ -static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effect) +static int need_envelope_modifier(struct iforce *iforce, struct ff_effect *old, + struct ff_effect *effect) { switch (effect->type) { case FF_CONSTANT: @@ -256,7 +263,8 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec break; default: - warn("bad effect type in need_envelope_modifier"); + dev_warn(&iforce->dev->dev, "bad effect type in %s\n", + __func__); } return 0; @@ -266,10 +274,12 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec * Analyse the changes in an effect, and tell if we need to send a periodic * parameter effect */ -static int need_period_modifier(struct ff_effect *old, struct ff_effect *new) +static int need_period_modifier(struct iforce *iforce, struct ff_effect *old, + struct ff_effect *new) { if (new->type != FF_PERIODIC) { - warn("bad effect type in need_period_modifier"); + dev_warn(&iforce->dev->dev, "bad effect type in %s\n", + __func__); return 0; } return (old->u.periodic.period != new->u.periodic.period @@ -355,7 +365,7 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru int param2_err = 1; int core_err = 0; - if (!old || need_period_modifier(old, effect)) { + if (!old || need_period_modifier(iforce, old, effect)) { param1_err = make_period_modifier(iforce, mod1_chunk, old != NULL, effect->u.periodic.magnitude, effect->u.periodic.offset, @@ -365,7 +375,7 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru set_bit(FF_MOD1_IS_USED, core_effect->flags); } - if (!old || need_envelope_modifier(old, effect)) { + if (!old || need_envelope_modifier(iforce, old, effect)) { param2_err = make_envelope_modifier(iforce, mod2_chunk, old !=NULL, effect->u.periodic.envelope.attack_length, @@ -425,7 +435,7 @@ int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, stru int param2_err = 1; int core_err = 0; - if (!old || need_magnitude_modifier(old, effect)) { + if (!old || need_magnitude_modifier(iforce, old, effect)) { param1_err = make_magnitude_modifier(iforce, mod1_chunk, old != NULL, effect->u.constant.level); @@ -434,7 +444,7 @@ int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, stru set_bit(FF_MOD1_IS_USED, core_effect->flags); } - if (!old || need_envelope_modifier(old, effect)) { + if (!old || need_envelope_modifier(iforce, old, effect)) { param2_err = make_envelope_modifier(iforce, mod2_chunk, old != NULL, effect->u.constant.envelope.attack_length, @@ -487,7 +497,7 @@ int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, str default: return -1; } - if (!old || need_condition_modifier(old, effect)) { + if (!old || need_condition_modifier(iforce, old, effect)) { param_err = make_condition_modifier(iforce, mod1_chunk, old != NULL, effect->u.condition[0].right_saturation, diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 61ee6e38739d..baabf8302645 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -218,7 +218,9 @@ static void iforce_release(struct input_dev *dev) /* Check: no effects should be present in memory */ for (i = 0; i < dev->ff->max_effects; i++) { if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) { - warn("iforce_release: Device still owns effects"); + dev_warn(&dev->dev, + "%s: Device still owns effects\n", + __func__); break; } } @@ -335,26 +337,26 @@ int iforce_init_device(struct iforce *iforce) if (!iforce_get_id_packet(iforce, "M")) input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1]; else - warn("Device does not respond to id packet M"); + dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n"); if (!iforce_get_id_packet(iforce, "P")) input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1]; else - warn("Device does not respond to id packet P"); + dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n"); if (!iforce_get_id_packet(iforce, "B")) iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1]; else - warn("Device does not respond to id packet B"); + dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n"); if (!iforce_get_id_packet(iforce, "N")) ff_effects = iforce->edata[1]; else - warn("Device does not respond to id packet N"); + dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n"); /* Check if the device can store more effects than the driver can really handle */ if (ff_effects > IFORCE_EFFECTS_MAX) { - warn("Limiting number of effects to %d (device reports %d)", + dev_warn(&iforce->dev->dev, "Limiting number of effects to %d (device reports %d)\n", IFORCE_EFFECTS_MAX, ff_effects); ff_effects = IFORCE_EFFECTS_MAX; } diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 015b50aa76fc..a17b50016009 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c @@ -65,7 +65,8 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data) if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) { - warn("not enough space in xmit buffer to send new packet"); + dev_warn(&iforce->dev->dev, + "not enough space in xmit buffer to send new packet\n"); spin_unlock_irqrestore(&iforce->xmit_lock, flags); return -1; } @@ -148,7 +149,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr) return 0; } } - warn("unused effect %04x updated !!!", addr); + dev_warn(&iforce->dev->dev, "unused effect %04x updated !!!\n", addr); return -1; } @@ -159,7 +160,8 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) static int being_used = 0; if (being_used) - warn("re-entrant call to iforce_process %d", being_used); + dev_warn(&iforce->dev->dev, + "re-entrant call to iforce_process %d\n", being_used); being_used++; #ifdef CONFIG_JOYSTICK_IFORCE_232 diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 851cc4087c2f..f83185aeb511 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -64,7 +64,7 @@ void iforce_usb_xmit(struct iforce *iforce) if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) { clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); - warn("usb_submit_urb failed %d\n", n); + dev_warn(&iforce->dev->dev, "usb_submit_urb failed %d\n", n); } /* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended. diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c index debfc1af9d95..428ecd3294a3 100644 --- a/drivers/input/misc/ati_remote.c +++ b/drivers/input/misc/ati_remote.c @@ -285,7 +285,6 @@ static const struct { }; /* Local function prototypes */ -static void ati_remote_dump (unsigned char *data, unsigned int actual_length); static int ati_remote_open (struct input_dev *inputdev); static void ati_remote_close (struct input_dev *inputdev); static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data); @@ -307,15 +306,16 @@ static struct usb_driver ati_remote_driver = { /* * ati_remote_dump_input */ -static void ati_remote_dump(unsigned char *data, unsigned int len) +static void ati_remote_dump(struct device *dev, unsigned char *data, + unsigned int len) { if ((len == 1) && (data[0] != (unsigned char)0xff) && (data[0] != 0x00)) - warn("Weird byte 0x%02x", data[0]); + dev_warn(dev, "Weird byte 0x%02x\n", data[0]); else if (len == 4) - warn("Weird key %02x %02x %02x %02x", + dev_warn(dev, "Weird key %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3]); else - warn("Weird data, len=%d %02x %02x %02x %02x %02x %02x ...", + dev_warn(dev, "Weird data, len=%d %02x %02x %02x %02x %02x %02x ...\n", len, data[0], data[1], data[2], data[3], data[4], data[5]); } @@ -470,7 +470,7 @@ static void ati_remote_input_report(struct urb *urb) /* Deal with strange looking inputs */ if ( (urb->actual_length != 4) || (data[0] != 0x14) || ((data[3] & 0x0f) != 0x00) ) { - ati_remote_dump(data, urb->actual_length); + ati_remote_dump(&urb->dev->dev, data, urb->actual_length); return; } @@ -814,7 +814,7 @@ static void ati_remote_disconnect(struct usb_interface *interface) ati_remote = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); if (!ati_remote) { - warn("%s - null device?\n", __func__); + dev_warn(&interface->dev, "%s - null device?\n", __func__); return; } diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index e53c838f1866..1aa82e8af614 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -1706,20 +1706,21 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL); inputdev = input_allocate_device(); if (!aiptek || !inputdev) { - warn("aiptek: cannot allocate memory or input device"); + dev_warn(&intf->dev, + "cannot allocate memory or input device\n"); goto fail1; } aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH, GFP_ATOMIC, &aiptek->data_dma); if (!aiptek->data) { - warn("aiptek: cannot allocate usb buffer"); + dev_warn(&intf->dev, "cannot allocate usb buffer\n"); goto fail1; } aiptek->urb = usb_alloc_urb(0, GFP_KERNEL); if (!aiptek->urb) { - warn("aiptek: cannot allocate urb"); + dev_warn(&intf->dev, "cannot allocate urb\n"); goto fail2; } @@ -1864,7 +1865,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) */ err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group); if (err) { - warn("aiptek: cannot create sysfs group err: %d", err); + dev_warn(&intf->dev, "cannot create sysfs group err: %d\n", + err); goto fail3; } @@ -1872,7 +1874,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) */ err = input_register_device(aiptek->inputdev); if (err) { - warn("aiptek: input_register_device returned err: %d", err); + dev_warn(&intf->dev, + "input_register_device returned err: %d\n", err); goto fail4; } return 0; -- cgit v1.2.3 From aa82661baf8a48379355ffa8bf162b07cf487600 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Aug 2008 09:37:34 -0700 Subject: USB: remove warn() macro from usb media drivers USB should not be having it's own printk macros, so remove warn() and use the system-wide standard of dev_warn() wherever possible. In the few places that will not work out, use a basic printk(). Cc: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/radio/dsbr100.c | 13 ++++++++----- drivers/media/video/dabusb.c | 4 ++-- drivers/media/video/ov511.c | 19 ++++++++++++------- drivers/media/video/usbvideo/konicawc.c | 8 +++++--- drivers/media/video/usbvideo/quickcam_messenger.c | 14 ++++++++------ 5 files changed, 35 insertions(+), 23 deletions(-) diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 66783fffe4c1..78f56944e640 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -310,7 +310,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, radio->curfreq = f->frequency; if (dsbr100_setfreq(radio, radio->curfreq)==-1) - warn("Set frequency failed"); + dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); return 0; } @@ -361,12 +361,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv, case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { if (dsbr100_stop(radio) == -1) { - warn("Radio did not respond properly"); + dev_warn(&radio->usbdev->dev, + "Radio did not respond properly\n"); return -EBUSY; } } else { if (dsbr100_start(radio) == -1) { - warn("Radio did not respond properly"); + dev_warn(&radio->usbdev->dev, + "Radio did not respond properly\n"); return -EBUSY; } } @@ -416,7 +418,8 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file) radio->muted = 1; if (dsbr100_start(radio)<0) { - warn("Radio did not start up properly"); + dev_warn(&radio->usbdev->dev, + "Radio did not start up properly\n"); radio->users = 0; unlock_kernel(); return -EIO; @@ -501,7 +504,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf, radio->curfreq = FREQ_MIN*FREQ_MUL; video_set_drvdata(radio->videodev, radio); if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) { - warn("Could not register video device"); + dev_warn(&intf->dev, "Could not register video device\n"); video_device_release(radio->videodev); kfree(radio->transfer_buffer); kfree(radio); diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c index 3aa538afcc0b..298810d5262b 100644 --- a/drivers/media/video/dabusb.c +++ b/drivers/media/video/dabusb.c @@ -192,7 +192,7 @@ static void dabusb_iso_complete (struct urb *purb) err("dabusb_iso_complete: invalid len %d", len); } else - warn("dabusb_iso_complete: corrupted packet status: %d", purb->iso_frame_desc[i].status); + dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status); if (dst != purb->actual_length) err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length); } @@ -289,7 +289,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb) } if( ret == -EPIPE ) { - warn("CLEAR_FEATURE request to remove STALL condition."); + dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n"); if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe))) err("request failed"); } diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 935d73de57bd..210f1240b331 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -1098,9 +1098,10 @@ ov51x_clear_snapshot(struct usb_ov511 *ov) reg_w(ov, R51x_SYS_SNAP, 0x02); reg_w(ov, R51x_SYS_SNAP, 0x00); } else if (ov->bclass == BCL_OV518) { - warn("snapshot reset not supported yet on OV518(+)"); + dev_warn(&ov->dev->dev, + "snapshot reset not supported yet on OV518(+)\n"); } else { - err("clear snap: invalid bridge type"); + dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n"); } } @@ -1115,14 +1116,16 @@ ov51x_check_snapshot(struct usb_ov511 *ov) if (ov->bclass == BCL_OV511) { ret = reg_r(ov, R51x_SYS_SNAP); if (ret < 0) { - err("Error checking snspshot status (%d)", ret); + dev_err(&ov->dev->dev, + "Error checking snspshot status (%d)\n", ret); } else if (ret & 0x08) { status = 1; } } else if (ov->bclass == BCL_OV518) { - warn("snapshot check not supported yet on OV518(+)"); + dev_warn(&ov->dev->dev, + "snapshot check not supported yet on OV518(+)\n"); } else { - err("check snap: invalid bridge type"); + dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n"); } return status; @@ -5217,7 +5220,8 @@ saa7111a_configure(struct usb_ov511 *ov) if (ov->bclass == BCL_OV511) reg_w(ov, 0x11, 0x00); else - warn("SAA7111A not yet supported with OV518/OV518+"); + dev_warn(&ov->dev->dev, + "SAA7111A not yet supported with OV518/OV518+\n"); return 0; } @@ -5456,7 +5460,8 @@ ov518_configure(struct usb_ov511 *ov) * required. OV518 has no uncompressed mode, to save RAM. */ if (!dumppix && !ov->compress) { ov->compress = 1; - warn("Compression required with OV518...enabling"); + dev_warn(&ov->dev->dev, + "Compression required with OV518...enabling\n"); } if (ov->bridge == BRG_OV518) { diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c index e986c28b7bb0..da27a5287983 100644 --- a/drivers/media/video/usbvideo/konicawc.c +++ b/drivers/media/video/usbvideo/konicawc.c @@ -229,7 +229,8 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev cam->input = input_dev = input_allocate_device(); if (!input_dev) { - warn("Not enough memory for camera's input device\n"); + dev_warn(&dev->dev, + "Not enough memory for camera's input device\n"); return; } @@ -243,8 +244,9 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev error = input_register_device(cam->input); if (error) { - warn("Failed to register camera's input device, err: %d\n", - error); + dev_warn(&dev->dev, + "Failed to register camera's input device, err: %d\n", + error); input_free_device(cam->input); cam->input = NULL; } diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c index 05c61b523115..4459b8a7f818 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/drivers/media/video/usbvideo/quickcam_messenger.c @@ -93,7 +93,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev) cam->input = input_dev = input_allocate_device(); if (!input_dev) { - warn("insufficient mem for cam input device"); + dev_warn(&dev->dev, "insufficient mem for cam input device\n"); return; } @@ -107,8 +107,9 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev) error = input_register_device(cam->input); if (error) { - warn("Failed to register camera's input device, err: %d\n", - error); + dev_warn(&dev->dev, + "Failed to register camera's input device, err: %d\n", + error); input_free_device(cam->input); cam->input = NULL; } @@ -587,8 +588,9 @@ static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb) dataurb->iso_frame_desc[i].offset; if (st < 0) { - warn("Data error: packet=%d. len=%d. status=%d.", - i, n, st); + dev_warn(&uvd->dev->dev, + "Data error: packet=%d. len=%d. status=%d.\n", + i, n, st); uvd->stats.iso_err_count++; continue; } @@ -699,7 +701,7 @@ static void qcm_stop_data(struct uvd *uvd) ret = qcm_camera_off(uvd); if (ret) - warn("couldn't turn the cam off."); + dev_warn(&uvd->dev->dev, "couldn't turn the cam off.\n"); uvd->streaming = 0; -- cgit v1.2.3 From 4dc8994806a812044e48514af60d4b4e0315f237 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Aug 2008 09:37:34 -0700 Subject: USB: remove warn() macro from usb net drivers USB should not be having it's own printk macros, so remove warn() and use the system-wide standard of dev_warn() wherever possible. In the few places that will not work out, use a basic printk(). Cc: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- drivers/net/irda/stir4200.c | 10 +++++----- drivers/net/usb/catc.c | 5 +++-- drivers/net/usb/kaweth.c | 8 ++++---- drivers/net/usb/rtl8150.c | 16 ++++++++-------- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index 051963782749..148ce2803b00 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -506,7 +506,7 @@ static int change_speed(struct stir_cb *stir, unsigned speed) goto found; } - warn("%s: invalid speed %d", stir->netdev->name, speed); + dev_warn(&stir->netdev->dev, "invalid speed %d\n", speed); return -EINVAL; found: @@ -598,8 +598,8 @@ static int fifo_txwait(struct stir_cb *stir, int space) err = read_reg(stir, REG_FIFOCTL, stir->fifo_status, FIFO_REGS_SIZE); if (unlikely(err != FIFO_REGS_SIZE)) { - warn("%s: FIFO register read error: %d", - stir->netdev->name, err); + dev_warn(&stir->netdev->dev, + "FIFO register read error: %d\n", err); return err; } @@ -836,8 +836,8 @@ static void stir_rcv_irq(struct urb *urb) /* in case of error, the kernel thread will restart us */ if (err) { - warn("%s: usb receive submit error: %d", - stir->netdev->name, err); + dev_warn(&stir->netdev->dev, "usb receive submit error: %d\n", + err); stir->receiving = 0; wake_up_process(stir->thread); } diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 22c17bbacb69..92ff9c83d9f2 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -456,7 +456,7 @@ static void catc_tx_timeout(struct net_device *netdev) { struct catc *catc = netdev_priv(netdev); - warn("Transmit timed out."); + dev_warn(&netdev->dev, "Transmit timed out.\n"); usb_unlink_urb(catc->tx_urb); } @@ -847,7 +847,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id dbg("64k Memory\n"); break; default: - warn("Couldn't detect memory size, assuming 32k"); + dev_warn(&intf->dev, + "Couldn't detect memory size, assuming 32k\n"); case 0x87654321: catc_set_reg(catc, TxBufCount, 4); catc_set_reg(catc, RxBufCount, 16); diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index d6829db51b45..4f7a0106781e 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -832,7 +832,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC))) { - warn("kaweth failed tx_urb %d", res); + dev_warn(&net->dev, "kaweth failed tx_urb %d\n", res); skip: kaweth->stats.tx_errors++; @@ -924,7 +924,7 @@ static void kaweth_tx_timeout(struct net_device *net) { struct kaweth_device *kaweth = netdev_priv(net); - warn("%s: Tx timed out. Resetting.", net->name); + dev_warn(&net->dev, "%s: Tx timed out. Resetting.\n", net->name); kaweth->stats.tx_errors++; net->trans_start = jiffies; @@ -1209,7 +1209,7 @@ static void kaweth_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (!kaweth) { - warn("unregistering non-existant device"); + dev_warn(&intf->dev, "unregistering non-existant device\n"); return; } netdev = kaweth->net; @@ -1269,7 +1269,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) if (!wait_event_timeout(awd.wqh, awd.done, timeout)) { // timeout - warn("usb_control/bulk_msg: timeout"); + dev_warn(&urb->dev->dev, "usb_control/bulk_msg: timeout\n"); usb_kill_urb(urb); // remove urb safely status = -ETIMEDOUT; } diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index df56a518691c..7726b5e86764 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -221,7 +221,7 @@ static void ctrl_callback(struct urb *urb) case -ENOENT: break; default: - warn("ctrl urb status %d", urb->status); + dev_warn(&urb->dev->dev, "ctrl urb status %d\n", urb->status); } dev = urb->context; clear_bit(RX_REG_SET, &dev->flags); @@ -441,10 +441,10 @@ static void read_bulk_callback(struct urb *urb) case -ENOENT: return; /* the urb is in unlink state */ case -ETIME: - warn("may be reset is needed?.."); + dev_warn(&urb->dev->dev, "may be reset is needed?..\n"); goto goon; default: - warn("Rx status %d", urb->status); + dev_warn(&urb->dev->dev, "Rx status %d\n", urb->status); goto goon; } @@ -665,7 +665,7 @@ static int enable_net_traffic(rtl8150_t * dev) u8 cr, tcr, rcr, msr; if (!rtl8150_reset(dev)) { - warn("%s - device reset failed", __FUNCTION__); + dev_warn(&dev->udev->dev, "device reset failed\n"); } /* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */ rcr = 0x9e; @@ -699,7 +699,7 @@ static struct net_device_stats *rtl8150_netdev_stats(struct net_device *dev) static void rtl8150_tx_timeout(struct net_device *netdev) { rtl8150_t *dev = netdev_priv(netdev); - warn("%s: Tx timeout.", netdev->name); + dev_warn(&netdev->dev, "Tx timeout.\n"); usb_unlink_urb(dev->tx_urb); dev->stats.tx_errors++; } @@ -740,7 +740,7 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev) if (res == -ENODEV) netif_device_detach(dev->netdev); else { - warn("failed tx_urb %d\n", res); + dev_warn(&netdev->dev, "failed tx_urb %d\n", res); dev->stats.tx_errors++; netif_start_queue(netdev); } @@ -783,7 +783,7 @@ static int rtl8150_open(struct net_device *netdev) if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) { if (res == -ENODEV) netif_device_detach(dev->netdev); - warn("%s: rx_urb submit failed: %d", __FUNCTION__, res); + dev_warn(&netdev->dev, "rx_urb submit failed: %d\n", res); return res; } usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), @@ -792,7 +792,7 @@ static int rtl8150_open(struct net_device *netdev) if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) { if (res == -ENODEV) netif_device_detach(dev->netdev); - warn("%s: intr_urb submit failed: %d", __FUNCTION__, res); + dev_warn(&netdev->dev, "intr_urb submit failed: %d\n", res); usb_kill_urb(dev->rx_urb); return res; } -- cgit v1.2.3 From 3b6004f3b5a8b4506fa8dee29667aed44913a990 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Aug 2008 09:37:34 -0700 Subject: USB: remove warn() macro from usb drivers USB should not be having it's own printk macros, so remove warn() and use the system-wide standard of dev_warn() wherever possible. In the few places that will not work out, use a basic printk(). Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/usbatm.c | 10 +++++----- drivers/usb/atm/usbatm.h | 10 ++++++++-- drivers/usb/atm/xusbatm.c | 2 +- drivers/usb/core/devio.c | 3 ++- drivers/usb/core/inode.c | 6 ++++-- drivers/usb/core/message.c | 3 ++- drivers/usb/image/mdc800.c | 8 +++++--- drivers/usb/misc/usblcd.c | 2 +- drivers/usb/misc/uss720.c | 7 ++++--- 9 files changed, 32 insertions(+), 19 deletions(-) diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 0da2c25bab3b..06dd114910d4 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -344,7 +344,7 @@ static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char __func__, sarb->len, vcc); /* discard cells already received */ skb_trim(sarb, 0); - UDSL_ASSERT(sarb->tail + ATM_CELL_PAYLOAD <= sarb->end); + UDSL_ASSERT(instance, sarb->tail + ATM_CELL_PAYLOAD <= sarb->end); } memcpy(skb_tail_pointer(sarb), source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD); @@ -432,7 +432,7 @@ static void usbatm_extract_cells(struct usbatm_data *instance, unsigned char *cell_buf = instance->cell_buf; unsigned int space_left = stride - buf_usage; - UDSL_ASSERT(buf_usage <= stride); + UDSL_ASSERT(instance, buf_usage <= stride); if (avail_data >= space_left) { /* add new data and process cell */ @@ -475,7 +475,7 @@ static unsigned int usbatm_write_cells(struct usbatm_data *instance, unsigned int stride = instance->tx_channel.stride; vdbg("%s: skb->len=%d, avail_space=%u", __func__, skb->len, avail_space); - UDSL_ASSERT(!(avail_space % stride)); + UDSL_ASSERT(instance, !(avail_space % stride)); for (bytes_written = 0; bytes_written < avail_space && ctrl->len; bytes_written += stride, target += stride) { @@ -547,7 +547,7 @@ static void usbatm_rx_process(unsigned long data) if (!urb->iso_frame_desc[i].status) { unsigned int actual_length = urb->iso_frame_desc[i].actual_length; - UDSL_ASSERT(actual_length <= packet_size); + UDSL_ASSERT(instance, actual_length <= packet_size); if (!merge_length) merge_start = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset; @@ -1188,7 +1188,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, struct urb *urb; unsigned int iso_packets = usb_pipeisoc(channel->endpoint) ? channel->buf_size / channel->packet_size : 0; - UDSL_ASSERT(!usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint)); + UDSL_ASSERT(instance, !usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint)); urb = usb_alloc_urb(iso_packets, GFP_KERNEL); if (!urb) { diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index e6887c6cf3cf..f6f4508a9d42 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h @@ -40,9 +40,15 @@ */ #ifdef DEBUG -#define UDSL_ASSERT(x) BUG_ON(!(x)) +#define UDSL_ASSERT(instance, x) BUG_ON(!(x)) #else -#define UDSL_ASSERT(x) do { if (!(x)) warn("failed assertion '%s' at line %d", __stringify(x), __LINE__); } while(0) +#define UDSL_ASSERT(instance, x) \ + do { \ + if (!(x)) \ + dev_warn(&(instance)->usb_intf->dev, \ + "failed assertion '%s' at line %d", \ + __stringify(x), __LINE__); \ + } while(0) #endif #define usb_err(instance, format, arg...) \ diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index 8472543eee81..17d167bbd2dc 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c @@ -193,7 +193,7 @@ static int __init xusbatm_init(void) num_vendor != num_product || num_vendor != num_rx_endpoint || num_vendor != num_tx_endpoint) { - warn("malformed module parameters"); + printk(KERN_WARNING "xusbatm: malformed module parameters\n"); return -EINVAL; } diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 528befdcc781..7f621149f9f2 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -413,7 +413,8 @@ static void driver_disconnect(struct usb_interface *intf) if (likely(ifnum < 8*sizeof(ps->ifclaimed))) clear_bit(ifnum, &ps->ifclaimed); else - warn("interface number %u out of range", ifnum); + dev_warn(&intf->dev, "interface number %u out of range\n", + ifnum); usb_set_intfdata(intf, NULL); diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 77fa7a080801..2cf2dc8528d8 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -240,7 +240,9 @@ static void update_sb(struct super_block *sb) update_special(bus); break; default: - warn("Unknown node %s mode %x found on remount!\n",bus->d_name.name,bus->d_inode->i_mode); + printk(KERN_WARNING "usbfs: Unknown node %s " + "mode %x found on remount!\n", + bus->d_name.name, bus->d_inode->i_mode); break; } } @@ -259,7 +261,7 @@ static int remount(struct super_block *sb, int *flags, char *data) return 0; if (parse_options(sb, data)) { - warn("usbfs: mount parameter error:"); + printk(KERN_WARNING "usbfs: mount parameter error.\n"); return -EINVAL; } diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 286b4431a097..887738577b28 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1204,7 +1204,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) alt = usb_altnum_to_altsetting(iface, alternate); if (!alt) { - warn("selecting invalid altsetting %d", alternate); + dev_warn(&dev->dev, "selecting invalid altsetting %d", + alternate); return -EINVAL; } diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 0fb114ca1eba..228552beb534 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -361,7 +361,8 @@ static int mdc800_usb_waitForIRQ (int mode, int msec) if (mdc800->state == NOT_CONNECTED) { - warn ("Camera gets disconnected during waiting for irq."); + printk(KERN_WARNING "mdc800: Camera gets disconnected " + "during waiting for irq.\n"); mdc800->camera_request_ready=0; return -2; } @@ -443,7 +444,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, if (mdc800->dev != NULL) { - warn ("only one Mustek MDC800 is supported."); + dev_warn(&intf->dev, "only one Mustek MDC800 is supported.\n"); return -ENODEV; } @@ -701,7 +702,8 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l } if (mdc800->state == WORKING) { - warn ("Illegal State \"working\" reached during read ?!"); + printk(KERN_WARNING "mdc800: Illegal State \"working\"" + "reached during read ?!\n"); mutex_unlock(&mdc800->io_lock); return -EBUSY; } diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 2db4228fbb01..d589324bb0d0 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -311,7 +311,7 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id dev->interface = interface; if (le16_to_cpu(dev->udev->descriptor.idProduct) != 0x0001) { - warn(KERN_INFO "USBLCD model not supported."); + dev_warn(&interface->dev, "USBLCD model not supported.\n"); return -ENODEV; } diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index f1255b0a182d..594f3e4e8c2e 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -228,11 +228,12 @@ static int get_1284_register(struct parport *pp, unsigned char reg, unsigned cha ret = rq->urb->status; *val = priv->reg[(reg >= 9) ? 0 : regindex[reg]]; if (ret) - warn("get_1284_register: usb error %d", ret); + printk(KERN_WARNING "get_1284_register: " + "usb error %d\n", ret); kref_put(&rq->ref_count, destroy_async); return ret; } - warn("get_1284_register timeout"); + printk(KERN_WARNING "get_1284_register timeout\n"); kill_all_async_requests_priv(priv); return -EIO; } @@ -716,7 +717,7 @@ static int uss720_probe(struct usb_interface *intf, spin_lock_init(&priv->asynclock); INIT_LIST_HEAD(&priv->asynclist); if (!(pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops))) { - warn("could not register parport"); + printk(KERN_WARNING "uss720: could not register parport\n"); goto probe_abort; } -- cgit v1.2.3 From 46fcaec505d957c87b2f3820314f9e4dc0631777 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 15 Oct 2008 11:30:07 -0700 Subject: USB: remove warn macro from HID core There were two stragglers that got missed in the last merge of the HID tree that forgot to change the warn() calls to dev_warn(). This patch fixes them up. Acked-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/usbhid/hid-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 1d3b8a394d46..705a43cdeea4 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -428,7 +428,7 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC); if (!usbhid->out[usbhid->outhead].raw_report) { spin_unlock_irqrestore(&usbhid->outlock, flags); - warn("output queueing failed"); + dev_warn(&hid->dev, "output queueing failed\n"); return; } hid_output_report(report, usbhid->out[usbhid->outhead].raw_report); @@ -455,7 +455,7 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC); if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) { spin_unlock_irqrestore(&usbhid->ctrllock, flags); - warn("control queueing failed"); + dev_warn(&hid->dev, "control queueing failed\n"); return; } hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report); -- cgit v1.2.3 From c197a8db59daf06dc5e77acd5a9681329cb22458 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 18 Aug 2008 13:21:04 -0700 Subject: USB: remove info() macro from usb/serial drivers USB should not be having it's own printk macros, so remove info() and use the system-wide standard of dev_info() wherever possible. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/belkin_sa.c | 5 +++-- drivers/usb/serial/cp2101.c | 3 ++- drivers/usb/serial/cyberjack.c | 5 +++-- drivers/usb/serial/cypress_m8.c | 3 ++- drivers/usb/serial/digi_acceleport.c | 3 ++- drivers/usb/serial/empeg.c | 3 ++- drivers/usb/serial/ftdi_sio.c | 11 +++++++---- drivers/usb/serial/garmin_gps.c | 3 ++- drivers/usb/serial/hp4x.c | 3 ++- drivers/usb/serial/io_edgeport.c | 3 ++- drivers/usb/serial/io_ti.c | 3 ++- drivers/usb/serial/ipaq.c | 3 ++- drivers/usb/serial/ipw.c | 3 ++- drivers/usb/serial/ir-usb.c | 3 ++- drivers/usb/serial/iuu_phoenix.c | 3 ++- drivers/usb/serial/keyspan.c | 3 ++- drivers/usb/serial/keyspan_pda.c | 3 ++- drivers/usb/serial/kl5kusb105.c | 23 ++++++++++++----------- drivers/usb/serial/kobil_sct.c | 4 ++-- drivers/usb/serial/mct_u232.c | 3 ++- drivers/usb/serial/mos7720.c | 3 ++- drivers/usb/serial/mos7840.c | 3 ++- drivers/usb/serial/omninet.c | 3 ++- drivers/usb/serial/option.c | 3 ++- drivers/usb/serial/pl2303.c | 2 +- drivers/usb/serial/safe_serial.c | 13 ++++++------- drivers/usb/serial/sierra.c | 3 ++- drivers/usb/serial/spcp8x5.c | 3 ++- drivers/usb/serial/ti_usb_3410_5052.c | 3 ++- drivers/usb/serial/usb-serial.c | 7 ++++--- drivers/usb/serial/visor.c | 15 +++++++++------ drivers/usb/serial/whiteheat.c | 8 +++++--- 32 files changed, 96 insertions(+), 63 deletions(-) diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 1913bc7c5f0b..bb19f1c2e0d3 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -187,7 +187,7 @@ static int belkin_sa_startup(struct usb_serial *serial) /* see comments at top of file */ priv->bad_flow_control = (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0; - info("bcdDevice: %04x, bfc: %d", + dev_info(&dev->dev, "bcdDevice: %04x, bfc: %d\n", le16_to_cpu(dev->descriptor.bcdDevice), priv->bad_flow_control); @@ -577,7 +577,8 @@ static int __init belkin_sa_init(void) retval = usb_register(&belkin_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&belkin_device); diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 1279553381e3..8008d0bc80ad 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -753,7 +753,8 @@ static int __init cp2101_init(void) } /* Success */ - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; } diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 94ef36c4764b..068680f9929d 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -499,8 +499,9 @@ static int __init cyberjack_init(void) if (retval) goto failed_usb_register; - info(DRIVER_VERSION " " DRIVER_AUTHOR); - info(DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION " " + DRIVER_AUTHOR "\n"); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); return 0; failed_usb_register: diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index f3514a91f915..e0ca809f75f5 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -1658,7 +1658,8 @@ static int __init cypress_init(void) if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 5756ac6d6c92..ebc2918719a0 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -1854,7 +1854,8 @@ static int __init digi_init(void) retval = usb_register(&digi_driver); if (retval) goto failed_usb_register; - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&digi_acceleport_4_device); diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 1072e847280f..fdd28e940bc1 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -519,7 +519,8 @@ static int __init empeg_init(void) if (retval) goto failed_usb_register; - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 89dab5c3682c..bcadb1f4f5dd 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1154,7 +1154,7 @@ static void ftdi_determine_type(struct usb_serial_port *port) /* Assume its an FT232R */ priv->chip_type = FT232RL; } - info("Detected %s", ftdi_chip_name[priv->chip_type]); + dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); } @@ -1410,7 +1410,8 @@ static int ftdi_jtag_probe(struct usb_serial *serial) dbg("%s", __func__); if (interface == udev->actconfig->interface[0]) { - info("Ignoring serial port reserved for JTAG"); + dev_info(&udev->dev, + "Ignoring serial port reserved for JTAG\n"); return -ENODEV; } @@ -1428,7 +1429,8 @@ static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) if (ep->enabled && ep_desc->wMaxPacketSize == 0) { ep_desc->wMaxPacketSize = cpu_to_le16(0x40); - info("Fixing invalid wMaxPacketSize on read pipe"); + dev_info(&serial->dev->dev, + "Fixing invalid wMaxPacketSize on read pipe\n"); } return 0; @@ -2426,7 +2428,8 @@ static int __init ftdi_init(void) if (retval) goto failed_usb_register; - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&ftdi_sio_device); diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 2ad0569bcf19..8e6a66e38db2 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1585,7 +1585,8 @@ static int __init garmin_init(void) retval = usb_register(&garmin_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index ab905869e959..431329275133 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c @@ -63,7 +63,8 @@ static int __init hp49gp_init(void) retval = usb_register(&hp49gp_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&hp49gp_device); diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 611f97fd62f1..eb95efdfbe8b 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -3253,7 +3253,8 @@ static int __init edgeport_init(void) if (retval) goto failed_usb_register; atomic_set(&CmdUrbs, 0); - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 541dd8e6e7a2..c3cdd00ddc41 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2978,7 +2978,8 @@ static int __init edgeport_init(void) retval = usb_register(&io_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&edgeport_2port_device); diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 2affa9c118b2..5108cbc64a55 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -976,7 +976,6 @@ static int __init ipaq_init(void) retval = usb_serial_register(&ipaq_device); if (retval) goto failed_usb_serial_register; - info(DRIVER_DESC " " DRIVER_VERSION); if (vendor) { ipaq_id_table[0].idVendor = vendor; ipaq_id_table[0].idProduct = product; @@ -985,6 +984,8 @@ static int __init ipaq_init(void) if (retval) goto failed_usb_register; + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&ipaq_device); diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 480cac27d646..3ac59a8a980f 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -485,7 +485,8 @@ static int usb_ipw_init(void) usb_serial_deregister(&ipw_device); return retval; } - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; } diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 45d4043e04ab..b679a556b98d 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -602,7 +602,8 @@ static int __init ir_init(void) if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 53710aa7eadd..e320972cb227 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -1185,7 +1185,8 @@ static int __init iuu_init(void) retval = usb_register(&iuu_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&iuu_device); diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 15447af48691..9878c0fb3859 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -217,7 +217,8 @@ static int __init keyspan_init(void) if (retval) goto failed_usb_register; - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 99e9a14c5bf6..2928ba844394 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -874,7 +874,8 @@ static int __init keyspan_pda_init(void) retval = usb_register(&keyspan_pda_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: #ifdef XIRCOM diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index ff3a07f5102f..573c6972fae7 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -183,11 +183,10 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port, KLSI_TIMEOUT); if (rc < 0) err("Change port settings failed (error = %d)", rc); - info("%s - %d byte block, baudrate %x, databits %d, u1 %d, u2 %d", - __func__, - settings->pktlen, - settings->baudrate, settings->databits, - settings->unknown1, settings->unknown2); + dev_info(&port->serial->dev->dev, + "%d byte block, baudrate %x, databits %d, u1 %d, u2 %d\n", + settings->pktlen, settings->baudrate, settings->databits, + settings->unknown1, settings->unknown2); return rc; } /* klsi_105_chg_port_settings */ @@ -215,7 +214,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, __u8 status_buf[KLSI_STATUSBUF_LEN] = { -1, -1}; __u16 status; - info("%s - sending SIO Poll request", __func__); + dev_info(&port->serial->dev->dev, "sending SIO Poll request\n"); rc = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), KL5KUSB105A_SIO_POLL, @@ -230,8 +229,8 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, else { status = get_unaligned_le16(status_buf); - info("%s - read status %x %x", __func__, - status_buf[0], status_buf[1]); + dev_info(&port->serial->dev->dev, "read status %x %x", + status_buf[0], status_buf[1]); *line_state_p = klsi_105_status2linestate(status); } @@ -475,8 +474,9 @@ static void klsi_105_close(struct tty_struct *tty, /* FIXME */ /* wgg - do I need this? I think so. */ usb_kill_urb(port->interrupt_in_urb); - info("kl5kusb105 port stats: %ld bytes in, %ld bytes out", - priv->bytes_in, priv->bytes_out); + dev_info(&port->serial->dev->dev, + "port stats: %ld bytes in, %ld bytes out\n", + priv->bytes_in, priv->bytes_out); } /* klsi_105_close */ @@ -960,7 +960,8 @@ static int __init klsi_105_init(void) if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&kl5kusb105d_device); diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index cfcf37c2b957..6286baad9392 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -744,8 +744,8 @@ static int __init kobil_init(void) if (retval) goto failed_usb_register; - info(DRIVER_VERSION " " DRIVER_AUTHOR); - info(DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 9b2cef81cde0..29fa66ea2d21 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -817,7 +817,8 @@ static int __init mct_u232_init(void) retval = usb_register(&mct_u232_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&mct_u232_device); diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 7b538caec37f..5711aa55d24b 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1585,7 +1585,8 @@ static int __init moschip7720_init(void) if (retval) goto failed_port_device_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); /* Register with the usb */ retval = usb_register(&usb_driver); diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 60543d79ef56..d5f682626e71 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -2743,7 +2743,8 @@ static int __init moschip7840_init(void) goto failed_port_device_register; dbg("%s\n", "Entring..."); - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); /* Register with the usb */ retval = usb_register(&io_driver); diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index c4d70b0f1e48..9890f26cd91d 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -364,7 +364,8 @@ static int __init omninet_init(void) retval = usb_register(&omninet_driver); if (retval) goto failed_usb_register; - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&zyxel_omninet_device); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 0d18a40a154e..3d87eabcd922 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -420,7 +420,8 @@ static int __init option_init(void) if (retval) goto failed_driver_register; - info(DRIVER_DESC ": " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 908437847165..491c8857b644 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -1147,7 +1147,7 @@ static int __init pl2303_init(void) retval = usb_register(&pl2303_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&pl2303_device); diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 72903ac9f5c0..40cff61cb4a2 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -250,8 +250,8 @@ static void safe_read_bulk_callback(struct urb *urb) if (!fcs) { int actual_length = data[length - 2] >> 2; if (actual_length <= (length - 2)) { - info("%s - actual: %d", __func__, - actual_length); + dev_info(&urb->dev->dev, "%s - actual: %d\n", + __func__, actual_length); tty_insert_flip_string(tty, data, actual_length); tty_flip_buffer_push(tty); @@ -428,14 +428,13 @@ static int __init safe_init(void) { int i, retval; - info(DRIVER_VERSION " " DRIVER_AUTHOR); - info(DRIVER_DESC); - info("vendor: %x product: %x safe: %d padded: %d\n", - vendor, product, safe, padded); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); /* if we have vendor / product parameters patch them into id list */ if (vendor || product) { - info("vendor: %x product: %x\n", vendor, product); + printk(KERN_INFO KBUILD_MODNAME ": vendor: %x product: %x\n", + vendor, product); for (i = 0; i < ARRAY_SIZE(id_table); i++) { if (!id_table[i].idVendor && !id_table[i].idProduct) { diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 6794e5721df6..0f2b67244af6 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -750,7 +750,8 @@ static int __init sierra_init(void) if (retval) goto failed_driver_register; - info(DRIVER_DESC ": " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 1533d6e12238..96aeec746191 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -1054,7 +1054,8 @@ static int __init spcp8x5_init(void) retval = usb_register(&spcp8x5_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&spcp8x5_device); diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index a9523b8348da..31c42d1cae13 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -382,7 +382,8 @@ static int __init ti_init(void) if (ret) goto failed_usb; - info(TI_DRIVER_DESC " " TI_DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " TI_DRIVER_VERSION ":" + TI_DRIVER_DESC "\n"); return 0; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index e7d4246027b2..92ba4f7361e4 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1160,7 +1160,7 @@ static int __init usb_serial_init(void) goto exit_generic; } - info(DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); return result; @@ -1237,7 +1237,7 @@ int usb_serial_register(struct usb_serial_driver *driver) retval, driver->description); list_del(&driver->driver_list); } else - info("USB Serial support registered for %s", + printk(KERN_INFO "USB Serial support registered for %s\n", driver->description); return retval; @@ -1248,7 +1248,8 @@ EXPORT_SYMBOL_GPL(usb_serial_register); void usb_serial_deregister(struct usb_serial_driver *device) { /* must be called with BKL held */ - info("USB Serial deregistering driver %s", device->description); + printk(KERN_INFO "USB Serial deregistering driver %s\n", + device->description); list_del(&device->driver_list); usb_serial_bus_deregister(device); } diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index a6d1c75a1c89..de4b5f0e7f3d 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -971,11 +971,14 @@ static int __init visor_init(void) break; } } - info( - "Untested USB device specified at time of module insertion"); - info("Warning: This is not guaranteed to work"); - info("Using a newer kernel is preferred to this method"); - info("Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x", + printk(KERN_INFO KBUILD_MODNAME + ": Untested USB device specified at time of module insertion\n"); + printk(KERN_INFO KBUILD_MODNAME + ": Warning: This is not guaranteed to work\n"); + printk(KERN_INFO KBUILD_MODNAME + ": Using a newer kernel is preferred to this method\n"); + printk(KERN_INFO KBUILD_MODNAME + ": Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x\n", vendor, product); } retval = usb_serial_register(&handspring_device); @@ -990,7 +993,7 @@ static int __init visor_init(void) retval = usb_register(&visor_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); return 0; failed_usb_register: diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 11c8b97a5177..39f7f8d291d6 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -452,8 +452,9 @@ static int whiteheat_attach(struct usb_serial *serial) hw_info = (struct whiteheat_hw_info *)&result[1]; - info("%s: Driver %s: Firmware v%d.%02d", serial->type->description, - DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev); + dev_info(&serial->dev->dev, "%s: Driver %s: Firmware v%d.%02d\n", + serial->type->description, DRIVER_VERSION, + hw_info->sw_major_rev, hw_info->sw_minor_rev); for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; @@ -1556,7 +1557,8 @@ static int __init whiteheat_init(void) retval = usb_register(&whiteheat_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&whiteheat_device); -- cgit v1.2.3 From 1b29a375fb0b79a11a2d18e7bf5f6da422a35025 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 18 Aug 2008 13:21:04 -0700 Subject: USB: remove info() macro from usb/misc drivers USB should not be having it's own printk macros, so remove info() and use the system-wide standard of dev_info() wherever possible. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/adutux.c | 5 +++-- drivers/usb/misc/cytherm.c | 3 ++- drivers/usb/misc/emi26.c | 4 ++-- drivers/usb/misc/emi62.c | 4 ++-- drivers/usb/misc/idmouse.c | 5 +++-- drivers/usb/misc/legousbtower.c | 23 +++++++++++++---------- drivers/usb/misc/rio500.c | 11 ++++++----- drivers/usb/misc/trancevibrator.c | 3 ++- drivers/usb/misc/usblcd.c | 11 ++++++----- drivers/usb/misc/uss720.c | 12 ++++++++---- 10 files changed, 47 insertions(+), 34 deletions(-) diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 965f6eaea6a0..92f58ccc8fb3 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -895,8 +895,9 @@ static int __init adu_init(void) goto exit; } - info("adutux " DRIVER_DESC " " DRIVER_VERSION); - info("adutux is an experimental driver. Use at your own risk"); + printk(KERN_INFO "adutux " DRIVER_DESC " " DRIVER_VERSION "\n"); + printk(KERN_INFO "adutux is an experimental driver. " + "Use at your own risk\n"); exit: dbg(2," %s : leave, return value %d", __func__, result); diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index 1cd9e7eba93b..68e1d1723873 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c @@ -428,7 +428,8 @@ static int __init usb_cytherm_init(void) return result; } - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; } diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 4b994a0cd272..1ee72055f468 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c @@ -64,7 +64,7 @@ static int emi26_writememory (struct usb_device *dev, int address, static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit) { int response; - info("%s - %d", __func__, reset_bit); + dev_info(&dev->dev, "%s - %d\n", __func__, reset_bit); /* printk(KERN_DEBUG "%s - %d", __func__, reset_bit); */ response = emi26_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0); if (response < 0) { @@ -254,7 +254,7 @@ static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *i { struct usb_device *dev = interface_to_usbdev(intf); - info("%s start", __func__); + dev_info(&intf->dev, "%s start\n", __func__); emi26_load_firmware(dev); diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 5d859ded5bbf..602ee05ba9ff 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c @@ -73,7 +73,7 @@ static int emi62_writememory(struct usb_device *dev, int address, static int emi62_set_reset (struct usb_device *dev, unsigned char reset_bit) { int response; - info("%s - %d", __func__, reset_bit); + dev_info(&dev->dev, "%s - %d\n", __func__, reset_bit); response = emi62_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0); if (response < 0) { @@ -271,7 +271,7 @@ static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_device *dev = interface_to_usbdev(intf); dev_dbg(&intf->dev, "emi62_probe\n"); - info("%s start", __func__); + dev_info(&intf->dev, "%s start\n", __func__); emi62_load_firmware(dev); diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 4bcf7fb4e5da..6da8887538c7 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -403,14 +403,15 @@ static void idmouse_disconnect(struct usb_interface *interface) mutex_unlock(&dev->lock); } - info("%s disconnected", DRIVER_DESC); + dev_info(&interface->dev, "disconnected\n"); } static int __init usb_idmouse_init(void) { int result; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); /* register this driver with the USB subsystem */ result = usb_register(&idmouse_driver); diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 9370326a5940..ab0f3226158b 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -851,9 +851,8 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device dbg(2, "%s: enter", __func__); - if (udev == NULL) { - info ("udev is NULL."); - } + if (udev == NULL) + dev_info(&interface->dev, "udev is NULL.\n"); /* allocate memory for our device state and initialize it */ @@ -954,7 +953,9 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device dev->minor = interface->minor; /* let the user know what node this device is now attached to */ - info ("LEGO USB Tower #%d now attached to major %d minor %d", (dev->minor - LEGO_USB_TOWER_MINOR_BASE), USB_MAJOR, dev->minor); + dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major " + "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE), + USB_MAJOR, dev->minor); /* get the firmware version and log it */ result = usb_control_msg (udev, @@ -971,10 +972,10 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device retval = result; goto error; } - info("LEGO USB Tower firmware version is %d.%d build %d", - get_version_reply.major, - get_version_reply.minor, - le16_to_cpu(get_version_reply.build_no)); + dev_info(&interface->dev, "LEGO USB Tower firmware version is %d.%d " + "build %d\n", get_version_reply.major, + get_version_reply.minor, + le16_to_cpu(get_version_reply.build_no)); exit: @@ -1021,7 +1022,8 @@ static void tower_disconnect (struct usb_interface *interface) mutex_unlock(&dev->lock); } - info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE)); + dev_info(&interface->dev, "LEGO USB Tower #%d now disconnected\n", + (minor - LEGO_USB_TOWER_MINOR_BASE)); dbg(2, "%s: leave", __func__); } @@ -1046,7 +1048,8 @@ static int __init lego_usb_tower_init(void) goto exit; } - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); exit: dbg(2, "%s: leave, return value %d", __func__, retval); diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 248a12aacef6..deb95bb49fd1 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -89,7 +89,7 @@ static int open_rio(struct inode *inode, struct file *file) mutex_unlock(&(rio->lock)); - info("Rio opened."); + dev_info(&rio->rio_dev->dev, "Rio opened.\n"); return 0; } @@ -100,7 +100,7 @@ static int close_rio(struct inode *inode, struct file *file) rio->isopen = 0; - info("Rio closed."); + dev_info(&rio->rio_dev->dev, "Rio closed.\n"); return 0; } @@ -451,7 +451,7 @@ static int probe_rio(struct usb_interface *intf, struct rio_usb_data *rio = &rio_instance; int retval; - info("USB Rio found at address %d", dev->devnum); + dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum); retval = usb_register_dev(intf, &usb_rio_class); if (retval) { @@ -503,7 +503,7 @@ static void disconnect_rio(struct usb_interface *intf) kfree(rio->ibuf); kfree(rio->obuf); - info("USB Rio disconnected."); + dev_info(&intf->dev, "USB Rio disconnected.\n"); rio->present = 0; mutex_unlock(&(rio->lock)); @@ -531,7 +531,8 @@ static int __init usb_rio_init(void) if (retval) goto out; - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); out: return retval; diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 03368edf3f22..2e14102955c5 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -144,7 +144,8 @@ static int __init tv_init(void) return retval; } - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; } diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index d589324bb0d0..e0ff9ccd866b 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -359,12 +359,13 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id i = le16_to_cpu(dev->udev->descriptor.bcdDevice); - info("USBLCD Version %1d%1d.%1d%1d found at address %d", - (i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF), - dev->udev->devnum); + dev_info(&interface->dev, "USBLCD Version %1d%1d.%1d%1d found " + "at address %d\n", (i & 0xF000)>>12, (i & 0xF00)>>8, + (i & 0xF0)>>4,(i & 0xF), dev->udev->devnum); /* let the user know what node this device is now attached to */ - info("USB LCD device now attached to USBLCD-%d", interface->minor); + dev_info(&interface->dev, "USB LCD device now attached to USBLCD-%d\n", + interface->minor); return 0; error: @@ -413,7 +414,7 @@ static void lcd_disconnect(struct usb_interface *interface) /* decrement our usage count */ kref_put(&dev->kref, lcd_delete); - info("USB LCD #%d now disconnected", minor); + dev_info(&interface->dev, "USB LCD #%d now disconnected\n", minor); } static struct usb_driver lcd_driver = { diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 594f3e4e8c2e..9a6c27a01793 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -801,10 +801,14 @@ static int __init uss720_init(void) if (retval) goto out; - info(DRIVER_VERSION ":" DRIVER_DESC); - info("NOTE: this is a special purpose driver to allow nonstandard"); - info("protocols (eg. bitbang) over USS720 usb to parallel cables"); - info("If you just want to connect to a printer, use usblp instead"); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); + printk(KERN_INFO KBUILD_MODNAME ": NOTE: this is a special purpose " + "driver to allow nonstandard\n"); + printk(KERN_INFO KBUILD_MODNAME ": protocols (eg. bitbang) over " + "USS720 usb to parallel cables\n"); + printk(KERN_INFO KBUILD_MODNAME ": If you just want to connect to a " + "printer, use usblp instead\n"); out: return retval; } -- cgit v1.2.3 From 5909f6ea2bc7f785ceb1bed14c670946a536ff2d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 18 Aug 2008 13:21:04 -0700 Subject: USB: remove info() macro from remaining usb drivers USB should not be having it's own printk macros, so remove info() and use the system-wide standard of dev_info() wherever possible. In the few places that will not work out, use a basic printk(). Clean up the remaining usages of this in the drivers/usb/ directory. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 3 ++- drivers/usb/host/r8a66597-hcd.c | 13 ++++++++----- drivers/usb/image/mdc800.c | 7 ++++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index c257453fa9de..d9c2b8dafd67 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1454,7 +1454,8 @@ static int __init acm_init(void) return retval; } - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; } diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 3a45ad275b41..2a9bec264ad3 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -760,10 +760,12 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597, if ((r8a66597->dma_map & (1 << i)) != 0) continue; - info("address %d, EndpointAddress 0x%02x use DMA FIFO", - usb_pipedevice(urb->pipe), - info->dir_in ? USB_ENDPOINT_DIR_MASK + info->epnum - : info->epnum); + dev_info(&dev->udev->dev, + "address %d, EndpointAddress 0x%02x use " + "DMA FIFO\n", usb_pipedevice(urb->pipe), + info->dir_in ? + USB_ENDPOINT_DIR_MASK + info->epnum + : info->epnum); r8a66597->dma_map |= 1 << i; dev->dma_map |= 1 << i; @@ -2387,7 +2389,8 @@ static int __init r8a66597_init(void) if (usb_disabled()) return -ENODEV; - info("driver %s, %s", hcd_name, DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": driver %s, %s\n", hcd_name, + DRIVER_VERSION); return platform_driver_register(&r8a66597_driver); } module_init(r8a66597_init); diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 228552beb534..dd432c8feaf8 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -489,7 +489,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, } - info ("Found Mustek MDC800 on USB."); + dev_info(&intf->dev, "Found Mustek MDC800 on USB.\n"); mutex_lock(&mdc800->io_lock); @@ -571,7 +571,7 @@ static void mdc800_usb_disconnect (struct usb_interface *intf) mdc800->dev = NULL; usb_set_intfdata(intf, NULL); } - info ("Mustek MDC800 disconnected from USB."); + dev_info(&intf->dev, "Mustek MDC800 disconnected from USB.\n"); } @@ -1020,7 +1020,8 @@ static int __init usb_mdc800_init (void) if (retval) goto cleanup_on_fail; - info (DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; -- cgit v1.2.3 From 880c9c66a60c0aa4fb4dac2da9679da5f8f41903 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 18 Aug 2008 13:21:04 -0700 Subject: USB: remove info() macro from usb network drivers USB should not be having it's own printk macros, so remove info() and use the system-wide standard of dev_info() wherever possible. Cc: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- drivers/net/irda/kingsun-sir.c | 3 ++- drivers/net/irda/ks959-sir.c | 3 ++- drivers/net/irda/ksdazzle-sir.c | 3 ++- drivers/net/irda/stir4200.c | 8 +++++--- drivers/net/usb/catc.c | 3 ++- drivers/net/usb/kaweth.c | 19 ++++++++++--------- drivers/net/usb/rtl8150.c | 15 +++++++++------ 7 files changed, 32 insertions(+), 22 deletions(-) diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c index 73fe83be34fe..e1429fc6d050 100644 --- a/drivers/net/irda/kingsun-sir.c +++ b/drivers/net/irda/kingsun-sir.c @@ -540,7 +540,8 @@ static int kingsun_probe(struct usb_interface *intf, if (ret != 0) goto free_mem; - info("IrDA: Registered KingSun/DonShine device %s", net->name); + dev_info(&net->dev, "IrDA: Registered KingSun/DonShine device %s\n", + net->name); usb_set_intfdata(intf, kingsun); diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c index 8c257a51341a..2482d61662a2 100644 --- a/drivers/net/irda/ks959-sir.c +++ b/drivers/net/irda/ks959-sir.c @@ -801,7 +801,8 @@ static int ks959_probe(struct usb_interface *intf, if (ret != 0) goto free_mem; - info("IrDA: Registered KingSun KS-959 device %s", net->name); + dev_info(&net->dev, "IrDA: Registered KingSun KS-959 device %s\n", + net->name); usb_set_intfdata(intf, kingsun); diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c index d01a28593ce2..1e0de93fd618 100644 --- a/drivers/net/irda/ksdazzle-sir.c +++ b/drivers/net/irda/ksdazzle-sir.c @@ -705,7 +705,8 @@ static int ksdazzle_probe(struct usb_interface *intf, if (ret != 0) goto free_mem; - info("IrDA: Registered KingSun/Dazzle device %s", net->name); + dev_info(&net->dev, "IrDA: Registered KingSun/Dazzle device %s\n", + net->name); usb_set_intfdata(intf, kingsun); diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index 148ce2803b00..3575804fd7c6 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -783,8 +783,9 @@ static int stir_transmit_thread(void *arg) if (unlikely(receive_start(stir))) { if (net_ratelimit()) - info("%s: receive usb submit failed", - stir->netdev->name); + dev_info(&dev->dev, + "%s: receive usb submit failed\n", + stir->netdev->name); stir->receiving = 0; msleep(10); continue; @@ -1073,7 +1074,8 @@ static int stir_probe(struct usb_interface *intf, if (ret != 0) goto err_out2; - info("IrDA: Registered SigmaTel device %s", net->name); + dev_info(&intf->dev, "IrDA: Registered SigmaTel device %s\n", + net->name); usb_set_intfdata(intf, stir); diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 92ff9c83d9f2..466a89e24444 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -954,7 +954,8 @@ static int __init catc_init(void) { int result = usb_register(&catc_driver); if (result == 0) - info(DRIVER_VERSION " " DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return result; } diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 4f7a0106781e..fdbf3be24fda 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -1016,10 +1016,10 @@ static int kaweth_probe( */ if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) { - info("Firmware present in device."); + dev_info(&intf->dev, "Firmware present in device.\n"); } else { /* Download the firmware */ - info("Downloading firmware..."); + dev_info(&intf->dev, "Downloading firmware...\n"); kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL); if ((result = kaweth_download_firmware(kaweth, "kaweth/new_code.bin", @@ -1061,7 +1061,7 @@ static int kaweth_probe( } /* Device will now disappear for a moment... */ - info("Firmware loaded. I'll be back..."); + dev_info(&intf->dev, "Firmware loaded. I'll be back...\n"); err_fw: free_page((unsigned long)kaweth->firmware_buf); free_netdev(netdev); @@ -1075,10 +1075,10 @@ err_fw: goto err_free_netdev; } - info("Statistics collection: %x", kaweth->configuration.statistics_mask); - info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1)); - info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size)); - info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", + dev_info(&intf->dev, "Statistics collection: %x\n", kaweth->configuration.statistics_mask); + dev_info(&intf->dev, "Multicast filter limit: %x\n", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1)); + dev_info(&intf->dev, "MTU: %d\n", le16_to_cpu(kaweth->configuration.segment_size)); + dev_info(&intf->dev, "Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", (int)kaweth->configuration.hw_addr[0], (int)kaweth->configuration.hw_addr[1], (int)kaweth->configuration.hw_addr[2], @@ -1174,7 +1174,8 @@ err_fw: goto err_intfdata; } - info("kaweth interface created at %s", kaweth->net->name); + dev_info(&intf->dev, "kaweth interface created at %s\n", + kaweth->net->name); dbg("Kaweth probe returning."); @@ -1205,7 +1206,7 @@ static void kaweth_disconnect(struct usb_interface *intf) struct kaweth_device *kaweth = usb_get_intfdata(intf); struct net_device *netdev; - info("Unregistering"); + dev_info(&intf->dev, "Unregistering\n"); usb_set_intfdata(intf, NULL); if (!kaweth) { diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 7726b5e86764..6133401ebc67 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -538,7 +538,8 @@ static void write_bulk_callback(struct urb *urb) if (!netif_device_present(dev->netdev)) return; if (urb->status) - info("%s: Tx status %d", dev->netdev->name, urb->status); + dev_info(&urb->dev->dev, "%s: Tx status %d\n", + dev->netdev->name, urb->status); dev->netdev->trans_start = jiffies; netif_wake_queue(dev->netdev); } @@ -561,7 +562,8 @@ static void intr_callback(struct urb *urb) return; /* -EPIPE: should clear the halt */ default: - info("%s: intr status %d", dev->netdev->name, urb->status); + dev_info(&urb->dev->dev, "%s: intr status %d\n", + dev->netdev->name, urb->status); goto resubmit; } @@ -710,12 +712,12 @@ static void rtl8150_set_multicast(struct net_device *netdev) netif_stop_queue(netdev); if (netdev->flags & IFF_PROMISC) { dev->rx_creg |= cpu_to_le16(0x0001); - info("%s: promiscuous mode", netdev->name); + dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name); } else if (netdev->mc_count || (netdev->flags & IFF_ALLMULTI)) { dev->rx_creg &= cpu_to_le16(0xfffe); dev->rx_creg |= cpu_to_le16(0x0002); - info("%s: allmulti set", netdev->name); + dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name); } else { /* ~RX_MULTICAST, ~RX_PROMISCUOUS */ dev->rx_creg &= cpu_to_le16(0x00fc); @@ -947,7 +949,7 @@ static int rtl8150_probe(struct usb_interface *intf, goto out2; } - info("%s: rtl8150 is detected", netdev->name); + dev_info(&intf->dev, "%s: rtl8150 is detected\n", netdev->name); return 0; @@ -984,7 +986,8 @@ static void rtl8150_disconnect(struct usb_interface *intf) static int __init usb_rtl8150_init(void) { - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return usb_register(&rtl8150_driver); } -- cgit v1.2.3 From 899ef6e7cf2f057fcfd8071b36de04117313242b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 18 Aug 2008 13:21:04 -0700 Subject: USB: remove info() macro from usb input drivers USB should not be having it's own printk macros, so remove info() and use the system-wide standard of dev_info() wherever possible. Acked-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/joystick/xpad.c | 2 +- drivers/input/misc/ati_remote.c | 6 ++++-- drivers/input/misc/yealink.c | 3 ++- drivers/input/tablet/acecad.c | 3 ++- drivers/input/tablet/aiptek.c | 13 ++++++++----- drivers/input/tablet/gtco.c | 4 ++-- drivers/input/tablet/kbtab.c | 3 ++- drivers/input/tablet/wacom_sys.c | 3 ++- 8 files changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 839d1c9622f6..b868b8d5fbb3 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -911,7 +911,7 @@ static int __init usb_xpad_init(void) { int result = usb_register(&xpad_driver); if (result == 0) - info(DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); return result; } diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c index 428ecd3294a3..e290fde35e74 100644 --- a/drivers/input/misc/ati_remote.c +++ b/drivers/input/misc/ati_remote.c @@ -834,9 +834,11 @@ static int __init ati_remote_init(void) result = usb_register(&ati_remote_driver); if (result) - err("usb_register error #%d\n", result); + printk(KERN_ERR KBUILD_MODNAME + ": usb_register error #%d\n", result); else - info("Registered USB driver " DRIVER_DESC " v. " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return result; } diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c index 11b5c7e84ed1..93a22ac0f88c 100644 --- a/drivers/input/misc/yealink.c +++ b/drivers/input/misc/yealink.c @@ -999,7 +999,8 @@ static int __init yealink_dev_init(void) { int ret = usb_register(&yealink_driver); if (ret == 0) - info(DRIVER_DESC ":" DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return ret; } diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index 570e0e83ac46..670c61c5a516 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c @@ -280,7 +280,8 @@ static int __init usb_acecad_init(void) { int result = usb_register(&usb_acecad_driver); if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return result; } diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 1aa82e8af614..7d005a3616d7 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -1844,8 +1844,9 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) aiptek->curSetting.programmableDelay = speeds[i]; (void)aiptek_program_tablet(aiptek); if (aiptek->inputdev->absmax[ABS_X] > 0) { - info("input: Aiptek using %d ms programming speed\n", - aiptek->curSetting.programmableDelay); + dev_info(&intf->dev, + "Aiptek using %d ms programming speed\n", + aiptek->curSetting.programmableDelay); break; } } @@ -1853,7 +1854,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Murphy says that some day someone will have a tablet that fails the above test. That's you, Frederic Rodrigo */ if (i == ARRAY_SIZE(speeds)) { - info("input: Aiptek tried all speeds, no sane response"); + dev_info(&intf->dev, + "Aiptek tried all speeds, no sane response\n"); goto fail2; } @@ -1925,8 +1927,9 @@ static int __init aiptek_init(void) { int result = usb_register(&aiptek_driver); if (result == 0) { - info(DRIVER_VERSION ": " DRIVER_AUTHOR); - info(DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_AUTHOR "\n"); } return result; } diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c index 7df0228e836e..5524e01dbb1a 100644 --- a/drivers/input/tablet/gtco.c +++ b/drivers/input/tablet/gtco.c @@ -2,7 +2,7 @@ GTCO digitizer USB driver -Use the err(), dbg() and info() macros from usb.h for system logging +Use the err() and dbg() macros from usb.h for system logging TO CHECK: Is pressure done right on report 5? @@ -1010,7 +1010,7 @@ static void gtco_disconnect(struct usb_interface *interface) kfree(gtco); } - info("gtco driver disconnected"); + dev_info(&interface->dev, "gtco driver disconnected\n"); } /* STANDARD MODULE LOAD ROUTINES */ diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c index d89112fa6e6b..6682b17bf844 100644 --- a/drivers/input/tablet/kbtab.c +++ b/drivers/input/tablet/kbtab.c @@ -215,7 +215,8 @@ static int __init kbtab_init(void) retval = usb_register(&kbtab_driver); if (retval) goto out; - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); out: return retval; } diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 5fbc463baf5a..09e227aa0d49 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -385,7 +385,8 @@ static int __init wacom_init(void) wacom_driver.id_table = get_device_table(); result = usb_register(&wacom_driver); if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return result; } -- cgit v1.2.3 From b887265c165f94917d0f565b1883a6e7b3c8388c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 18 Aug 2008 13:21:04 -0700 Subject: USB: remove info() macro from usb mtd drivers USB should not be having it's own printk macros, so remove info() and use the system-wide standard of dev_info() wherever possible. Acked-by: David Woodhouse Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/alauda.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/alauda.c b/drivers/mtd/nand/alauda.c index 257937cd99bf..962380394855 100644 --- a/drivers/mtd/nand/alauda.c +++ b/drivers/mtd/nand/alauda.c @@ -691,7 +691,7 @@ static int alauda_probe(struct usb_interface *interface, al[0].port = ALAUDA_PORT_XD; al[1].port = ALAUDA_PORT_SM; - info("alauda probed"); + dev_info(&interface->dev, "alauda probed\n"); alauda_check_media(al); alauda_check_media(al+1); @@ -716,7 +716,7 @@ static void alauda_disconnect(struct usb_interface *interface) if (al) kref_put(&al->kref, alauda_delete); - info("alauda gone"); + dev_info(&interface->dev, "alauda gone"); } static struct usb_driver alauda_driver = { -- cgit v1.2.3 From 194343d9364ea07c9f27c4505380a15a905e8a24 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 Aug 2008 16:56:34 -0700 Subject: USB: remove use of err() in drivers/usb/serial err() is going away, so switch to dev_err() or printk() if it's really needed. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/aircable.c | 8 +-- drivers/usb/serial/belkin_sa.c | 34 +++++------ drivers/usb/serial/cyberjack.c | 23 ++++--- drivers/usb/serial/cypress_m8.c | 18 +++--- drivers/usb/serial/digi_acceleport.c | 65 ++++++++++++-------- drivers/usb/serial/empeg.c | 8 +-- drivers/usb/serial/ezusb.c | 3 +- drivers/usb/serial/ftdi_sio.c | 68 ++++++++++++--------- drivers/usb/serial/io_edgeport.c | 16 ++--- drivers/usb/serial/ipaq.c | 27 +++++---- drivers/usb/serial/keyspan_pda.c | 14 +++-- drivers/usb/serial/kl5kusb105.c | 46 ++++++++------ drivers/usb/serial/mct_u232.c | 39 +++++++----- drivers/usb/serial/mos7720.c | 19 +++--- drivers/usb/serial/mos7840.c | 26 ++++---- drivers/usb/serial/omninet.c | 19 +++--- drivers/usb/serial/safe_serial.c | 15 +++-- drivers/usb/serial/spcp8x5.c | 7 ++- drivers/usb/serial/usb-serial.c | 19 +++--- drivers/usb/serial/visor.c | 2 +- drivers/usb/serial/whiteheat.c | 113 +++++++++++++++++++++-------------- 21 files changed, 346 insertions(+), 243 deletions(-) diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 99fb7dc59c45..537f953bd7f8 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c @@ -220,8 +220,8 @@ static void aircable_send(struct usb_serial_port *port) buf = kzalloc(count + HCI_HEADER_LENGTH, GFP_ATOMIC); if (!buf) { - err("%s- kzalloc(%d) failed.", __func__, - count + HCI_HEADER_LENGTH); + dev_err(&port->dev, "%s- kzalloc(%d) failed.\n", + __func__, count + HCI_HEADER_LENGTH); return; } @@ -276,7 +276,7 @@ static void aircable_read(struct work_struct *work) if (!tty) { schedule_work(&priv->rx_work); - err("%s - No tty available", __func__); + dev_err(&port->dev, "%s - No tty available\n", __func__); return ; } @@ -336,7 +336,7 @@ static int aircable_attach(struct usb_serial *serial) priv = kzalloc(sizeof(struct aircable_private), GFP_KERNEL); if (!priv) { - err("%s- kmalloc(%Zd) failed.", __func__, + dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__, sizeof(struct aircable_private)); return -ENOMEM; } diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index bb19f1c2e0d3..b7eacad4d48c 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -228,7 +228,7 @@ static int belkin_sa_open(struct tty_struct *tty, port->read_urb->dev = port->serial->dev; retval = usb_submit_urb(port->read_urb, GFP_KERNEL); if (retval) { - err("usb_submit_urb(read bulk) failed"); + dev_err(&port->dev, "usb_submit_urb(read bulk) failed\n"); goto exit; } @@ -236,7 +236,7 @@ static int belkin_sa_open(struct tty_struct *tty, retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (retval) { usb_kill_urb(port->read_urb); - err(" usb_submit_urb(read int) failed"); + dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); } exit: @@ -342,8 +342,8 @@ static void belkin_sa_read_int_callback(struct urb *urb) exit: retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) - err("%s - usb_submit_urb failed with result %d", - __func__, retval); + dev_err(&port->dev, "%s - usb_submit_urb failed with " + "result %d\n", __func__, retval); } static void belkin_sa_set_termios(struct tty_struct *tty, @@ -382,12 +382,12 @@ static void belkin_sa_set_termios(struct tty_struct *tty, if ((old_cflag & CBAUD) == B0) { control_state |= (TIOCM_DTR|TIOCM_RTS); if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0) - err("Set DTR error"); + dev_err(&port->dev, "Set DTR error\n"); /* don't set RTS if using hardware flow control */ if (!(old_cflag & CRTSCTS)) if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST , 1) < 0) - err("Set RTS error"); + dev_err(&port->dev, "Set RTS error\n"); } } @@ -403,18 +403,18 @@ static void belkin_sa_set_termios(struct tty_struct *tty, /* Report the actual baud rate back to the caller */ tty_encode_baud_rate(tty, baud, baud); if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0) - err("Set baudrate error"); + dev_err(&port->dev, "Set baudrate error\n"); } else { /* Disable flow control */ if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, BELKIN_SA_FLOW_NONE) < 0) - err("Disable flowcontrol error"); + dev_err(&port->dev, "Disable flowcontrol error\n"); /* Drop RTS and DTR */ control_state &= ~(TIOCM_DTR | TIOCM_RTS); if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0) - err("DTR LOW error"); + dev_err(&port->dev, "DTR LOW error\n"); if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0) - err("RTS LOW error"); + dev_err(&port->dev, "RTS LOW error\n"); } /* set the parity */ @@ -425,7 +425,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty, else urb_value = BELKIN_SA_PARITY_NONE; if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0) - err("Set parity error"); + dev_err(&port->dev, "Set parity error\n"); } /* set the number of data bits */ @@ -448,7 +448,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty, break; } if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0) - err("Set data bits error"); + dev_err(&port->dev, "Set data bits error\n"); } /* set the number of stop bits */ @@ -457,7 +457,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty, : BELKIN_SA_STOP_BITS(1); if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST, urb_value) < 0) - err("Set stop bits error"); + dev_err(&port->dev, "Set stop bits error\n"); } /* Set flow control */ @@ -478,7 +478,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty, urb_value &= ~(BELKIN_SA_FLOW_IRTS); if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, urb_value) < 0) - err("Set flow control error"); + dev_err(&port->dev, "Set flow control error\n"); } /* save off the modified port settings */ @@ -494,7 +494,7 @@ static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state) struct usb_serial *serial = port->serial; if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0) - err("Set break_ctl %d", break_state); + dev_err(&port->dev, "Set break_ctl %d\n", break_state); } @@ -554,13 +554,13 @@ static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file, retval = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, rts); if (retval < 0) { - err("Set RTS error %d", retval); + dev_err(&port->dev, "Set RTS error %d\n", retval); goto exit; } retval = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, dtr); if (retval < 0) { - err("Set DTR error %d", retval); + dev_err(&port->dev, "Set DTR error %d\n", retval); goto exit; } exit: diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 068680f9929d..858bdd038fbc 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -141,7 +141,8 @@ static int cyberjack_startup(struct usb_serial *serial) result = usb_submit_urb(serial->port[i]->interrupt_in_urb, GFP_KERNEL); if (result) - err(" usb_submit_urb(read int) failed"); + dev_err(&serial->dev->dev, + "usb_submit_urb(read int) failed\n"); dbg("%s - usb_submit_urb(int urb)", __func__); } @@ -274,8 +275,9 @@ static int cyberjack_write(struct tty_struct *tty, /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - err("%s - failed submitting write urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed submitting write urb, error %d", + __func__, result); /* Throw away data. No better idea what to do with it. */ priv->wrfilled = 0; priv->wrsent = 0; @@ -351,7 +353,9 @@ static void cyberjack_read_int_callback(struct urb *urb) port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", __func__, result); + dev_err(&port->dev, "%s - failed resubmitting " + "read urb, error %d\n", + __func__, result); dbg("%s - usb_submit_urb(read urb)", __func__); } } @@ -360,7 +364,7 @@ resubmit: port->interrupt_in_urb->dev = port->serial->dev; result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result) - err(" usb_submit_urb(read int) failed"); + dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); dbg("%s - usb_submit_urb(int urb)", __func__); } @@ -414,8 +418,8 @@ static void cyberjack_read_bulk_callback(struct urb *urb) port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", - __func__, result); + dev_err(&port->dev, "%s - failed resubmitting read " + "urb, error %d\n", __func__, result); dbg("%s - usb_submit_urb(read urb)", __func__); } } @@ -462,8 +466,9 @@ static void cyberjack_write_bulk_callback(struct urb *urb) /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - err("%s - failed submitting write urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed submitting write urb, error %d\n", + __func__, result); /* Throw away data. No better idea what to do with it. */ priv->wrfilled = 0; priv->wrsent = 0; diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index e0ca809f75f5..eae4740d448c 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -404,8 +404,8 @@ static int cypress_serial_control(struct tty_struct *tty, retval != -ENODEV); if (retval != sizeof(feature_buffer)) { - err("%s - failed sending serial line settings - %d", - __func__, retval); + dev_err(&port->dev, "%s - failed sending serial " + "line settings - %d\n", __func__, retval); cypress_set_dead(port); } else { spin_lock_irqsave(&priv->lock, flags); @@ -443,7 +443,8 @@ static int cypress_serial_control(struct tty_struct *tty, && retval != -ENODEV); if (retval != sizeof(feature_buffer)) { - err("%s - failed to retrieve serial line settings - %d", __func__, retval); + dev_err(&port->dev, "%s - failed to retrieve serial " + "line settings - %d\n", __func__, retval); cypress_set_dead(port); return retval; } else { @@ -476,8 +477,8 @@ static void cypress_set_dead(struct usb_serial_port *port) priv->comm_is_ok = 0; spin_unlock_irqrestore(&priv->lock, flags); - err("cypress_m8 suspending failing port %d - interval might be too short", - port->number); + dev_err(&port->dev, "cypress_m8 suspending failing port %d - " + "interval might be too short\n", port->number); } @@ -679,7 +680,8 @@ static int cypress_open(struct tty_struct *tty, /* setup the port and start reading from the device */ if (!port->interrupt_in_urb) { - err("%s - interrupt_in_urb is empty!", __func__); + dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n", + __func__); return -1; } @@ -1107,8 +1109,8 @@ static void cypress_set_termios(struct tty_struct *tty, data_bits = 3; break; default: - err("%s - CSIZE was set, but not CS5-CS8", - __func__); + dev_err(&port->dev, "%s - CSIZE was set, but not CS5-CS8\n", + __func__); data_bits = 3; } spin_lock_irqsave(&priv->lock, flags); diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index ebc2918719a0..69f84f0ea6fe 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -661,7 +661,8 @@ static int digi_write_oob_command(struct usb_serial_port *port, } spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); if (ret) - err("%s: usb_submit_urb failed, ret=%d", __func__, ret); + dev_err(&port->dev, "%s: usb_submit_urb failed, ret=%d\n", + __func__, ret); return ret; } @@ -743,7 +744,8 @@ static int digi_write_inb_command(struct usb_serial_port *port, spin_unlock_irqrestore(&priv->dp_port_lock, flags); if (ret) - err("%s: usb_submit_urb failed, ret=%d, port=%d", + dev_err(&port->dev, + "%s: usb_submit_urb failed, ret=%d, port=%d\n", __func__, ret, priv->dp_port_num); return ret; } @@ -812,7 +814,8 @@ static int digi_set_modem_signals(struct usb_serial_port *port, spin_unlock(&port_priv->dp_port_lock); spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); if (ret) - err("%s: usb_submit_urb failed, ret=%d", __func__, ret); + dev_err(&port->dev, "%s: usb_submit_urb failed, ret=%d\n", + __func__, ret); return ret; } @@ -907,7 +910,8 @@ static void digi_rx_unthrottle(struct tty_struct *tty) spin_unlock_irqrestore(&priv->dp_port_lock, flags); if (ret) - err("%s: usb_submit_urb failed, ret=%d, port=%d", + dev_err(&port->dev, + "%s: usb_submit_urb failed, ret=%d, port=%d\n", __func__, ret, priv->dp_port_num); } @@ -1214,7 +1218,8 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port, /* return length of new data written, or error */ spin_unlock_irqrestore(&priv->dp_port_lock, flags); if (ret < 0) - err("%s: usb_submit_urb failed, ret=%d, port=%d", + dev_err(&port->dev, + "%s: usb_submit_urb failed, ret=%d, port=%d\n", __func__, ret, priv->dp_port_num); dbg("digi_write: returning %d", ret); return ret; @@ -1235,14 +1240,16 @@ static void digi_write_bulk_callback(struct urb *urb) /* port and serial sanity check */ if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { - err("%s: port or port->private is NULL, status=%d", - __func__, status); + dev_err(&port->dev, + "%s: port or port->private is NULL, status=%d\n", + __func__, status); return; } serial = port->serial; if (serial == NULL || (serial_priv = usb_get_serial_data(serial)) == NULL) { - err("%s: serial or serial->private is NULL, status=%d", - __func__, status); + dev_err(&port->dev, + "%s: serial or serial->private is NULL, status=%d\n", + __func__, status); return; } @@ -1284,7 +1291,8 @@ static void digi_write_bulk_callback(struct urb *urb) spin_unlock(&priv->dp_port_lock); if (ret) - err("%s: usb_submit_urb failed, ret=%d, port=%d", + dev_err(&port->dev, + "%s: usb_submit_urb failed, ret=%d, port=%d\n", __func__, ret, priv->dp_port_num); } @@ -1518,8 +1526,9 @@ static int digi_startup_device(struct usb_serial *serial) port->write_urb->dev = port->serial->dev; ret = usb_submit_urb(port->read_urb, GFP_KERNEL); if (ret != 0) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", - __func__, ret, i); + dev_err(&port->dev, + "%s: usb_submit_urb failed, ret=%d, port=%d\n", + __func__, ret, i); break; } } @@ -1618,22 +1627,26 @@ static void digi_read_bulk_callback(struct urb *urb) dbg("digi_read_bulk_callback: TOP"); /* port sanity check, do not resubmit if port is not valid */ - if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { - err("%s: port or port->private is NULL, status=%d", - __func__, status); + if (port == NULL) + return; + priv = usb_get_serial_port_data(port); + if (priv == NULL) { + dev_err(&port->dev, "%s: port->private is NULL, status=%d\n", + __func__, status); return; } if (port->serial == NULL || (serial_priv = usb_get_serial_data(port->serial)) == NULL) { - err("%s: serial is bad or serial->private is NULL, status=%d", - __func__, status); + dev_err(&port->dev, "%s: serial is bad or serial->private " + "is NULL, status=%d\n", __func__, status); return; } /* do not resubmit urb if it has any status error */ if (status) { - err("%s: nonzero read bulk status: status=%d, port=%d", - __func__, status, priv->dp_port_num); + dev_err(&port->dev, + "%s: nonzero read bulk status: status=%d, port=%d\n", + __func__, status, priv->dp_port_num); return; } @@ -1650,8 +1663,9 @@ static void digi_read_bulk_callback(struct urb *urb) urb->dev = port->serial->dev; ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret != 0) { - err("%s: failed resubmitting urb, ret=%d, port=%d", - __func__, ret, priv->dp_port_num); + dev_err(&port->dev, + "%s: failed resubmitting urb, ret=%d, port=%d\n", + __func__, ret, priv->dp_port_num); } } @@ -1687,10 +1701,11 @@ static int digi_read_inb_callback(struct urb *urb) /* short/multiple packet check */ if (urb->actual_length != len + 2) { - err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, " - "port=%d, opcode=%d, len=%d, actual_length=%d, " - "status=%d", __func__, status, priv->dp_port_num, - opcode, len, urb->actual_length, port_status); + dev_err(&port->dev, "%s: INCOMPLETE OR MULTIPLE PACKET, " + "urb->status=%d, port=%d, opcode=%d, len=%d, " + "actual_length=%d, status=%d\n", __func__, status, + priv->dp_port_num, opcode, len, urb->actual_length, + port_status); return -1; } diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index fdd28e940bc1..8a69cce40b6d 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -416,7 +416,7 @@ static int empeg_startup(struct usb_serial *serial) dbg("%s", __func__); if (serial->dev->actconfig->desc.bConfigurationValue != 1) { - err("active config #%d != 1 ??", + dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", serial->dev->actconfig->desc.bConfigurationValue); return -ENODEV; } @@ -499,15 +499,15 @@ static int __init empeg_init(void) urb = usb_alloc_urb(0, GFP_KERNEL); write_urb_pool[i] = urb; if (urb == NULL) { - err("No more urbs???"); + printk(KERN_ERR "empeg: No more urbs???\n"); continue; } urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (!urb->transfer_buffer) { - err("%s - out of memory for urb buffers.", - __func__); + printk(KERN_ERR "empeg: %s - out of memory for urb " + "buffers.", __func__); continue; } } diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c index 711e84f6ed82..3cfc762f5056 100644 --- a/drivers/usb/serial/ezusb.c +++ b/drivers/usb/serial/ezusb.c @@ -28,7 +28,8 @@ int ezusb_writememory(struct usb_serial *serial, int address, /* dbg("ezusb_writememory %x, %d", address, length); */ if (!serial->dev) { - err("%s - no physical device present, failing.", __func__); + printk(KERN_ERR "ezusb: %s - no physical device present, " + "failing.\n", __func__); return -ENODEV; } diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index bcadb1f4f5dd..51d7bdea2869 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1327,7 +1327,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); if (!priv) { - err("%s- kmalloc(%Zd) failed.", __func__, + dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__, sizeof(struct ftdi_private)); return -ENOMEM; } @@ -1524,8 +1524,9 @@ static int ftdi_open(struct tty_struct *tty, ftdi_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) - err("%s - failed submitting read urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed submitting read urb, error %d\n", + __func__, result); return result; @@ -1559,7 +1560,7 @@ static void ftdi_close(struct tty_struct *tty, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 0, priv->interface, buf, 0, WDR_TIMEOUT) < 0) { - err("error from flowcontrol urb"); + dev_err(&port->dev, "error from flowcontrol urb\n"); } /* drop RTS and DTR */ @@ -1624,14 +1625,15 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, buffer = kmalloc(transfer_size, GFP_ATOMIC); if (!buffer) { - err("%s ran out of kernel memory for urb ...", __func__); + dev_err(&port->dev, + "%s ran out of kernel memory for urb ...\n", __func__); count = -ENOMEM; goto error_no_buffer; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { - err("%s - no more free urbs", __func__); + dev_err(&port->dev, "%s - no more free urbs\n", __func__); count = -ENOMEM; goto error_no_urb; } @@ -1675,8 +1677,9 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { - err("%s - failed submitting write urb, error %d", - __func__, status); + dev_err(&port->dev, + "%s - failed submitting write urb, error %d\n", + __func__, status); count = status; goto error; } else { @@ -1783,7 +1786,8 @@ static int ftdi_chars_in_buffer(struct tty_struct *tty) buffered = (int)priv->tx_outstanding_bytes; spin_unlock_irqrestore(&priv->tx_lock, flags); if (buffered < 0) { - err("%s outstanding tx bytes is negative!", __func__); + dev_err(&port->dev, "%s outstanding tx bytes is negative!\n", + __func__); buffered = 0; } return buffered; @@ -1799,11 +1803,12 @@ static void ftdi_read_bulk_callback(struct urb *urb) int status = urb->status; if (urb->number_of_packets > 0) { - err("%s transfer_buffer_length %d actual_length %d number of packets %d", - __func__, - urb->transfer_buffer_length, - urb->actual_length, urb->number_of_packets); - err("%s transfer_flags %x ", __func__, urb->transfer_flags); + dev_err(&port->dev, "%s transfer_buffer_length %d " + "actual_length %d number of packets %d\n", __func__, + urb->transfer_buffer_length, + urb->actual_length, urb->number_of_packets); + dev_err(&port->dev, "%s transfer_flags %x\n", __func__, + urb->transfer_flags); } dbg("%s - port %d", __func__, port->number); @@ -1824,7 +1829,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) } if (urb != port->read_urb) - err("%s - Not my urb!", __func__); + dev_err(&port->dev, "%s - Not my urb!\n", __func__); if (status) { /* This will happen at close every time so it is a dbg not an @@ -1927,7 +1932,8 @@ static void ftdi_process_read(struct work_struct *work) length = min(PKTSZ, urb->actual_length-packet_offset)-2; if (length < 0) { - err("%s - bad packet length: %d", __func__, length+2); + dev_err(&port->dev, "%s - bad packet length: %d\n", + __func__, length+2); length = 0; } @@ -2042,8 +2048,9 @@ static void ftdi_process_read(struct work_struct *work) result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed resubmitting read urb, error %d\n", + __func__, result); } out: tty_kref_put(tty); @@ -2072,8 +2079,8 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) FTDI_SIO_SET_DATA_REQUEST_TYPE, urb_value , priv->interface, buf, 0, WDR_TIMEOUT) < 0) { - err("%s FAILED to enable/disable break state (state was %d)", - __func__, break_state); + dev_err(&port->dev, "%s FAILED to enable/disable break state " + "(state was %d)\n", __func__, break_state); } dbg("%s break state is %d - urb is %d", __func__, @@ -2145,7 +2152,7 @@ static void ftdi_set_termios(struct tty_struct *tty, case CS7: urb_value |= 7; dbg("Setting CS7"); break; case CS8: urb_value |= 8; dbg("Setting CS8"); break; default: - err("CSIZE was set but not CS5-CS8"); + dev_err(&port->dev, "CSIZE was set but not CS5-CS8\n"); } } @@ -2158,7 +2165,8 @@ static void ftdi_set_termios(struct tty_struct *tty, FTDI_SIO_SET_DATA_REQUEST_TYPE, urb_value , priv->interface, buf, 0, WDR_SHORT_TIMEOUT) < 0) { - err("%s FAILED to set databits/stopbits/parity", __func__); + dev_err(&port->dev, "%s FAILED to set " + "databits/stopbits/parity\n", __func__); } /* Now do the baudrate */ @@ -2169,14 +2177,17 @@ static void ftdi_set_termios(struct tty_struct *tty, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 0, priv->interface, buf, 0, WDR_TIMEOUT) < 0) { - err("%s error from disable flowcontrol urb", __func__); + dev_err(&port->dev, + "%s error from disable flowcontrol urb\n", + __func__); } /* Drop RTS and DTR */ clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } else { /* set the baudrate determined before */ if (change_speed(tty, port)) - err("%s urb failed to set baudrate", __func__); + dev_err(&port->dev, "%s urb failed to set baudrate\n", + __func__); /* Ensure RTS and DTR are raised when baudrate changed from 0 */ if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) set_mctrl(port, TIOCM_DTR | TIOCM_RTS); @@ -2192,7 +2203,8 @@ static void ftdi_set_termios(struct tty_struct *tty, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), buf, 0, WDR_TIMEOUT) < 0) { - err("urb failed to set to rts/cts flow control"); + dev_err(&port->dev, + "urb failed to set to rts/cts flow control\n"); } } else { @@ -2223,7 +2235,8 @@ static void ftdi_set_termios(struct tty_struct *tty, urb_value , (FTDI_SIO_XON_XOFF_HS | priv->interface), buf, 0, WDR_TIMEOUT) < 0) { - err("urb failed to set to xon/xoff flow control"); + dev_err(&port->dev, "urb failed to set to " + "xon/xoff flow control\n"); } } else { /* else clause to only run if cflag ! CRTSCTS and iflag @@ -2236,7 +2249,8 @@ static void ftdi_set_termios(struct tty_struct *tty, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 0, priv->interface, buf, 0, WDR_TIMEOUT) < 0) { - err("urb failed to clear flow control"); + dev_err(&port->dev, + "urb failed to clear flow control\n"); } } diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index eb95efdfbe8b..e85c8c0d1ad9 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -3109,13 +3109,13 @@ static int edge_startup(struct usb_serial *serial) edge_serial->interrupt_read_urb = usb_alloc_urb(0, GFP_KERNEL); if (!edge_serial->interrupt_read_urb) { - err("out of memory"); + dev_err(&dev->dev, "out of memory\n"); return -ENOMEM; } edge_serial->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!edge_serial->interrupt_in_buffer) { - err("out of memory"); + dev_err(&dev->dev, "out of memory\n"); usb_free_urb(edge_serial->interrupt_read_urb); return -ENOMEM; } @@ -3146,13 +3146,13 @@ static int edge_startup(struct usb_serial *serial) edge_serial->read_urb = usb_alloc_urb(0, GFP_KERNEL); if (!edge_serial->read_urb) { - err("out of memory"); + dev_err(&dev->dev, "out of memory\n"); return -ENOMEM; } edge_serial->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!edge_serial->bulk_in_buffer) { - err("out of memory"); + dev_err(&dev->dev, "out of memory\n"); usb_free_urb(edge_serial->read_urb); return -ENOMEM; } @@ -3181,7 +3181,8 @@ static int edge_startup(struct usb_serial *serial) } if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) { - err("Error - the proper endpoints were not found!"); + dev_err(&dev->dev, "Error - the proper endpoints " + "were not found!\n"); return -ENODEV; } @@ -3190,8 +3191,9 @@ static int edge_startup(struct usb_serial *serial) response = usb_submit_urb(edge_serial->interrupt_read_urb, GFP_KERNEL); if (response) - err("%s - Error %d submitting control urb", - __func__, response); + dev_err(&dev->dev, + "%s - Error %d submitting control urb\n", + __func__, response); } return response; } diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 5108cbc64a55..132be74d2b89 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -608,7 +608,7 @@ static int ipaq_open(struct tty_struct *tty, bytes_out = 0; priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL); if (priv == NULL) { - err("%s - Out of memory", __func__); + dev_err(&port->dev, "%s - Out of memory\n", __func__); return -ENOMEM; } usb_set_serial_port_data(port, priv); @@ -693,8 +693,7 @@ static int ipaq_open(struct tty_struct *tty, } if (!retries && result) { - err("%s - failed doing control urb, error %d", __func__, - result); + dev_err(&port->dev, "%s - failed doing control urb, error %d\n", __func__, result); goto error; } @@ -707,8 +706,9 @@ static int ipaq_open(struct tty_struct *tty, result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) { - err("%s - failed submitting read urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed submitting read urb, error %d\n", + __func__, result); goto error; } @@ -716,7 +716,7 @@ static int ipaq_open(struct tty_struct *tty, enomem: result = -ENOMEM; - err("%s - Out of memory", __func__); + dev_err(&port->dev, "%s - Out of memory\n", __func__); error: ipaq_destroy_lists(port); kfree(priv); @@ -781,8 +781,9 @@ static void ipaq_read_bulk_callback(struct urb *urb) ipaq_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed resubmitting read urb, error %d\n", + __func__, result); return; } @@ -847,7 +848,8 @@ static int ipaq_write_bulk(struct usb_serial_port *port, spin_unlock_irqrestore(&write_list_lock, flags); result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) - err("%s - failed submitting write urb, error %d", + dev_err(&port->dev, + "%s - failed submitting write urb, error %d\n", __func__, result); } else { spin_unlock_irqrestore(&write_list_lock, flags); @@ -909,8 +911,9 @@ static void ipaq_write_bulk_callback(struct urb *urb) spin_unlock_irqrestore(&write_list_lock, flags); result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) - err("%s - failed submitting write urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed submitting write urb, error %d\n", + __func__, result); } else { priv->active = 0; spin_unlock_irqrestore(&write_list_lock, flags); @@ -957,7 +960,7 @@ static int ipaq_startup(struct usb_serial *serial) { dbg("%s", __func__); if (serial->dev->actconfig->desc.bConfigurationValue != 1) { - err("active config #%d != 1 ??", + dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", serial->dev->actconfig->desc.bConfigurationValue); return -ENODEV; } diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 2928ba844394..bf1ae247da66 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -742,11 +742,13 @@ static int keyspan_pda_fake_startup(struct usb_serial *serial) fw_name = "keyspan_pda/xircom_pgs.fw"; #endif else { - err("%s: unknown vendor, aborting.", __func__); + dev_err(&serial->dev->dev, "%s: unknown vendor, aborting.\n", + __func__); return -ENODEV; } if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) { - err("failed to load firmware \"%s\"\n", fw_name); + dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n", + fw_name); return -ENOENT; } record = (const struct ihex_binrec *)fw->data; @@ -756,10 +758,10 @@ static int keyspan_pda_fake_startup(struct usb_serial *serial) (unsigned char *)record->data, be16_to_cpu(record->len), 0xa0); if (response < 0) { - err("ezusb_writememory failed for Keyspan PDA " - "firmware (%d %04X %p %d)", - response, be32_to_cpu(record->addr), - record->data, be16_to_cpu(record->len)); + dev_err(&serial->dev->dev, "ezusb_writememory failed " + "for Keyspan PDA firmware (%d %04X %p %d)\n", + response, be32_to_cpu(record->addr), + record->data, be16_to_cpu(record->len)); break; } record = ihex_next_binrec(record); diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 573c6972fae7..dc36a052766f 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -182,7 +182,8 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port, sizeof(struct klsi_105_port_settings), KLSI_TIMEOUT); if (rc < 0) - err("Change port settings failed (error = %d)", rc); + dev_err(&port->dev, + "Change port settings failed (error = %d)\n", rc); dev_info(&port->serial->dev->dev, "%d byte block, baudrate %x, databits %d, u1 %d, u2 %d\n", settings->pktlen, settings->baudrate, settings->databits, @@ -225,7 +226,8 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, 10000 ); if (rc < 0) - err("Reading line status failed (error = %d)", rc); + dev_err(&port->dev, "Reading line status failed (error = %d)\n", + rc); else { status = get_unaligned_le16(status_buf); @@ -279,15 +281,16 @@ static int klsi_105_startup(struct usb_serial *serial) priv->write_urb_pool[j] = urb; if (urb == NULL) { - err("No more urbs???"); + dev_err(&serial->dev->dev, "No more urbs???\n"); goto err_cleanup; } urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (!urb->transfer_buffer) { - err("%s - out of memory for urb buffers.", - __func__); + dev_err(&serial->dev->dev, + "%s - out of memory for urb buffers.\n", + __func__); goto err_cleanup; } } @@ -408,7 +411,8 @@ static int klsi_105_open(struct tty_struct *tty, rc = usb_submit_urb(port->read_urb, GFP_KERNEL); if (rc) { - err("%s - failed submitting read urb, error %d", __func__, rc); + dev_err(&port->dev, "%s - failed submitting read urb, " + "error %d\n", __func__, rc); retval = rc; goto exit; } @@ -423,7 +427,7 @@ static int klsi_105_open(struct tty_struct *tty, 0, KLSI_TIMEOUT); if (rc < 0) { - err("Enabling read failed (error = %d)", rc); + dev_err(&port->dev, "Enabling read failed (error = %d)\n", rc); retval = rc; } else dbg("%s - enabled reading", __func__); @@ -463,7 +467,8 @@ static void klsi_105_close(struct tty_struct *tty, NULL, 0, KLSI_TIMEOUT); if (rc < 0) - err("Disabling read failed (error = %d)", rc); + dev_err(&port->dev, + "Disabling read failed (error = %d)\n", rc); } mutex_unlock(&port->serial->disc_mutex); @@ -522,7 +527,9 @@ static int klsi_105_write(struct tty_struct *tty, urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC); if (urb->transfer_buffer == NULL) { - err("%s - no more kernel memory...", __func__); + dev_err(&port->dev, + "%s - no more kernel memory...\n", + __func__); goto exit; } } @@ -549,8 +556,9 @@ static int klsi_105_write(struct tty_struct *tty, /* send the data out the bulk port */ result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { - err("%s - failed submitting write urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed submitting write urb, error %d\n", + __func__, result); goto exit; } buf += size; @@ -694,8 +702,9 @@ static void klsi_105_read_bulk_callback(struct urb *urb) port); rc = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (rc) - err("%s - failed resubmitting read urb, error %d", - __func__, rc); + dev_err(&port->dev, + "%s - failed resubmitting read urb, error %d\n", + __func__, rc); } /* klsi_105_read_bulk_callback */ @@ -799,7 +808,8 @@ static void klsi_105_set_termios(struct tty_struct *tty, priv->cfg.databits = kl5kusb105a_dtb_8; break; default: - err("CSIZE was not CS5-CS8, using default of 8"); + dev_err(&port->dev, + "CSIZE was not CS5-CS8, using default of 8\n"); priv->cfg.databits = kl5kusb105a_dtb_8; break; } @@ -886,7 +896,8 @@ static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file) rc = klsi_105_get_line_state(port, &line_state); if (rc < 0) { - err("Reading line control failed (error = %d)", rc); + dev_err(&port->dev, + "Reading line control failed (error = %d)\n", rc); /* better return value? EAGAIN? */ return rc; } @@ -944,8 +955,9 @@ static void klsi_105_unthrottle(struct tty_struct *tty) port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - err("%s - failed submitting read urb, error %d", __func__, - result); + dev_err(&port->dev, + "%s - failed submitting read urb, error %d\n", + __func__, result); } diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 29fa66ea2d21..07710cf31d0d 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -246,7 +246,8 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty, 0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE, WDR_TIMEOUT); if (rc < 0) /*FIXME: What value speed results */ - err("Set BAUD RATE %d failed (error = %d)", value, rc); + dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n", + value, rc); else tty_encode_baud_rate(tty, speed, speed); dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor); @@ -274,8 +275,9 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty, 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE, WDR_TIMEOUT); if (rc < 0) - err("Sending USB device request code %d failed (error = %d)", - MCT_U232_SET_UNKNOWN1_REQUEST, rc); + dev_err(&port->dev, "Sending USB device request code %d " + "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST, + rc); if (port && C_CRTSCTS(tty)) cts_enable_byte = 1; @@ -288,8 +290,8 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty, 0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE, WDR_TIMEOUT); if (rc < 0) - err("Sending USB device request code %d failed (error = %d)", - MCT_U232_SET_CTS_REQUEST, rc); + dev_err(&port->dev, "Sending USB device request code %d " + "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc); return rc; } /* mct_u232_set_baud_rate */ @@ -303,7 +305,8 @@ static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr) 0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE, WDR_TIMEOUT); if (rc < 0) - err("Set LINE CTRL 0x%x failed (error = %d)", lcr, rc); + dev_err(&serial->dev->dev, + "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc); dbg("set_line_ctrl: 0x%x", lcr); return rc; } /* mct_u232_set_line_ctrl */ @@ -325,7 +328,8 @@ static int mct_u232_set_modem_ctrl(struct usb_serial *serial, 0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE, WDR_TIMEOUT); if (rc < 0) - err("Set MODEM CTRL 0x%x failed (error = %d)", mcr, rc); + dev_err(&serial->dev->dev, + "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); return rc; @@ -341,7 +345,8 @@ static int mct_u232_get_modem_stat(struct usb_serial *serial, 0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE, WDR_TIMEOUT); if (rc < 0) { - err("Get MODEM STATus failed (error = %d)", rc); + dev_err(&serial->dev->dev, + "Get MODEM STATus failed (error = %d)\n", rc); *msr = 0; } dbg("get_modem_stat: 0x%x", *msr); @@ -470,8 +475,9 @@ static int mct_u232_open(struct tty_struct *tty, port->read_urb->dev = port->serial->dev; retval = usb_submit_urb(port->read_urb, GFP_KERNEL); if (retval) { - err("usb_submit_urb(read bulk) failed pipe 0x%x err %d", - port->read_urb->pipe, retval); + dev_err(&port->dev, + "usb_submit_urb(read bulk) failed pipe 0x%x err %d\n", + port->read_urb->pipe, retval); goto error; } @@ -479,8 +485,9 @@ static int mct_u232_open(struct tty_struct *tty, retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (retval) { usb_kill_urb(port->read_urb); - err(" usb_submit_urb(read int) failed pipe 0x%x err %d", - port->interrupt_in_urb->pipe, retval); + dev_err(&port->dev, + "usb_submit_urb(read int) failed pipe 0x%x err %d", + port->interrupt_in_urb->pipe, retval); goto error; } return 0; @@ -612,8 +619,9 @@ static void mct_u232_read_int_callback(struct urb *urb) exit: retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) - err("%s - usb_submit_urb failed with result %d", - __func__, retval); + dev_err(&port->dev, + "%s - usb_submit_urb failed with result %d\n", + __func__, retval); } /* mct_u232_read_int_callback */ static void mct_u232_set_termios(struct tty_struct *tty, @@ -680,7 +688,8 @@ static void mct_u232_set_termios(struct tty_struct *tty, case CS8: last_lcr |= MCT_U232_DATA_BITS_8; break; default: - err("CSIZE was not CS5-CS8, using default of 8"); + dev_err(&port->dev, + "CSIZE was not CS5-CS8, using default of 8\n"); last_lcr |= MCT_U232_DATA_BITS_8; break; } diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 5711aa55d24b..e772cc0a97fd 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -355,14 +355,16 @@ static int mos7720_open(struct tty_struct *tty, mos7720_port->write_urb_pool[j] = urb; if (urb == NULL) { - err("No more urbs???"); + dev_err(&port->dev, "No more urbs???\n"); continue; } urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (!urb->transfer_buffer) { - err("%s-out of memory for urb buffers.", __func__); + dev_err(&port->dev, + "%s-out of memory for urb buffers.\n", + __func__); usb_free_urb(mos7720_port->write_urb_pool[j]); mos7720_port->write_urb_pool[j] = NULL; continue; @@ -694,7 +696,8 @@ static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port, urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (urb->transfer_buffer == NULL) { - err("%s no more kernel memory...", __func__); + dev_err(&port->dev, "%s no more kernel memory...\n", + __func__); goto exit; } } @@ -714,8 +717,8 @@ static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port, /* send it down the pipe */ status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { - err("%s - usb_submit_urb(write bulk) failed with status = %d", - __func__, status); + dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " + "with status = %d\n", __func__, status); bytes_sent = status; goto exit; } @@ -975,7 +978,7 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, /* Calculate the Divisor */ status = calc_baud_rate_divisor(baudrate, &divisor); if (status) { - err("%s - bad baud rate", __func__); + dev_err(&port->dev, "%s - bad baud rate\n", __func__); return status; } @@ -1478,7 +1481,7 @@ static int mos7720_startup(struct usb_serial *serial) /* create our private serial structure */ mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL); if (mos7720_serial == NULL) { - err("%s - Out of memory", __func__); + dev_err(&dev->dev, "%s - Out of memory\n", __func__); return -ENOMEM; } @@ -1491,7 +1494,7 @@ static int mos7720_startup(struct usb_serial *serial) for (i = 0; i < serial->num_ports; ++i) { mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); if (mos7720_port == NULL) { - err("%s - Out of memory", __func__); + dev_err(&dev->dev, "%s - Out of memory\n", __func__); usb_set_serial_data(serial, NULL); kfree(mos7720_serial); return -ENOMEM; diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index d5f682626e71..fda4a6421c44 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -844,7 +844,7 @@ static int mos7840_open(struct tty_struct *tty, mos7840_port->write_urb_pool[j] = urb; if (urb == NULL) { - err("No more urbs???"); + dev_err(&port->dev, "No more urbs???\n"); continue; } @@ -853,7 +853,9 @@ static int mos7840_open(struct tty_struct *tty, if (!urb->transfer_buffer) { usb_free_urb(urb); mos7840_port->write_urb_pool[j] = NULL; - err("%s-out of memory for urb buffers.", __func__); + dev_err(&port->dev, + "%s-out of memory for urb buffers.\n", + __func__); continue; } } @@ -1021,8 +1023,8 @@ static int mos7840_open(struct tty_struct *tty, usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); if (response) { - err("%s - Error %d submitting interrupt urb", - __func__, response); + dev_err(&port->dev, "%s - Error %d submitting " + "interrupt urb\n", __func__, response); } } @@ -1055,8 +1057,8 @@ static int mos7840_open(struct tty_struct *tty, port->bulk_in_endpointAddress); response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL); if (response) { - err("%s - Error %d submitting control urb", __func__, - response); + dev_err(&port->dev, "%s - Error %d submitting control urb\n", + __func__, response); } /* initialize our wait queues */ @@ -1492,7 +1494,8 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (urb->transfer_buffer == NULL) { - err("%s no more kernel memory...", __func__); + dev_err(&port->dev, "%s no more kernel memory...\n", + __func__); goto exit; } } @@ -1517,8 +1520,8 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, if (status) { mos7840_port->busy[i] = 0; - err("%s - usb_submit_urb(write bulk) failed with status = %d", - __func__, status); + dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " + "with status = %d\n", __func__, status); bytes_sent = status; goto exit; } @@ -1856,8 +1859,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, /* Calculate the Divisor */ if (status) { - err("%s - bad baud rate", __func__); - dbg("%s\n", "bad baud rate"); + dev_err(&port->dev, "%s - bad baud rate\n", __func__); return status; } /* Enable access to divisor latch */ @@ -2446,7 +2448,7 @@ static int mos7840_startup(struct usb_serial *serial) for (i = 0; i < serial->num_ports; ++i) { mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); if (mos7840_port == NULL) { - err("%s - Out of memory", __func__); + dev_err(&dev->dev, "%s - Out of memory\n", __func__); status = -ENOMEM; i--; /* don't follow NULL pointer cleaning up */ goto error; diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 9890f26cd91d..df6539712726 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -154,8 +154,8 @@ static int omninet_attach(struct usb_serial *serial) od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL); if (!od) { - err("%s- kmalloc(%Zd) failed.", - __func__, sizeof(struct omninet_data)); + dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", + __func__, sizeof(struct omninet_data)); return -ENOMEM; } usb_set_serial_port_data(port, od); @@ -183,8 +183,9 @@ static int omninet_open(struct tty_struct *tty, omninet_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) - err("%s - failed submitting read urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed submitting read urb, error %d\n", + __func__, result); return result; } @@ -244,8 +245,9 @@ static void omninet_read_bulk_callback(struct urb *urb) omninet_read_bulk_callback, port); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed resubmitting read urb, error %d\n", + __func__, result); return; } @@ -298,8 +300,9 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, result = usb_submit_urb(wport->write_urb, GFP_ATOMIC); if (result) { wport->write_urb_busy = 0; - err("%s - failed submitting write urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed submitting write urb, error %d\n", + __func__, result); } else result = count; diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 40cff61cb4a2..4b463cd140ef 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -256,11 +256,12 @@ static void safe_read_bulk_callback(struct urb *urb) data, actual_length); tty_flip_buffer_push(tty); } else { - err("%s - inconsistent lengths %d:%d", + dev_err(&port->dev, + "%s - inconsistent lengths %d:%d\n", __func__, actual_length, length); } } else { - err("%s - bad CRC %x", __func__, fcs); + dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs); } } else { tty_insert_flip_string(tty, data, length); @@ -277,8 +278,9 @@ static void safe_read_bulk_callback(struct urb *urb) result = usb_submit_urb(urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed resubmitting read urb, error %d\n", + __func__, result); /* FIXME: Need a mechanism to retry later if this happens */ } @@ -369,8 +371,9 @@ static int safe_write(struct tty_struct *tty, struct usb_serial_port *port, result = usb_submit_urb(port->write_urb, GFP_KERNEL); if (result) { port->write_urb_busy = 0; - err("%s - failed submitting write urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed submitting write urb, error %d\n", + __func__, result); return 0; } dbg("%s urb: %p submitted", __func__, port->write_urb); diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 96aeec746191..a65bc2bd8e71 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -589,8 +589,8 @@ static void spcp8x5_set_termios(struct tty_struct *tty, case 1000000: buf[0] = 0x0b; break; default: - err("spcp825 driver does not support the baudrate " - "requested, using default of 9600."); + dev_err(&port->dev, "spcp825 driver does not support the " + "baudrate requested, using default of 9600.\n"); } /* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */ @@ -629,7 +629,8 @@ static void spcp8x5_set_termios(struct tty_struct *tty, SET_UART_FORMAT_TYPE, SET_UART_FORMAT, uartdata, 0, NULL, 0, 100); if (i < 0) - err("Set UART format %#x failed (error = %d)", uartdata, i); + dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n", + uartdata, i); dbg("0x21:0x40:0:0 %d\n", i); if (cflag & CRTSCTS) { diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 92ba4f7361e4..8be3f39891c7 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1121,7 +1121,8 @@ static int __init usb_serial_init(void) result = bus_register(&usb_serial_bus_type); if (result) { - err("%s - registering bus driver failed", __func__); + printk(KERN_ERR "usb-serial: %s - registering bus driver " + "failed\n", __func__); goto exit_bus; } @@ -1142,21 +1143,24 @@ static int __init usb_serial_init(void) tty_set_operations(usb_serial_tty_driver, &serial_ops); result = tty_register_driver(usb_serial_tty_driver); if (result) { - err("%s - tty_register_driver failed", __func__); + printk(KERN_ERR "usb-serial: %s - tty_register_driver failed\n", + __func__); goto exit_reg_driver; } /* register the USB driver */ result = usb_register(&usb_serial_driver); if (result < 0) { - err("%s - usb_register failed", __func__); + printk(KERN_ERR "usb-serial: %s - usb_register failed\n", + __func__); goto exit_tty; } /* register the generic driver, if we should */ result = usb_serial_generic_register(debug); if (result < 0) { - err("%s - registering generic driver failed", __func__); + printk(KERN_ERR "usb-serial: %s - registering generic " + "driver failed\n", __func__); goto exit_generic; } @@ -1174,7 +1178,8 @@ exit_reg_driver: bus_unregister(&usb_serial_bus_type); exit_bus: - err("%s - returning with error %d", __func__, result); + printk(KERN_ERR "usb-serial: %s - returning with error %d\n", + __func__, result); put_tty_driver(usb_serial_tty_driver); return result; } @@ -1233,8 +1238,8 @@ int usb_serial_register(struct usb_serial_driver *driver) retval = usb_serial_bus_register(driver); if (retval) { - err("problem %d when registering driver %s", - retval, driver->description); + printk(KERN_ERR "usb-serial: problem %d when registering " + "driver %s\n", retval, driver->description); list_del(&driver->driver_list); } else printk(KERN_INFO "USB Serial support registered for %s\n", diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index de4b5f0e7f3d..4facce3d9364 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -768,7 +768,7 @@ static int visor_probe(struct usb_serial *serial, dbg("%s", __func__); if (serial->dev->actconfig->desc.bConfigurationValue != 1) { - err("active config #%d != 1 ??", + dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", serial->dev->actconfig->desc.bConfigurationValue); return -ENODEV; } diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 39f7f8d291d6..5335d3211c07 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -303,12 +303,15 @@ static int whiteheat_firmware_download(struct usb_serial *serial, if (request_ihex_firmware(&firmware_fw, "whiteheat.fw", &serial->dev->dev)) { - err("%s - request \"whiteheat.fw\" failed", __func__); + dev_err(&serial->dev->dev, + "%s - request \"whiteheat.fw\" failed\n", __func__); goto out; } if (request_ihex_firmware(&loader_fw, "whiteheat_loader.fw", &serial->dev->dev)) { - err("%s - request \"whiteheat_loader.fw\" failed", __func__); + dev_err(&serial->dev->dev, + "%s - request \"whiteheat_loader.fw\" failed\n", + __func__); goto out; } ret = 0; @@ -320,9 +323,10 @@ static int whiteheat_firmware_download(struct usb_serial *serial, (unsigned char *)record->data, be16_to_cpu(record->len), 0xa0); if (response < 0) { - err("%s - ezusb_writememory failed for loader (%d %04X %p %d)", - __func__, response, be32_to_cpu(record->addr), - record->data, be16_to_cpu(record->len)); + dev_err(&serial->dev->dev, "%s - ezusb_writememory " + "failed for loader (%d %04X %p %d)\n", + __func__, response, be32_to_cpu(record->addr), + record->data, be16_to_cpu(record->len)); break; } record = ihex_next_binrec(record); @@ -338,9 +342,11 @@ static int whiteheat_firmware_download(struct usb_serial *serial, (unsigned char *)record->data, be16_to_cpu(record->len), 0xa3); if (response < 0) { - err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)", - __func__, response, be32_to_cpu(record->addr), - record->data, be16_to_cpu(record->len)); + dev_err(&serial->dev->dev, "%s - ezusb_writememory " + "failed for first firmware step " + "(%d %04X %p %d)\n", __func__, response, + be32_to_cpu(record->addr), record->data, + be16_to_cpu(record->len)); break; } ++record; @@ -354,9 +360,11 @@ static int whiteheat_firmware_download(struct usb_serial *serial, (unsigned char *)record->data, be16_to_cpu(record->len), 0xa0); if (response < 0) { - err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)", - __func__, response, be32_to_cpu(record->addr), - record->data, be16_to_cpu(record->len)); + dev_err(&serial->dev->dev, "%s - ezusb_writememory " + "failed for second firmware step " + "(%d %04X %p %d)\n", __func__, response, + be32_to_cpu(record->addr), record->data, + be16_to_cpu(record->len)); break; } ++record; @@ -421,12 +429,12 @@ static int whiteheat_attach(struct usb_serial *serial) ret = usb_bulk_msg(serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT_MS); if (ret) { - err("%s: Couldn't send command [%d]", - serial->type->description, ret); + dev_err(&serial->dev->dev, "%s: Couldn't send command [%d]\n", + serial->type->description, ret); goto no_firmware; } else if (alen != 2) { - err("%s: Send command incomplete [%d]", - serial->type->description, alen); + dev_err(&serial->dev->dev, "%s: Send command incomplete [%d]\n", + serial->type->description, alen); goto no_firmware; } @@ -437,16 +445,16 @@ static int whiteheat_attach(struct usb_serial *serial) ret = usb_bulk_msg(serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS); if (ret) { - err("%s: Couldn't get results [%d]", - serial->type->description, ret); + dev_err(&serial->dev->dev, "%s: Couldn't get results [%d]\n", + serial->type->description, ret); goto no_firmware; } else if (alen != sizeof(*hw_info) + 1) { - err("%s: Get results incomplete [%d]", - serial->type->description, alen); + dev_err(&serial->dev->dev, "%s: Get results incomplete [%d]\n", + serial->type->description, alen); goto no_firmware; } else if (result[0] != command[0]) { - err("%s: Command failed [%d]", - serial->type->description, result[0]); + dev_err(&serial->dev->dev, "%s: Command failed [%d]\n", + serial->type->description, result[0]); goto no_firmware; } @@ -461,8 +469,9 @@ static int whiteheat_attach(struct usb_serial *serial) info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); if (info == NULL) { - err("%s: Out of memory for port structures\n", - serial->type->description); + dev_err(&port->dev, + "%s: Out of memory for port structures\n", + serial->type->description); goto no_private; } @@ -482,18 +491,20 @@ static int whiteheat_attach(struct usb_serial *serial) for (j = 0; j < urb_pool_size; j++) { urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - err("No free urbs available"); + dev_err(&port->dev, "No free urbs available\n"); goto no_rx_urb; } buf_size = port->read_urb->transfer_buffer_length; urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL); if (!urb->transfer_buffer) { - err("Couldn't allocate urb buffer"); + dev_err(&port->dev, + "Couldn't allocate urb buffer\n"); goto no_rx_buf; } wrap = kmalloc(sizeof(*wrap), GFP_KERNEL); if (!wrap) { - err("Couldn't allocate urb wrapper"); + dev_err(&port->dev, + "Couldn't allocate urb wrapper\n"); goto no_rx_wrap; } usb_fill_bulk_urb(urb, serial->dev, @@ -506,18 +517,20 @@ static int whiteheat_attach(struct usb_serial *serial) urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - err("No free urbs available"); + dev_err(&port->dev, "No free urbs available\n"); goto no_tx_urb; } buf_size = port->write_urb->transfer_buffer_length; urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL); if (!urb->transfer_buffer) { - err("Couldn't allocate urb buffer"); + dev_err(&port->dev, + "Couldn't allocate urb buffer\n"); goto no_tx_buf; } wrap = kmalloc(sizeof(*wrap), GFP_KERNEL); if (!wrap) { - err("Couldn't allocate urb wrapper"); + dev_err(&port->dev, + "Couldn't allocate urb wrapper\n"); goto no_tx_wrap; } usb_fill_bulk_urb(urb, serial->dev, @@ -535,8 +548,9 @@ static int whiteheat_attach(struct usb_serial *serial) command_info = kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL); if (command_info == NULL) { - err("%s: Out of memory for port structures\n", - serial->type->description); + dev_err(&serial->dev->dev, + "%s: Out of memory for port structures\n", + serial->type->description); goto no_command_private; } @@ -553,12 +567,15 @@ static int whiteheat_attach(struct usb_serial *serial) no_firmware: /* Firmware likely not running */ - err("%s: Unable to retrieve firmware version, try replugging\n", - serial->type->description); - err("%s: If the firmware is not running (status led not blinking)\n", - serial->type->description); - err("%s: please contact support@connecttech.com\n", - serial->type->description); + dev_err(&serial->dev->dev, + "%s: Unable to retrieve firmware version, try replugging\n", + serial->type->description); + dev_err(&serial->dev->dev, + "%s: If the firmware is not running (status led not blinking)\n", + serial->type->description); + dev_err(&serial->dev->dev, + "%s: please contact support@connecttech.com\n", + serial->type->description); kfree(result); return -ENODEV; @@ -681,8 +698,9 @@ static int whiteheat_open(struct tty_struct *tty, /* Start reading from the device */ retval = start_port_read(port); if (retval) { - err("%s - failed submitting read urb, error %d", - __func__, retval); + dev_err(&port->dev, + "%s - failed submitting read urb, error %d\n", + __func__, retval); firm_close(port); stop_command_port(port->serial); goto exit; @@ -807,8 +825,9 @@ static int whiteheat_write(struct tty_struct *tty, urb->transfer_buffer_length = bytes; result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { - err("%s - failed submitting write urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed submitting write urb, error %d\n", + __func__, result); sent = result; spin_lock_irqsave(&info->lock, flags); list_add(tmp, &info->tx_urbs_free); @@ -1076,7 +1095,7 @@ static void whiteheat_read_callback(struct urb *urb) wrap = urb_to_wrap(urb, &info->rx_urbs_submitted); if (!wrap) { spin_unlock(&info->lock); - err("%s - Not my urb!", __func__); + dev_err(&port->dev, "%s - Not my urb!\n", __func__); return; } list_del(&wrap->list); @@ -1120,7 +1139,7 @@ static void whiteheat_write_callback(struct urb *urb) wrap = urb_to_wrap(urb, &info->tx_urbs_submitted); if (!wrap) { spin_unlock(&info->lock); - err("%s - Not my urb!", __func__); + dev_err(&port->dev, "%s - Not my urb!\n", __func__); return; } list_move(&wrap->list, &info->tx_urbs_free); @@ -1384,8 +1403,9 @@ static int start_command_port(struct usb_serial *serial) command_port->read_urb->dev = serial->dev; retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL); if (retval) { - err("%s - failed submitting read urb, error %d", - __func__, retval); + dev_err(&serial->dev->dev, + "%s - failed submitting read urb, error %d\n", + __func__, retval); goto exit; } } @@ -1523,7 +1543,8 @@ static void rx_data_softint(struct work_struct *work) urb->dev = port->serial->dev; result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { - err("%s - failed resubmitting read urb, error %d", + dev_err(&port->dev, + "%s - failed resubmitting read urb, error %d\n", __func__, result); spin_lock_irqsave(&info->lock, flags); list_add(tmp, &info->rx_urbs_free); -- cgit v1.2.3 From 9908a32e94de2141463e104c9924279ed3509447 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Aug 2008 09:37:34 -0700 Subject: USB: remove err() macro from usb class drivers USB should not be having it's own printk macros, so remove err() and use the system-wide standard of dev_err() wherever possible. In the few places that will not work out, use a basic printk(). Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 23 +++++++++++++--------- drivers/usb/class/cdc-wdm.c | 48 ++++++++++++++++++++++++++++----------------- drivers/usb/class/usblp.c | 7 ++++--- 3 files changed, 48 insertions(+), 30 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d9c2b8dafd67..fab23ee8702b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -326,8 +326,8 @@ exit: usb_mark_last_busy(acm->dev); retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) - err ("%s - usb_submit_urb failed with result %d", - __func__, retval); + dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with " + "result %d", __func__, retval); } /* data interface returns incoming bytes, or we got unthrottled */ @@ -514,7 +514,7 @@ static void acm_waker(struct work_struct *waker) rv = usb_autopm_get_interface(acm->control); if (rv < 0) { - err("Autopm failure in %s", __func__); + dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__); return; } if (acm->delayed_wb) { @@ -924,7 +924,7 @@ static int acm_probe (struct usb_interface *intf, /* normal probing*/ if (!buffer) { - err("Weird descriptor references\n"); + dev_err(&intf->dev, "Weird descriptor references\n"); return -EINVAL; } @@ -934,21 +934,24 @@ static int acm_probe (struct usb_interface *intf, buflen = intf->cur_altsetting->endpoint->extralen; buffer = intf->cur_altsetting->endpoint->extra; } else { - err("Zero length descriptor references\n"); + dev_err(&intf->dev, + "Zero length descriptor references\n"); return -EINVAL; } } while (buflen > 0) { if (buffer [1] != USB_DT_CS_INTERFACE) { - err("skipping garbage\n"); + dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; } switch (buffer [2]) { case USB_CDC_UNION_TYPE: /* we've found it */ if (union_header) { - err("More than one union descriptor, skipping ..."); + dev_err(&intf->dev, "More than one " + "union descriptor, " + "skipping ...\n"); goto next_desc; } union_header = (struct usb_cdc_union_desc *) @@ -966,7 +969,9 @@ static int acm_probe (struct usb_interface *intf, call_management_function = buffer[3]; call_interface_num = buffer[4]; if ((call_management_function & 3) != 3) - err("This device cannot do calls on its own. It is no modem."); + dev_err(&intf->dev, "This device " + "cannot do calls on its own. " + "It is no modem.\n"); break; default: /* there are LOTS more CDC descriptors that @@ -1051,7 +1056,7 @@ skip_normal_probe: for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); if (minor == ACM_TTY_MINORS) { - err("no more free acm devices"); + dev_err(&intf->dev, "no more free acm devices\n"); return -ENODEV; } diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 7e8e1235e4e5..7429f70b9d06 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -132,10 +132,12 @@ static void wdm_in_callback(struct urb *urb) "nonzero urb status received: -ESHUTDOWN"); break; case -EPIPE: - err("nonzero urb status received: -EPIPE"); + dev_err(&desc->intf->dev, + "nonzero urb status received: -EPIPE\n"); break; default: - err("Unexpected error %d", status); + dev_err(&desc->intf->dev, + "Unexpected error %d\n", status); break; } } @@ -170,16 +172,18 @@ static void wdm_int_callback(struct urb *urb) return; /* unplug */ case -EPIPE: set_bit(WDM_INT_STALL, &desc->flags); - err("Stall on int endpoint"); + dev_err(&desc->intf->dev, "Stall on int endpoint\n"); goto sw; /* halt is cleared in work */ default: - err("nonzero urb status received: %d", status); + dev_err(&desc->intf->dev, + "nonzero urb status received: %d\n", status); break; } } if (urb->actual_length < sizeof(struct usb_cdc_notification)) { - err("wdm_int_callback - %d bytes", urb->actual_length); + dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n", + urb->actual_length); goto exit; } @@ -198,7 +202,8 @@ static void wdm_int_callback(struct urb *urb) goto exit; default: clear_bit(WDM_POLL_RUNNING, &desc->flags); - err("unknown notification %d received: index %d len %d", + dev_err(&desc->intf->dev, + "unknown notification %d received: index %d len %d\n", dr->bNotificationType, dr->wIndex, dr->wLength); goto exit; } @@ -236,14 +241,16 @@ static void wdm_int_callback(struct urb *urb) sw: rv = schedule_work(&desc->rxwork); if (rv) - err("Cannot schedule work"); + dev_err(&desc->intf->dev, + "Cannot schedule work\n"); } } exit: rv = usb_submit_urb(urb, GFP_ATOMIC); if (rv) - err("%s - usb_submit_urb failed with result %d", - __func__, rv); + dev_err(&desc->intf->dev, + "%s - usb_submit_urb failed with result %d\n", + __func__, rv); } @@ -353,7 +360,7 @@ static ssize_t wdm_write if (rv < 0) { kfree(buf); clear_bit(WDM_IN_USE, &desc->flags); - err("Tx URB error: %d", rv); + dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv); } else { dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d", req->wIndex); @@ -401,7 +408,8 @@ retry: int t = desc->rerr; desc->rerr = 0; spin_unlock_irq(&desc->iuspin); - err("reading had resulted in %d", t); + dev_err(&desc->intf->dev, + "reading had resulted in %d\n", t); rv = -EIO; goto err; } @@ -440,7 +448,7 @@ retry: err: mutex_unlock(&desc->rlock); if (rv < 0) - err("wdm_read: exit error"); + dev_err(&desc->intf->dev, "wdm_read: exit error\n"); return rv; } @@ -450,7 +458,8 @@ static int wdm_flush(struct file *file, fl_owner_t id) wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags)); if (desc->werr < 0) - err("Error in flush path: %d", desc->werr); + dev_err(&desc->intf->dev, "Error in flush path: %d\n", + desc->werr); return desc->werr; } @@ -502,7 +511,7 @@ static int wdm_open(struct inode *inode, struct file *file) rv = usb_autopm_get_interface(desc->intf); if (rv < 0) { - err("Error autopm - %d", rv); + dev_err(&desc->intf->dev, "Error autopm - %d\n", rv); goto out; } intf->needs_remote_wakeup = 1; @@ -512,7 +521,8 @@ static int wdm_open(struct inode *inode, struct file *file) rv = usb_submit_urb(desc->validity, GFP_KERNEL); if (rv < 0) { desc->count--; - err("Error submitting int urb - %d", rv); + dev_err(&desc->intf->dev, + "Error submitting int urb - %d\n", rv); } } else { rv = 0; @@ -600,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) while (buflen > 0) { if (buffer [1] != USB_DT_CS_INTERFACE) { - err("skipping garbage"); + dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; } @@ -614,7 +624,8 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) "Finding maximum buffer length: %d", maxcom); break; default: - err("Ignoring extra header, type %d, length %d", + dev_err(&intf->dev, + "Ignoring extra header, type %d, length %d\n", buffer[2], buffer[0]); break; } @@ -772,7 +783,8 @@ static int recover_from_urb_loss(struct wdm_device *desc) if (desc->count) { rv = usb_submit_urb(desc->validity, GFP_NOIO); if (rv < 0) - err("Error resume submitting int urb - %d", rv); + dev_err(&desc->intf->dev, + "Error resume submitting int urb - %d\n", rv); } return rv; } diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 68a2239cd0b6..b5775af3ba26 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -593,8 +593,9 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) err = usblp_hp_channel_change_request(usblp, arg, &newChannel); if (err < 0) { - err("usblp%d: error = %d setting " - "HP channel", + dev_err(&usblp->dev->dev, + "usblp%d: error = %d setting " + "HP channel\n", usblp->minor, err); retval = -EIO; goto done; @@ -1345,7 +1346,7 @@ static void usblp_disconnect(struct usb_interface *intf) usb_deregister_dev(intf, &usblp_class); if (!usblp || !usblp->dev) { - err("bogus disconnect"); + dev_err(&intf->dev, "bogus disconnect\n"); BUG (); } -- cgit v1.2.3 From 69a85942ff2df8e1ee0a3b6afe8b1d85dce58333 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Aug 2008 09:37:34 -0700 Subject: USB: remove err() macro from usb core code USB should not be having it's own printk macros, so remove err() and use the system-wide standard of dev_err() wherever possible. In the few places that will not work out, use a basic printk(). Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 7 ++++--- drivers/usb/core/endpoint.c | 3 ++- drivers/usb/core/file.c | 5 +++-- drivers/usb/core/inode.c | 12 ++++++------ drivers/usb/core/urb.c | 4 ++-- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 7f621149f9f2..2bccefebff1b 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1777,19 +1777,20 @@ int __init usb_devio_init(void) retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX, "usb_device"); if (retval) { - err("unable to register minors for usb_device"); + printk(KERN_ERR "Unable to register minors for usb_device\n"); goto out; } cdev_init(&usb_device_cdev, &usbdev_file_operations); retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX); if (retval) { - err("unable to get usb_device major %d", USB_DEVICE_MAJOR); + printk(KERN_ERR "Unable to get usb_device major %d\n", + USB_DEVICE_MAJOR); goto error_cdev; } #ifdef CONFIG_USB_DEVICE_CLASS usb_classdev_class = class_create(THIS_MODULE, "usb_device"); if (IS_ERR(usb_classdev_class)) { - err("unable to register usb_device class"); + printk(KERN_ERR "Unable to register usb_device class\n"); retval = PTR_ERR(usb_classdev_class); cdev_del(&usb_device_cdev); usb_classdev_class = NULL; diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index 22912136fc14..946fae43d622 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c @@ -169,7 +169,8 @@ static int usb_endpoint_major_init(void) error = alloc_chrdev_region(&dev, 0, MAX_ENDPOINT_MINORS, "usb_endpoint"); if (error) { - err("unable to get a dynamic major for usb endpoints"); + printk(KERN_ERR "Unable to get a dynamic major for " + "usb endpoints.\n"); return error; } usb_endpoint_major = MAJOR(dev); diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 55f7f310924b..997e659ff693 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -86,7 +86,7 @@ static int init_usb_class(void) usb_class->class = class_create(THIS_MODULE, "usb"); if (IS_ERR(usb_class->class)) { result = IS_ERR(usb_class->class); - err("class_create failed for usb devices"); + printk(KERN_ERR "class_create failed for usb devices\n"); kfree(usb_class); usb_class = NULL; } @@ -115,7 +115,8 @@ int usb_major_init(void) error = register_chrdev(USB_MAJOR, "usb", &usb_fops); if (error) - err("unable to get major %d for usb devices", USB_MAJOR); + printk(KERN_ERR "Unable to get major %d for usb devices\n", + USB_MAJOR); return error; } diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 2cf2dc8528d8..94632264dccf 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -180,8 +180,8 @@ static int parse_options(struct super_block *s, char *data) listmode = option & S_IRWXUGO; break; default: - err("usbfs: unrecognised mount option \"%s\" " - "or missing value\n", p); + printk(KERN_ERR "usbfs: unrecognised mount option " + "\"%s\" or missing value\n", p); return -EINVAL; } } @@ -601,7 +601,7 @@ static int create_special_files (void) /* create the devices special file */ retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count); if (retval) { - err ("Unable to get usbfs mount"); + printk(KERN_ERR "Unable to get usbfs mount\n"); goto exit; } @@ -613,7 +613,7 @@ static int create_special_files (void) NULL, &usbfs_devices_fops, listuid, listgid); if (devices_usbfs_dentry == NULL) { - err ("Unable to create devices usbfs file"); + printk(KERN_ERR "Unable to create devices usbfs file\n"); retval = -ENODEV; goto error_clean_mounts; } @@ -665,7 +665,7 @@ static void usbfs_add_bus(struct usb_bus *bus) bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent, bus, NULL, busuid, busgid); if (bus->usbfs_dentry == NULL) { - err ("error creating usbfs bus entry"); + printk(KERN_ERR "Error creating usbfs bus entry\n"); return; } } @@ -696,7 +696,7 @@ static void usbfs_add_device(struct usb_device *dev) &usbdev_file_operations, devuid, devgid); if (dev->usbfs_dentry == NULL) { - err ("error creating usbfs device entry"); + printk(KERN_ERR "Error creating usbfs device entry\n"); return; } diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 175d528f4029..f2638009a464 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -70,7 +70,7 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) iso_packets * sizeof(struct usb_iso_packet_descriptor), mem_flags); if (!urb) { - err("alloc_urb: kmalloc failed"); + printk(KERN_ERR "alloc_urb: kmalloc failed\n"); return NULL; } usb_init_urb(urb); @@ -407,7 +407,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) /* fail if submitter gave bogus flags */ if (urb->transfer_flags != orig_flags) { - err("BOGUS urb flags, %x --> %x", + dev_err(&dev->dev, "BOGUS urb flags, %x --> %x\n", orig_flags, urb->transfer_flags); return -EINVAL; } -- cgit v1.2.3 From fd3f1917e345d852ef9ae36178719f4e639f70ae Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Aug 2008 09:37:34 -0700 Subject: USB: remove err() macro from usb misc drivers USB should not be having it's own printk macros, so remove err() and use the system-wide standard of dev_err() wherever possible. In the few places that will not work out, use a basic printk(). Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/adutux.c | 17 ++++++++++------- drivers/usb/misc/appledisplay.c | 24 +++++++++++++----------- drivers/usb/misc/cypress_cy7c63.c | 6 +++--- drivers/usb/misc/cytherm.c | 6 +++--- drivers/usb/misc/emi26.c | 13 ++++++++----- 5 files changed, 37 insertions(+), 29 deletions(-) diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 92f58ccc8fb3..7b6922e08ed1 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -283,8 +283,8 @@ static int adu_open(struct inode *inode, struct file *file) interface = usb_find_interface(&adu_driver, subminor); if (!interface) { - err("%s - error, can't find device for minor %d", - __func__, subminor); + printk(KERN_ERR "adutux: %s - error, can't find device for " + "minor %d\n", __func__, subminor); retval = -ENODEV; goto exit_no_device; } @@ -416,7 +416,8 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, /* verify that the device wasn't unplugged */ if (dev->udev == NULL) { retval = -ENODEV; - err("No device or device unplugged %d", retval); + printk(KERN_ERR "adutux: No device or device unplugged %d\n", + retval); goto exit; } @@ -576,7 +577,8 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, /* verify that the device wasn't unplugged */ if (dev->udev == NULL) { retval = -ENODEV; - err("No device or device unplugged %d", retval); + printk(KERN_ERR "adutux: No device or device unplugged %d\n", + retval); goto exit; } @@ -645,7 +647,8 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); if (retval < 0) { dev->out_urb_finished = 1; - err("Couldn't submit interrupt_out_urb %d", retval); + dev_err(&dev->udev->dev, "Couldn't submit " + "interrupt_out_urb %d\n", retval); goto exit; } @@ -890,8 +893,8 @@ static int __init adu_init(void) /* register this driver with the USB subsystem */ result = usb_register(&adu_driver); if (result < 0) { - err("usb_register failed for the "__FILE__" driver. " - "Error number %d", result); + printk(KERN_ERR "usb_register failed for the "__FILE__ + " driver. Error number %d\n", result); goto exit; } diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 71d672ea1229..1d8e39a557d9 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -130,7 +130,8 @@ static void appledisplay_complete(struct urb *urb) exit: retval = usb_submit_urb(pdata->urb, GFP_ATOMIC); if (retval) { - err("%s - usb_submit_urb failed with result %d", + dev_err(&pdata->udev->dev, + "%s - usb_submit_urb failed with result %d\n", __func__, retval); } } @@ -220,7 +221,7 @@ static int appledisplay_probe(struct usb_interface *iface, } } if (!int_in_endpointAddr) { - err("Could not find int-in endpoint"); + dev_err(&iface->dev, "Could not find int-in endpoint\n"); return -EIO; } @@ -228,7 +229,7 @@ static int appledisplay_probe(struct usb_interface *iface, pdata = kzalloc(sizeof(struct appledisplay), GFP_KERNEL); if (!pdata) { retval = -ENOMEM; - err("Out of memory"); + dev_err(&iface->dev, "Out of memory\n"); goto error; } @@ -241,8 +242,8 @@ static int appledisplay_probe(struct usb_interface *iface, pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL); if (!pdata->msgdata) { retval = -ENOMEM; - err("appledisplay: Allocating buffer for control messages " - "failed"); + dev_err(&iface->dev, + "Allocating buffer for control messages failed\n"); goto error; } @@ -250,7 +251,7 @@ static int appledisplay_probe(struct usb_interface *iface, pdata->urb = usb_alloc_urb(0, GFP_KERNEL); if (!pdata->urb) { retval = -ENOMEM; - err("appledisplay: Allocating URB failed"); + dev_err(&iface->dev, "Allocating URB failed\n"); goto error; } @@ -259,7 +260,7 @@ static int appledisplay_probe(struct usb_interface *iface, GFP_KERNEL, &pdata->urb->transfer_dma); if (!pdata->urbdata) { retval = -ENOMEM; - err("appledisplay: Allocating URB buffer failed"); + dev_err(&iface->dev, "Allocating URB buffer failed\n"); goto error; } @@ -270,7 +271,7 @@ static int appledisplay_probe(struct usb_interface *iface, pdata, 1); if (usb_submit_urb(pdata->urb, GFP_KERNEL)) { retval = -EIO; - err("appledisplay: Submitting URB failed"); + dev_err(&iface->dev, "Submitting URB failed\n"); goto error; } @@ -280,7 +281,7 @@ static int appledisplay_probe(struct usb_interface *iface, pdata->bd = backlight_device_register(bl_name, NULL, pdata, &appledisplay_bl_data); if (IS_ERR(pdata->bd)) { - err("appledisplay: Backlight registration failed"); + dev_err(&iface->dev, "Backlight registration failed\n"); goto error; } @@ -291,7 +292,8 @@ static int appledisplay_probe(struct usb_interface *iface, if (brightness < 0) { retval = brightness; - err("appledisplay: Error while getting initial brightness: %d", retval); + dev_err(&iface->dev, + "Error while getting initial brightness: %d\n", retval); goto error; } @@ -352,7 +354,7 @@ static int __init appledisplay_init(void) { wq = create_singlethread_workqueue("appledisplay"); if (!wq) { - err("Could not create work queue\n"); + printk(KERN_ERR "appledisplay: Could not create work queue\n"); return -ENOMEM; } diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index 937940404b7a..5720bfef6a38 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c @@ -278,9 +278,9 @@ static int __init cypress_init(void) /* register this driver with the USB subsystem */ result = usb_register(&cypress_driver); - if (result) { - err("Function usb_register failed! Error number: %d\n", result); - } + if (result) + printk(KERN_ERR KBUILD_MODNAME ": usb_register failed! " + "Error number: %d\n", result); return result; } diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index 68e1d1723873..4fb3c38b924b 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c @@ -422,9 +422,9 @@ static int __init usb_cytherm_init(void) int result; result = usb_register(&cytherm_driver); - if (result) - { - err("usb_register failed. Error number %d", result); + if (result) { + printk(KERN_ERR KBUILD_MODNAME ": usb_register failed! " + "Error number: %d\n", result); return result; } diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 1ee72055f468..e762beb5f3c6 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c @@ -50,7 +50,7 @@ static int emi26_writememory (struct usb_device *dev, int address, unsigned char *buffer = kmemdup(data, length, GFP_KERNEL); if (!buffer) { - err("emi26: kmalloc(%d) failed.", length); + dev_err(&dev->dev, "kmalloc(%d) failed.\n", length); return -ENOMEM; } /* Note: usb_control_msg returns negative value on error or length of the @@ -68,7 +68,7 @@ static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit) /* printk(KERN_DEBUG "%s - %d", __func__, reset_bit); */ response = emi26_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0); if (response < 0) { - err("emi26: set_reset (%d) failed", reset_bit); + dev_err(&dev->dev, "set_reset (%d) failed\n", reset_bit); } return response; } @@ -88,7 +88,8 @@ static int emi26_load_firmware (struct usb_device *dev) buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL); if (!buf) { - err( "%s - error loading firmware: error = %d", __func__, -ENOMEM); + dev_err(&dev->dev, "%s - error loading firmware: error = %d\n", + __func__, -ENOMEM); err = -ENOMEM; goto wraperr; } @@ -106,14 +107,16 @@ static int emi26_load_firmware (struct usb_device *dev) &dev->dev); if (err) { nofw: - err( "%s - request_firmware() failed", __func__); + dev_err(&dev->dev, "%s - request_firmware() failed\n", + __func__); goto wraperr; } /* Assert reset (stop the CPU in the EMI) */ err = emi26_set_reset(dev,1); if (err < 0) { - err( "%s - error loading firmware: error = %d", __func__, err); + dev_err(&dev->dev,"%s - error loading firmware: error = %d\n", + __func__, err); goto wraperr; } -- cgit v1.2.3 From 802f389a2cc6e2771b8de915ac241456d41eb79e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Aug 2008 09:37:34 -0700 Subject: USB: remove err() macro from more usb drivers USB should not be having it's own printk macros, so remove err() and use the system-wide standard of dev_err() wherever possible. In the few places that will not work out, use a basic printk(). Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-if.c | 2 +- drivers/usb/host/r8a66597-hcd.c | 51 ++++++++++++++++++++++------------------- drivers/usb/image/mdc800.c | 46 ++++++++++++++++++++++++------------- drivers/usb/storage/onetouch.c | 9 ++++---- 4 files changed, 63 insertions(+), 45 deletions(-) diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index ad44bd60df98..af849f596135 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -218,7 +218,7 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev, * and reading back and checking the contents are same or not */ if (reg_data != 0xFACE) { - err("scratch register mismatch %x", reg_data); + dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data); goto clean; } diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 2a9bec264ad3..c18d8790c410 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -118,7 +118,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) r8a66597_write(r8a66597, SCKE, SYSCFG0); tmp = r8a66597_read(r8a66597, SYSCFG0); if (i++ > 1000) { - err("register access fail."); + printk(KERN_ERR "r8a66597: register access fail.\n"); return -ENXIO; } } while ((tmp & SCKE) != SCKE); @@ -128,7 +128,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) r8a66597_write(r8a66597, USBE, SYSCFG0); tmp = r8a66597_read(r8a66597, SYSCFG0); if (i++ > 1000) { - err("register access fail."); + printk(KERN_ERR "r8a66597: register access fail.\n"); return -ENXIO; } } while ((tmp & USBE) != USBE); @@ -141,7 +141,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) msleep(1); tmp = r8a66597_read(r8a66597, SYSCFG0); if (i++ > 500) { - err("register access fail."); + printk(KERN_ERR "r8a66597: register access fail.\n"); return -ENXIO; } } while ((tmp & SCKE) != SCKE); @@ -265,7 +265,7 @@ static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port) if (root_port) { *root_port = (devpath[0] & 0x0F) - 1; if (*root_port >= R8A66597_MAX_ROOT_HUB) - err("illegal root port number"); + printk(KERN_ERR "r8a66597: Illegal root port number.\n"); } if (hub_port) *hub_port = devpath[2] & 0x0F; @@ -286,7 +286,7 @@ static u16 get_r8a66597_usb_speed(enum usb_device_speed speed) usbspd = HSMODE; break; default: - err("unknown speed"); + printk(KERN_ERR "r8a66597: unknown speed\n"); break; } @@ -385,7 +385,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb) struct r8a66597_device *dev; if (is_hub_limit(urb->dev->devpath)) { - err("Externel hub limit reached."); + dev_err(&urb->dev->dev, "External hub limit reached.\n"); return 0; } @@ -406,8 +406,9 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb) return addr; } - err("cannot communicate with a USB device more than 10.(%x)", - r8a66597->address_map); + dev_err(&urb->dev->dev, + "cannot communicate with a USB device more than 10.(%x)\n", + r8a66597->address_map); return 0; } @@ -447,7 +448,8 @@ static void r8a66597_reg_wait(struct r8a66597 *r8a66597, unsigned long reg, do { tmp = r8a66597_read(r8a66597, reg); if (i++ > 1000000) { - err("register%lx, loop %x is timeout", reg, loop); + printk(KERN_ERR "r8a66597: register%lx, loop %x " + "is timeout\n", reg, loop); break; } ndelay(1); @@ -675,7 +677,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, array[i++] = 1; break; default: - err("Illegal type"); + printk(KERN_ERR "r8a66597: Illegal type\n"); return 0; } @@ -705,7 +707,7 @@ static u16 get_r8a66597_type(__u8 type) r8a66597_type = R8A66597_ISO; break; default: - err("Illegal type"); + printk(KERN_ERR "r8a66597: Illegal type\n"); r8a66597_type = 0x0000; break; } @@ -724,7 +726,7 @@ static u16 get_bufnum(u16 pipenum) else if (check_interrupt(pipenum)) bufnum = 4 + (pipenum - 6); else - err("Illegal pipenum (%d)", pipenum); + printk(KERN_ERR "r8a66597: Illegal pipenum (%d)\n", pipenum); return bufnum; } @@ -740,7 +742,7 @@ static u16 get_buf_bsize(u16 pipenum) else if (check_interrupt(pipenum)) buf_bsize = 0; else - err("Illegal pipenum (%d)", pipenum); + printk(KERN_ERR "r8a66597: Illegal pipenum (%d)\n", pipenum); return buf_bsize; } @@ -1189,7 +1191,7 @@ static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td) prepare_status_packet(r8a66597, td); break; default: - err("invalid type."); + printk(KERN_ERR "r8a66597: invalid type.\n"); break; } @@ -1297,7 +1299,7 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) if (unlikely((tmp & FRDY) == 0)) { pipe_stop(r8a66597, td->pipe); pipe_irq_disable(r8a66597, pipenum); - err("in fifo not ready (%d)", pipenum); + printk(KERN_ERR "r8a66597: in fifo not ready (%d)\n", pipenum); finish_request(r8a66597, td, pipenum, td->urb, -EPIPE); return; } @@ -1372,7 +1374,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) if (unlikely((tmp & FRDY) == 0)) { pipe_stop(r8a66597, td->pipe); pipe_irq_disable(r8a66597, pipenum); - err("out write fifo not ready. (%d)", pipenum); + printk(KERN_ERR "r8a66597: out fifo not ready (%d)\n", pipenum); finish_request(r8a66597, td, pipenum, urb, -EPIPE); return; } @@ -2007,7 +2009,7 @@ static struct r8a66597_device *get_r8a66597_device(struct r8a66597 *r8a66597, return dev; } - err("get_r8a66597_device fail.(%d)\n", addr); + printk(KERN_ERR "r8a66597: get_r8a66597_device fail.(%d)\n", addr); return NULL; } @@ -2276,7 +2278,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) if (pdev->dev.dma_mask) { ret = -EINVAL; - err("dma not support"); + dev_err(&pdev->dev, "dma not supported\n"); goto clean_up; } @@ -2284,14 +2286,15 @@ static int __init r8a66597_probe(struct platform_device *pdev) (char *)hcd_name); if (!res) { ret = -ENODEV; - err("platform_get_resource_byname error."); + dev_err(&pdev->dev, "platform_get_resource_byname error.\n"); goto clean_up; } ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!ires) { ret = -ENODEV; - err("platform_get_resource IORESOURCE_IRQ error."); + dev_err(&pdev->dev, + "platform_get_resource IORESOURCE_IRQ error.\n"); goto clean_up; } @@ -2301,7 +2304,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) reg = ioremap(res->start, resource_len(res)); if (reg == NULL) { ret = -ENOMEM; - err("ioremap error."); + dev_err(&pdev->dev, "ioremap error.\n"); goto clean_up; } @@ -2309,7 +2312,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) hcd = usb_create_hcd(&r8a66597_hc_driver, &pdev->dev, (char *)hcd_name); if (!hcd) { ret = -ENOMEM; - err("Failed to create hcd"); + dev_err(&pdev->dev, "Failed to create hcd\n"); goto clean_up; } r8a66597 = hcd_to_r8a66597(hcd); @@ -2355,12 +2358,12 @@ static int __init r8a66597_probe(struct platform_device *pdev) } break; default: - err("Unknown irq_sense value."); + dev_err(&pdev->dev, "Unknown irq_sense value.\n"); } ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger); if (ret != 0) { - err("Failed to add hcd"); + dev_err(&pdev->dev, "Failed to add hcd\n"); goto clean_up; } diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index dd432c8feaf8..878c77ca086e 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -355,7 +355,7 @@ static int mdc800_usb_waitForIRQ (int mode, int msec) if (mdc800->camera_request_ready>0) { mdc800->camera_request_ready=0; - err ("timeout waiting for camera."); + dev_err(&mdc800->dev->dev, "timeout waiting for camera.\n"); return -1; } @@ -380,7 +380,8 @@ static void mdc800_usb_write_notify (struct urb *urb) int status = urb->status; if (status != 0) - err ("writing command fails (status=%i)", status); + dev_err(&mdc800->dev->dev, + "writing command fails (status=%i)\n", status); else mdc800->state=READY; mdc800->written = 1; @@ -407,7 +408,8 @@ static void mdc800_usb_download_notify (struct urb *urb) mdc800->state=READY; } } else { - err ("request bytes fails (status:%i)", status); + dev_err(&mdc800->dev->dev, + "request bytes fails (status:%i)\n", status); } mdc800->downloaded = 1; wake_up (&mdc800->download_wait); @@ -450,7 +452,8 @@ static int mdc800_usb_probe (struct usb_interface *intf, if (dev->descriptor.bNumConfigurations != 1) { - err ("probe fails -> wrong Number of Configuration"); + dev_err(&intf->dev, + "probe fails -> wrong Number of Configuration\n"); return -ENODEV; } intf_desc = intf->cur_altsetting; @@ -462,7 +465,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, || ( intf_desc->desc.bNumEndpoints != 4) ) { - err ("probe fails -> wrong Interface"); + dev_err(&intf->dev, "probe fails -> wrong Interface\n"); return -ENODEV; } @@ -483,7 +486,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, } if (mdc800->endpoint[i] == -1) { - err ("probe fails -> Wrong Endpoints."); + dev_err(&intf->dev, "probe fails -> Wrong Endpoints.\n"); return -ENODEV; } } @@ -495,7 +498,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, retval = usb_register_dev(intf, &mdc800_class); if (retval) { - err ("Not able to get a minor for this device."); + dev_err(&intf->dev, "Not able to get a minor for this device.\n"); return -ENODEV; } @@ -645,7 +648,8 @@ static int mdc800_device_open (struct inode* inode, struct file *file) mdc800->irq_urb->dev = mdc800->dev; retval = usb_submit_urb (mdc800->irq_urb, GFP_KERNEL); if (retval) { - err ("request USB irq fails (submit_retval=%i).", retval); + dev_err(&mdc800->dev->dev, + "request USB irq fails (submit_retval=%i).\n", retval); errn = -EIO; goto error_out; } @@ -735,7 +739,9 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l mdc800->download_urb->dev = mdc800->dev; retval = usb_submit_urb (mdc800->download_urb, GFP_KERNEL); if (retval) { - err ("Can't submit download urb (retval=%i)",retval); + dev_err(&mdc800->dev->dev, + "Can't submit download urb " + "(retval=%i)\n", retval); mutex_unlock(&mdc800->io_lock); return len-left; } @@ -744,7 +750,10 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l mdc800->downloaded = 0; if (mdc800->download_urb->status != 0) { - err ("request download-bytes fails (status=%i)",mdc800->download_urb->status); + dev_err(&mdc800->dev->dev, + "request download-bytes fails " + "(status=%i)\n", + mdc800->download_urb->status); mutex_unlock(&mdc800->io_lock); return len-left; } @@ -841,7 +850,8 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s if (mdc800_usb_waitForIRQ (0,TO_GET_READY)) { - err ("Camera didn't get ready.\n"); + dev_err(&mdc800->dev->dev, + "Camera didn't get ready.\n"); mutex_unlock(&mdc800->io_lock); return -EIO; } @@ -853,7 +863,9 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s mdc800->write_urb->dev = mdc800->dev; retval = usb_submit_urb (mdc800->write_urb, GFP_KERNEL); if (retval) { - err ("submitting write urb fails (retval=%i)", retval); + dev_err(&mdc800->dev->dev, + "submitting write urb fails " + "(retval=%i)\n", retval); mutex_unlock(&mdc800->io_lock); return -EIO; } @@ -872,7 +884,9 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s case 0x3e: /* Take shot in Fine Mode (WCam Mode) */ if (mdc800->pic_len < 0) { - err ("call 0x07 before 0x05,0x3e"); + dev_err(&mdc800->dev->dev, + "call 0x07 before " + "0x05,0x3e\n"); mdc800->state=READY; mutex_unlock(&mdc800->io_lock); return -EIO; @@ -892,7 +906,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ)) { - err ("requesting answer from irq fails"); + dev_err(&mdc800->dev->dev, "requesting answer from irq fails\n"); mutex_unlock(&mdc800->io_lock); return -EIO; } @@ -920,7 +934,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s { if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND)) { - err ("Command Timeout."); + dev_err(&mdc800->dev->dev, "Command Timeout.\n"); mutex_unlock(&mdc800->io_lock); return -EIO; } @@ -1031,7 +1045,7 @@ cleanup_on_fail: if (mdc800 != NULL) { - err ("can't alloc memory!"); + printk(KERN_ERR "mdc800: can't alloc memory!\n"); kfree(mdc800->download_urb_buffer); kfree(mdc800->write_urb_buffer); diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 98b89ea9e312..c7bf8954b4e4 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -78,8 +78,8 @@ static void usb_onetouch_irq(struct urb *urb) resubmit: retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) - err ("can't resubmit intr, %s-%s/input0, retval %d", - onetouch->udev->bus->bus_name, + dev_err(&dev->dev, "can't resubmit intr, %s-%s/input0, " + "retval %d\n", onetouch->udev->bus->bus_name, onetouch->udev->devpath, retval); } @@ -90,7 +90,7 @@ static int usb_onetouch_open(struct input_dev *dev) onetouch->is_open = 1; onetouch->irq->dev = onetouch->udev; if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) { - err("usb_submit_urb failed"); + dev_err(&dev->dev, "usb_submit_urb failed\n"); return -EIO; } @@ -117,7 +117,8 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action) break; case US_RESUME: if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0) - err("usb_submit_urb failed"); + dev_err(&onetouch->irq->dev->dev, + "usb_submit_urb failed\n"); break; default: break; -- cgit v1.2.3