Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (23 commits) ehci-fsl: add PPC_MPC837x to default y USB: POWERPC: ehci: fix ppc build USB: usb-storage: don't access beyond the end of the sg buffer USB: quirks and unusual_devs entry for Actions flash drive USB: usb-storage: unusual_devs entry for Oracom MP3 player USB: serial: move zte MF330 from sierra to option USB: add new vernier product id to ldusb.c USB: gadget: queue usb USB_CDC_GET_ENCAPSULATED_RESPONSE message USB: Add another Novatel U727 ID to the device table for usbserial USB: storage: Nikon D80 new FW still needs Fixup USB: usb-storage: don't clear-halt when Get-Max-LUN stalls USB: option: Added vendor id for Dell 5720 broadband modem USB: option: Add Kyocera KPC680 ids USB: quirks for known quirky audio devices USB: fix previous sparse fix which was incorrect USB: fix error handling in trancevibrator USB: g_printer, fix empty if statement USB: ehci-fsl: mpc834x config symbol is PPC_MPC834x, not MPC834x USB: fix usb open suspend race in cdc-acm USB: usb: yet another Dell wireless CDMA/EVDO modem ...
This commit is contained in:
Коммит
c6b0834668
|
@ -496,13 +496,10 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
|
||||||
otherwise it is scheduled, and with high data rates data can get lost. */
|
otherwise it is scheduled, and with high data rates data can get lost. */
|
||||||
tty->low_latency = 1;
|
tty->low_latency = 1;
|
||||||
|
|
||||||
if (usb_autopm_get_interface(acm->control)) {
|
if (usb_autopm_get_interface(acm->control) < 0)
|
||||||
mutex_unlock(&open_mutex);
|
goto early_bail;
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&acm->mutex);
|
mutex_lock(&acm->mutex);
|
||||||
mutex_unlock(&open_mutex);
|
|
||||||
if (acm->used++) {
|
if (acm->used++) {
|
||||||
usb_autopm_put_interface(acm->control);
|
usb_autopm_put_interface(acm->control);
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -536,6 +533,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
|
||||||
done:
|
done:
|
||||||
err_out:
|
err_out:
|
||||||
mutex_unlock(&acm->mutex);
|
mutex_unlock(&acm->mutex);
|
||||||
|
mutex_unlock(&open_mutex);
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
full_bailout:
|
full_bailout:
|
||||||
|
@ -544,6 +542,8 @@ bail_out:
|
||||||
usb_autopm_put_interface(acm->control);
|
usb_autopm_put_interface(acm->control);
|
||||||
acm->used--;
|
acm->used--;
|
||||||
mutex_unlock(&acm->mutex);
|
mutex_unlock(&acm->mutex);
|
||||||
|
early_bail:
|
||||||
|
mutex_unlock(&open_mutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -428,6 +428,7 @@ static int usblp_open(struct inode *inode, struct file *file)
|
||||||
usblp->rcomplete = 0;
|
usblp->rcomplete = 0;
|
||||||
|
|
||||||
if (handle_bidir(usblp) < 0) {
|
if (handle_bidir(usblp) < 0) {
|
||||||
|
usb_autopm_put_interface(intf);
|
||||||
usblp->used = 0;
|
usblp->used = 0;
|
||||||
file->private_data = NULL;
|
file->private_data = NULL;
|
||||||
retval = -EIO;
|
retval = -EIO;
|
||||||
|
|
|
@ -28,11 +28,23 @@
|
||||||
* devices is broken...
|
* devices is broken...
|
||||||
*/
|
*/
|
||||||
static const struct usb_device_id usb_quirk_list[] = {
|
static const struct usb_device_id usb_quirk_list[] = {
|
||||||
|
/* Action Semiconductor flash disk */
|
||||||
|
{ USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255},
|
||||||
|
|
||||||
/* CBM - Flash disk */
|
/* CBM - Flash disk */
|
||||||
{ USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME },
|
{ USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||||
/* HP 5300/5370C scanner */
|
/* HP 5300/5370C scanner */
|
||||||
{ USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
|
{ USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
|
||||||
|
|
||||||
|
/* Creative SB Audigy 2 NX */
|
||||||
|
{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||||
|
|
||||||
|
/* Roland SC-8820 */
|
||||||
|
{ USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||||
|
|
||||||
|
/* Edirol SD-20 */
|
||||||
|
{ USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||||
|
|
||||||
/* INTEL VALUE SSD */
|
/* INTEL VALUE SSD */
|
||||||
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
|
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||||
|
|
||||||
|
|
|
@ -1561,6 +1561,7 @@ done_set_intf:
|
||||||
memcpy(req->buf, buf, n);
|
memcpy(req->buf, buf, n);
|
||||||
req->complete = rndis_response_complete;
|
req->complete = rndis_response_complete;
|
||||||
rndis_free_response(dev->rndis_config, buf);
|
rndis_free_response(dev->rndis_config, buf);
|
||||||
|
value = n;
|
||||||
}
|
}
|
||||||
/* else stalls ... spec says to avoid that */
|
/* else stalls ... spec says to avoid that */
|
||||||
}
|
}
|
||||||
|
|
|
@ -1299,7 +1299,7 @@ printer_unbind(struct usb_gadget *gadget)
|
||||||
printer_req_free(dev->in_ep, req);
|
printer_req_free(dev->in_ep, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->current_rx_req != NULL);
|
if (dev->current_rx_req != NULL)
|
||||||
printer_req_free(dev->out_ep, dev->current_rx_req);
|
printer_req_free(dev->out_ep, dev->current_rx_req);
|
||||||
|
|
||||||
while (!list_empty(&dev->rx_reqs)) {
|
while (!list_empty(&dev->rx_reqs)) {
|
||||||
|
|
|
@ -69,10 +69,9 @@ config USB_EHCI_BIG_ENDIAN_DESC
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config USB_EHCI_FSL
|
config USB_EHCI_FSL
|
||||||
bool
|
bool "Support for Freescale on-chip EHCI USB controller"
|
||||||
depends on USB_EHCI_HCD
|
depends on USB_EHCI_HCD && FSL_SOC
|
||||||
select USB_EHCI_ROOT_HUB_TT
|
select USB_EHCI_ROOT_HUB_TT
|
||||||
default y if MPC834x || PPC_MPC831x
|
|
||||||
---help---
|
---help---
|
||||||
Variation of ARC USB block used in some Freescale chips.
|
Variation of ARC USB block used in some Freescale chips.
|
||||||
|
|
||||||
|
|
|
@ -862,18 +862,18 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
||||||
/* reschedule QH iff another request is queued */
|
/* reschedule QH iff another request is queued */
|
||||||
if (!list_empty (&qh->qtd_list)
|
if (!list_empty (&qh->qtd_list)
|
||||||
&& HC_IS_RUNNING (hcd->state)) {
|
&& HC_IS_RUNNING (hcd->state)) {
|
||||||
int schedule_status;
|
rc = qh_schedule(ehci, qh);
|
||||||
|
|
||||||
schedule_status = qh_schedule (ehci, qh);
|
/* An error here likely indicates handshake failure
|
||||||
spin_unlock_irqrestore (&ehci->lock, flags);
|
* or no space left in the schedule. Neither fault
|
||||||
|
* should happen often ...
|
||||||
if (schedule_status != 0) {
|
*
|
||||||
// shouldn't happen often, but ...
|
* FIXME kill the now-dysfunctional queued urbs
|
||||||
// FIXME kill those tds' urbs
|
*/
|
||||||
err ("can't reschedule qh %p, err %d",
|
if (rc != 0)
|
||||||
qh, schedule_status);
|
ehci_err(ehci,
|
||||||
}
|
"can't reschedule qh %p, err %d",
|
||||||
return status;
|
qh, rc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1014,7 +1014,7 @@ MODULE_LICENSE ("GPL");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
|
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
|
||||||
!defined(PS3_SYSTEM_BUS_DRIVER)
|
!defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
|
||||||
#error "missing bus glue for ehci-hcd"
|
#error "missing bus glue for ehci-hcd"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
|
#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
|
||||||
#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
|
#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
|
||||||
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
|
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
|
||||||
|
#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006
|
||||||
|
|
||||||
#define USB_VENDOR_ID_MICROCHIP 0x04d8
|
#define USB_VENDOR_ID_MICROCHIP 0x04d8
|
||||||
#define USB_DEVICE_ID_PICDEM 0x000c
|
#define USB_DEVICE_ID_PICDEM 0x000c
|
||||||
|
@ -92,6 +93,7 @@ static struct usb_device_id ld_usb_table [] = {
|
||||||
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
|
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
|
||||||
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
|
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
|
||||||
{ USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) },
|
{ USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) },
|
||||||
|
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) },
|
||||||
{ } /* Terminating entry */
|
{ } /* Terminating entry */
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(usb, ld_usb_table);
|
MODULE_DEVICE_TABLE(usb, ld_usb_table);
|
||||||
|
|
|
@ -59,13 +59,14 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr,
|
||||||
{
|
{
|
||||||
struct usb_interface *intf = to_usb_interface(dev);
|
struct usb_interface *intf = to_usb_interface(dev);
|
||||||
struct trancevibrator *tv = usb_get_intfdata(intf);
|
struct trancevibrator *tv = usb_get_intfdata(intf);
|
||||||
int temp, retval;
|
int temp, retval, old;
|
||||||
|
|
||||||
temp = simple_strtoul(buf, NULL, 10);
|
temp = simple_strtoul(buf, NULL, 10);
|
||||||
if (temp > 255)
|
if (temp > 255)
|
||||||
temp = 255;
|
temp = 255;
|
||||||
else if (temp < 0)
|
else if (temp < 0)
|
||||||
temp = 0;
|
temp = 0;
|
||||||
|
old = tv->speed;
|
||||||
tv->speed = temp;
|
tv->speed = temp;
|
||||||
|
|
||||||
dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed);
|
dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed);
|
||||||
|
@ -77,6 +78,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr,
|
||||||
tv->speed, /* speed value */
|
tv->speed, /* speed value */
|
||||||
0, NULL, 0, USB_CTRL_GET_TIMEOUT);
|
0, NULL, 0, USB_CTRL_GET_TIMEOUT);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
|
tv->speed = old;
|
||||||
dev_dbg(&tv->udev->dev, "retval = %d\n", retval);
|
dev_dbg(&tv->udev->dev, "retval = %d\n", retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -393,8 +393,8 @@ static const char *ftdi_chip_name[] = {
|
||||||
#define FTDI_STATUS_B1_MASK (FTDI_RS_BI)
|
#define FTDI_STATUS_B1_MASK (FTDI_RS_BI)
|
||||||
/* End TIOCMIWAIT */
|
/* End TIOCMIWAIT */
|
||||||
|
|
||||||
#define FTDI_IMPL_ASYNC_FLAGS = ( ASYNC_SPD_HI | ASYNC_SPD_VHI \
|
#define FTDI_IMPL_ASYNC_FLAGS = (ASYNC_SPD_HI | ASYNC_SPD_VHI \
|
||||||
ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP )
|
| ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP)
|
||||||
|
|
||||||
/* function prototypes for a FTDI serial converter */
|
/* function prototypes for a FTDI serial converter */
|
||||||
static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id);
|
static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id);
|
||||||
|
|
|
@ -113,6 +113,9 @@ static int option_send_setup(struct usb_serial_port *port);
|
||||||
#define NOVATELWIRELESS_VENDOR_ID 0x1410
|
#define NOVATELWIRELESS_VENDOR_ID 0x1410
|
||||||
#define DELL_VENDOR_ID 0x413C
|
#define DELL_VENDOR_ID 0x413C
|
||||||
|
|
||||||
|
#define KYOCERA_VENDOR_ID 0x0c88
|
||||||
|
#define KYOCERA_PRODUCT_KPC680 0x180a
|
||||||
|
|
||||||
#define ANYDATA_VENDOR_ID 0x16d5
|
#define ANYDATA_VENDOR_ID 0x16d5
|
||||||
#define ANYDATA_PRODUCT_ADU_E100A 0x6501
|
#define ANYDATA_PRODUCT_ADU_E100A 0x6501
|
||||||
#define ANYDATA_PRODUCT_ADU_500A 0x6502
|
#define ANYDATA_PRODUCT_ADU_500A 0x6502
|
||||||
|
@ -121,6 +124,8 @@ static int option_send_setup(struct usb_serial_port *port);
|
||||||
#define BANDRICH_PRODUCT_C100_1 0x1002
|
#define BANDRICH_PRODUCT_C100_1 0x1002
|
||||||
#define BANDRICH_PRODUCT_C100_2 0x1003
|
#define BANDRICH_PRODUCT_C100_2 0x1003
|
||||||
|
|
||||||
|
#define QUALCOMM_VENDOR_ID 0x05C6
|
||||||
|
|
||||||
static struct usb_device_id option_ids[] = {
|
static struct usb_device_id option_ids[] = {
|
||||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
||||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
|
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
|
||||||
|
@ -174,18 +179,23 @@ static struct usb_device_id option_ids[] = {
|
||||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
|
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
|
||||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */
|
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */
|
||||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */
|
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */
|
||||||
|
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x5010) }, /* Novatel U727 */
|
||||||
{ USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
|
{ USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
|
||||||
{ USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
|
{ USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
|
||||||
{ USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
|
{ USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
|
||||||
{ USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
|
{ USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
|
||||||
{ USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
|
{ USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
|
||||||
{ USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
|
{ USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
|
||||||
|
{ USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */
|
||||||
|
{ USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
|
||||||
{ USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
|
{ 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, 0x8137) }, /* Dell Wireless HSDPA 5520 */
|
||||||
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
|
{ 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_500A) },
|
||||||
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
|
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
|
||||||
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
|
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
|
||||||
|
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
|
||||||
|
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
|
||||||
{ } /* Terminating entry */
|
{ } /* Terminating entry */
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||||
|
@ -247,10 +257,10 @@ static int debug;
|
||||||
struct option_port_private {
|
struct option_port_private {
|
||||||
/* Input endpoints and buffer for this port */
|
/* Input endpoints and buffer for this port */
|
||||||
struct urb *in_urbs[N_IN_URB];
|
struct urb *in_urbs[N_IN_URB];
|
||||||
char in_buffer[N_IN_URB][IN_BUFLEN];
|
u8 *in_buffer[N_IN_URB];
|
||||||
/* Output endpoints and buffer for this port */
|
/* Output endpoints and buffer for this port */
|
||||||
struct urb *out_urbs[N_OUT_URB];
|
struct urb *out_urbs[N_OUT_URB];
|
||||||
char out_buffer[N_OUT_URB][OUT_BUFLEN];
|
u8 *out_buffer[N_OUT_URB];
|
||||||
unsigned long out_busy; /* Bit vector of URBs in use */
|
unsigned long out_busy; /* Bit vector of URBs in use */
|
||||||
|
|
||||||
/* Settings for the port */
|
/* Settings for the port */
|
||||||
|
@ -737,9 +747,10 @@ static int option_send_setup(struct usb_serial_port *port)
|
||||||
|
|
||||||
static int option_startup(struct usb_serial *serial)
|
static int option_startup(struct usb_serial *serial)
|
||||||
{
|
{
|
||||||
int i, err;
|
int i, j, err;
|
||||||
struct usb_serial_port *port;
|
struct usb_serial_port *port;
|
||||||
struct option_port_private *portdata;
|
struct option_port_private *portdata;
|
||||||
|
u8 *buffer;
|
||||||
|
|
||||||
dbg("%s", __FUNCTION__);
|
dbg("%s", __FUNCTION__);
|
||||||
|
|
||||||
|
@ -753,6 +764,20 @@ static int option_startup(struct usb_serial *serial)
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < N_IN_URB; j++) {
|
||||||
|
buffer = (u8 *)__get_free_page(GFP_KERNEL);
|
||||||
|
if (!buffer)
|
||||||
|
goto bail_out_error;
|
||||||
|
portdata->in_buffer[j] = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < N_OUT_URB; j++) {
|
||||||
|
buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
|
||||||
|
if (!buffer)
|
||||||
|
goto bail_out_error2;
|
||||||
|
portdata->out_buffer[j] = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
usb_set_serial_port_data(port, portdata);
|
usb_set_serial_port_data(port, portdata);
|
||||||
|
|
||||||
if (! port->interrupt_in_urb)
|
if (! port->interrupt_in_urb)
|
||||||
|
@ -766,6 +791,16 @@ static int option_startup(struct usb_serial *serial)
|
||||||
option_setup_urbs(serial);
|
option_setup_urbs(serial);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
bail_out_error2:
|
||||||
|
for (j = 0; j < N_OUT_URB; j++)
|
||||||
|
kfree(portdata->out_buffer[j]);
|
||||||
|
bail_out_error:
|
||||||
|
for (j = 0; j < N_IN_URB; j++)
|
||||||
|
if (portdata->in_buffer[j])
|
||||||
|
free_page((unsigned long)portdata->in_buffer[j]);
|
||||||
|
kfree(portdata);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void option_shutdown(struct usb_serial *serial)
|
static void option_shutdown(struct usb_serial *serial)
|
||||||
|
@ -794,12 +829,14 @@ static void option_shutdown(struct usb_serial *serial)
|
||||||
for (j = 0; j < N_IN_URB; j++) {
|
for (j = 0; j < N_IN_URB; j++) {
|
||||||
if (portdata->in_urbs[j]) {
|
if (portdata->in_urbs[j]) {
|
||||||
usb_free_urb(portdata->in_urbs[j]);
|
usb_free_urb(portdata->in_urbs[j]);
|
||||||
|
free_page((unsigned long)portdata->in_buffer[j]);
|
||||||
portdata->in_urbs[j] = NULL;
|
portdata->in_urbs[j] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (j = 0; j < N_OUT_URB; j++) {
|
for (j = 0; j < N_OUT_URB; j++) {
|
||||||
if (portdata->out_urbs[j]) {
|
if (portdata->out_urbs[j]) {
|
||||||
usb_free_urb(portdata->out_urbs[j]);
|
usb_free_urb(portdata->out_urbs[j]);
|
||||||
|
kfree(portdata->out_buffer[j]);
|
||||||
portdata->out_urbs[j] = NULL;
|
portdata->out_urbs[j] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,6 @@ static struct usb_device_id id_table [] = {
|
||||||
|
|
||||||
{ USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */
|
{ USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */
|
||||||
{ USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */
|
{ USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */
|
||||||
{ USB_DEVICE(0x05C6, 0x6613), .driver_info = DEVICE_1_PORT }, /* Onda H600/ZTE MF330 */
|
|
||||||
|
|
||||||
{ USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
|
{ USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -150,13 +150,14 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
|
||||||
|
|
||||||
/* Copy a buffer of length buflen to/from the srb's transfer buffer.
|
/* Copy a buffer of length buflen to/from the srb's transfer buffer.
|
||||||
* Update the **sgptr and *offset variables so that the next copy will
|
* Update the **sgptr and *offset variables so that the next copy will
|
||||||
* pick up from where this one left off. */
|
* pick up from where this one left off.
|
||||||
|
*/
|
||||||
unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
|
unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
|
||||||
unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
|
unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
|
||||||
unsigned int *offset, enum xfer_buf_dir dir)
|
unsigned int *offset, enum xfer_buf_dir dir)
|
||||||
{
|
{
|
||||||
unsigned int cnt;
|
unsigned int cnt;
|
||||||
|
struct scatterlist *sg = *sgptr;
|
||||||
|
|
||||||
/* We have to go through the list one entry
|
/* We have to go through the list one entry
|
||||||
* at a time. Each s-g entry contains some number of pages, and
|
* at a time. Each s-g entry contains some number of pages, and
|
||||||
|
@ -164,22 +165,23 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
|
||||||
* in kernel-addressable memory then kmap() will return its address.
|
* in kernel-addressable memory then kmap() will return its address.
|
||||||
* If the page is not directly accessible -- such as a user buffer
|
* If the page is not directly accessible -- such as a user buffer
|
||||||
* located in high memory -- then kmap() will map it to a temporary
|
* located in high memory -- then kmap() will map it to a temporary
|
||||||
* position in the kernel's virtual address space. */
|
* position in the kernel's virtual address space.
|
||||||
struct scatterlist *sg = *sgptr;
|
*/
|
||||||
|
|
||||||
if (!sg)
|
if (!sg)
|
||||||
sg = scsi_sglist(srb);
|
sg = scsi_sglist(srb);
|
||||||
|
buflen = min(buflen, scsi_bufflen(srb));
|
||||||
|
|
||||||
/* This loop handles a single s-g list entry, which may
|
/* This loop handles a single s-g list entry, which may
|
||||||
* include multiple pages. Find the initial page structure
|
* include multiple pages. Find the initial page structure
|
||||||
* and the starting offset within the page, and update
|
* and the starting offset within the page, and update
|
||||||
* the *offset and **sgptr values for the next loop. */
|
* the *offset and **sgptr values for the next loop.
|
||||||
|
*/
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
while (cnt < buflen) {
|
while (cnt < buflen && sg) {
|
||||||
struct page *page = sg_page(sg) +
|
struct page *page = sg_page(sg) +
|
||||||
((sg->offset + *offset) >> PAGE_SHIFT);
|
((sg->offset + *offset) >> PAGE_SHIFT);
|
||||||
unsigned int poff =
|
unsigned int poff = (sg->offset + *offset) & (PAGE_SIZE-1);
|
||||||
(sg->offset + *offset) & (PAGE_SIZE-1);
|
|
||||||
unsigned int sglen = sg->length - *offset;
|
unsigned int sglen = sg->length - *offset;
|
||||||
|
|
||||||
if (sglen > buflen - cnt) {
|
if (sglen > buflen - cnt) {
|
||||||
|
@ -222,14 +224,15 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the contents of buffer into srb's transfer buffer and set the
|
/* Store the contents of buffer into srb's transfer buffer and set the
|
||||||
* SCSI residue. */
|
* SCSI residue.
|
||||||
|
*/
|
||||||
void usb_stor_set_xfer_buf(unsigned char *buffer,
|
void usb_stor_set_xfer_buf(unsigned char *buffer,
|
||||||
unsigned int buflen, struct scsi_cmnd *srb)
|
unsigned int buflen, struct scsi_cmnd *srb)
|
||||||
{
|
{
|
||||||
unsigned int offset = 0;
|
unsigned int offset = 0;
|
||||||
struct scatterlist *sg = NULL;
|
struct scatterlist *sg = NULL;
|
||||||
|
|
||||||
usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
|
buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
|
||||||
TO_XFER_BUF);
|
TO_XFER_BUF);
|
||||||
if (buflen < scsi_bufflen(srb))
|
if (buflen < scsi_bufflen(srb))
|
||||||
scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
|
scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
|
||||||
|
|
|
@ -891,17 +891,6 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
|
||||||
if (result > 0)
|
if (result > 0)
|
||||||
return us->iobuf[0];
|
return us->iobuf[0];
|
||||||
|
|
||||||
/*
|
|
||||||
* Some devices (i.e. Iomega Zip100) need this -- apparently
|
|
||||||
* the bulk pipes get STALLed when the GetMaxLUN request is
|
|
||||||
* processed. This is, in theory, harmless to all other devices
|
|
||||||
* (regardless of if they stall or not).
|
|
||||||
*/
|
|
||||||
if (result == -EPIPE) {
|
|
||||||
usb_stor_clear_halt(us, us->recv_bulk_pipe);
|
|
||||||
usb_stor_clear_halt(us, us->send_bulk_pipe);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some devices don't like GetMaxLUN. They may STALL the control
|
* Some devices don't like GetMaxLUN. They may STALL the control
|
||||||
* pipe, they may return a zero-length result, they may do nothing at
|
* pipe, they may return a zero-length result, they may do nothing at
|
||||||
|
|
|
@ -357,7 +357,7 @@ UNUSUAL_DEV( 0x04b0, 0x040f, 0x0100, 0x0200,
|
||||||
US_FL_FIX_CAPACITY),
|
US_FL_FIX_CAPACITY),
|
||||||
|
|
||||||
/* Reported by Emil Larsson <emil@swip.net> */
|
/* Reported by Emil Larsson <emil@swip.net> */
|
||||||
UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101,
|
UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0110,
|
||||||
"NIKON",
|
"NIKON",
|
||||||
"NIKON DSC D80",
|
"NIKON DSC D80",
|
||||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||||
|
@ -759,6 +759,18 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210,
|
||||||
"Digital Camera EX-20 DSC",
|
"Digital Camera EX-20 DSC",
|
||||||
US_SC_8070, US_PR_DEVICE, NULL, 0 ),
|
US_SC_8070, US_PR_DEVICE, NULL, 0 ),
|
||||||
|
|
||||||
|
/* Reported by Andre Welter <a.r.welter@gmx.de>
|
||||||
|
* This antique device predates the release of the Bulk-only Transport
|
||||||
|
* spec, and if it gets a Get-Max-LUN then it requires the host to do a
|
||||||
|
* Clear-Halt on the bulk endpoints. The SINGLE_LUN flag will prevent
|
||||||
|
* us from sending the request.
|
||||||
|
*/
|
||||||
|
UNUSUAL_DEV( 0x059b, 0x0001, 0x0100, 0x0100,
|
||||||
|
"Iomega",
|
||||||
|
"ZIP 100",
|
||||||
|
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||||
|
US_FL_SINGLE_LUN ),
|
||||||
|
|
||||||
/* Reported by <Hendryk.Pfeiffer@gmx.de> */
|
/* Reported by <Hendryk.Pfeiffer@gmx.de> */
|
||||||
UNUSUAL_DEV( 0x059f, 0x0643, 0x0000, 0x0000,
|
UNUSUAL_DEV( 0x059f, 0x0643, 0x0000, 0x0000,
|
||||||
"LaCie",
|
"LaCie",
|
||||||
|
@ -1412,6 +1424,17 @@ UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103,
|
||||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||||
US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64),
|
US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64),
|
||||||
|
|
||||||
|
/* Patch by Leonid Petrov mail at lpetrov.net
|
||||||
|
* Reported by Robert Spitzenpfeil <robert@spitzenpfeil.org>
|
||||||
|
* http://www.qbik.ch/usb/devices/showdev.php?id=1705
|
||||||
|
* Updated to 103 device by MJ Ray mjr at phonecoop.coop
|
||||||
|
*/
|
||||||
|
UNUSUAL_DEV( 0x0f19, 0x0103, 0x0100, 0x0100,
|
||||||
|
"Oracom Co., Ltd",
|
||||||
|
"ORC-200M",
|
||||||
|
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||||
|
US_FL_IGNORE_RESIDUE ),
|
||||||
|
|
||||||
/* David Kuehling <dvdkhlng@gmx.de>:
|
/* David Kuehling <dvdkhlng@gmx.de>:
|
||||||
* for MP3-Player AVOX WSX-300ER (bought in Japan). Reports lots of SCSI
|
* for MP3-Player AVOX WSX-300ER (bought in Japan). Reports lots of SCSI
|
||||||
* errors when trying to write.
|
* errors when trying to write.
|
||||||
|
@ -1477,6 +1500,15 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110,
|
||||||
US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
|
US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
|
||||||
0 ),
|
0 ),
|
||||||
|
|
||||||
|
/* Reported by Fabio Venturi <f.venturi@tdnet.it>
|
||||||
|
* The device reports a vendor-specific bDeviceClass.
|
||||||
|
*/
|
||||||
|
UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100,
|
||||||
|
"Actions Semiconductor",
|
||||||
|
"Mtp device",
|
||||||
|
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||||
|
0),
|
||||||
|
|
||||||
/* Reported by Kevin Lloyd <linux@sierrawireless.com>
|
/* Reported by Kevin Lloyd <linux@sierrawireless.com>
|
||||||
* Entry is needed for the initializer function override,
|
* Entry is needed for the initializer function override,
|
||||||
* which instructs the device to load as a modem
|
* which instructs the device to load as a modem
|
||||||
|
|
Загрузка…
Ссылка в новой задаче