diff options
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r-- | drivers/usb/serial/option.c | 216 |
1 files changed, 116 insertions, 100 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a73420dd052..73f8277f88f 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -43,29 +43,25 @@ #include <linux/usb/serial.h> /* Function prototypes */ -static int option_open(struct usb_serial_port *port, struct file *filp); -static void option_close(struct usb_serial_port *port, struct file *filp); +static int option_open(struct tty_struct *tty, struct usb_serial_port *port, + struct file *filp); +static void option_close(struct tty_struct *tty, struct usb_serial_port *port, + struct file *filp); static int option_startup(struct usb_serial *serial); static void option_shutdown(struct usb_serial *serial); -static void option_rx_throttle(struct usb_serial_port *port); -static void option_rx_unthrottle(struct usb_serial_port *port); -static int option_write_room(struct usb_serial_port *port); +static int option_write_room(struct tty_struct *tty); static void option_instat_callback(struct urb *urb); -static int option_write(struct usb_serial_port *port, +static int option_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); - -static int option_chars_in_buffer(struct usb_serial_port *port); -static int option_ioctl(struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg); -static void option_set_termios(struct usb_serial_port *port, - struct ktermios *old); -static void option_break_ctl(struct usb_serial_port *port, int break_state); -static int option_tiocmget(struct usb_serial_port *port, struct file *file); -static int option_tiocmset(struct usb_serial_port *port, struct file *file, +static int option_chars_in_buffer(struct tty_struct *tty); +static void option_set_termios(struct tty_struct *tty, + struct usb_serial_port *port, struct ktermios *old); +static int option_tiocmget(struct tty_struct *tty, struct file *file); +static int option_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); -static int option_send_setup(struct usb_serial_port *port); +static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port); /* Vendor and product IDs */ #define OPTION_VENDOR_ID 0x0AF0 @@ -173,9 +169,11 @@ static int option_send_setup(struct usb_serial_port *port); #define DELL_VENDOR_ID 0x413C #define KYOCERA_VENDOR_ID 0x0c88 +#define KYOCERA_PRODUCT_KPC650 0x17da #define KYOCERA_PRODUCT_KPC680 0x180a #define ANYDATA_VENDOR_ID 0x16d5 +#define ANYDATA_PRODUCT_ADU_620UW 0x6202 #define ANYDATA_PRODUCT_ADU_E100A 0x6501 #define ANYDATA_PRODUCT_ADU_500A 0x6502 @@ -189,6 +187,23 @@ static int option_send_setup(struct usb_serial_port *port); #define BANDRICH_VENDOR_ID 0x1A8D #define BANDRICH_PRODUCT_C100_1 0x1002 #define BANDRICH_PRODUCT_C100_2 0x1003 +#define BANDRICH_PRODUCT_1004 0x1004 +#define BANDRICH_PRODUCT_1005 0x1005 +#define BANDRICH_PRODUCT_1006 0x1006 +#define BANDRICH_PRODUCT_1007 0x1007 +#define BANDRICH_PRODUCT_1008 0x1008 +#define BANDRICH_PRODUCT_1009 0x1009 +#define BANDRICH_PRODUCT_100A 0x100a + +#define BANDRICH_PRODUCT_100B 0x100b +#define BANDRICH_PRODUCT_100C 0x100c +#define BANDRICH_PRODUCT_100D 0x100d +#define BANDRICH_PRODUCT_100E 0x100e + +#define BANDRICH_PRODUCT_100F 0x100f +#define BANDRICH_PRODUCT_1010 0x1010 +#define BANDRICH_PRODUCT_1011 0x1011 +#define BANDRICH_PRODUCT_1012 0x1012 #define AMOI_VENDOR_ID 0x1614 #define AMOI_PRODUCT_9508 0x0800 @@ -200,6 +215,11 @@ static int option_send_setup(struct usb_serial_port *port); #define TELIT_VENDOR_ID 0x1bc7 #define TELIT_PRODUCT_UC864E 0x1003 +/* ZTE PRODUCTS */ +#define ZTE_VENDOR_ID 0x19d2 +#define ZTE_PRODUCT_MF628 0x0015 +#define ZTE_PRODUCT_CDMA_TECH 0xfffe + static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -300,16 +320,35 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ { 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) }, { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) }, { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) }, { 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_1004) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1005) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1006) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1007) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1008) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1009) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100A) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100B) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100C) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100D) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100E) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100F) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1010) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1011) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012) }, + { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ { 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) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); @@ -340,11 +379,7 @@ static struct usb_serial_driver option_1port_device = { .write = option_write, .write_room = option_write_room, .chars_in_buffer = option_chars_in_buffer, - .throttle = option_rx_throttle, - .unthrottle = option_rx_unthrottle, - .ioctl = option_ioctl, .set_termios = option_set_termios, - .break_ctl = option_break_ctl, .tiocmget = option_tiocmget, .tiocmset = option_tiocmset, .attach = option_startup, @@ -352,11 +387,7 @@ static struct usb_serial_driver option_1port_device = { .read_int_callback = option_instat_callback, }; -#ifdef CONFIG_USB_DEBUG static int debug; -#else -#define debug 0 -#endif /* per port private data */ @@ -401,47 +432,32 @@ static int __init option_init(void) return 0; failed_driver_register: - usb_serial_deregister (&option_1port_device); + usb_serial_deregister(&option_1port_device); failed_1port_device_register: return retval; } static void __exit option_exit(void) { - usb_deregister (&option_driver); - usb_serial_deregister (&option_1port_device); + usb_deregister(&option_driver); + usb_serial_deregister(&option_1port_device); } module_init(option_init); module_exit(option_exit); -static void option_rx_throttle(struct usb_serial_port *port) -{ - dbg("%s", __func__); -} - -static void option_rx_unthrottle(struct usb_serial_port *port) -{ - dbg("%s", __func__); -} - -static void option_break_ctl(struct usb_serial_port *port, int break_state) -{ - /* Unfortunately, I don't know how to send a break */ - dbg("%s", __func__); -} - -static void option_set_termios(struct usb_serial_port *port, - struct ktermios *old_termios) +static void option_set_termios(struct tty_struct *tty, + struct usb_serial_port *port, struct ktermios *old_termios) { dbg("%s", __func__); /* Doesn't support option setting */ - tty_termios_copy_hw(port->tty->termios, old_termios); - option_send_setup(port); + tty_termios_copy_hw(tty->termios, old_termios); + option_send_setup(tty, port); } -static int option_tiocmget(struct usb_serial_port *port, struct file *file) +static int option_tiocmget(struct tty_struct *tty, struct file *file) { + struct usb_serial_port *port = tty->driver_data; unsigned int value; struct option_port_private *portdata; @@ -457,9 +473,10 @@ static int option_tiocmget(struct usb_serial_port *port, struct file *file) return value; } -static int option_tiocmset(struct usb_serial_port *port, struct file *file, +static int option_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear) { + struct usb_serial_port *port = tty->driver_data; struct option_port_private *portdata; portdata = usb_get_serial_port_data(port); @@ -474,17 +491,11 @@ static int option_tiocmset(struct usb_serial_port *port, struct file *file, portdata->rts_state = 0; if (clear & TIOCM_DTR) portdata->dtr_state = 0; - return option_send_setup(port); -} - -static int option_ioctl(struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; + return option_send_setup(tty, port); } /* Write */ -static int option_write(struct usb_serial_port *port, +static int option_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { struct option_port_private *portdata; @@ -499,7 +510,7 @@ static int option_write(struct usb_serial_port *port, i = 0; left = count; - for (i=0; left > 0 && i < N_OUT_URB; i++) { + for (i = 0; left > 0 && i < N_OUT_URB; i++) { todo = left; if (todo > OUT_BUFLEN) todo = OUT_BUFLEN; @@ -520,7 +531,7 @@ static int option_write(struct usb_serial_port *port, usb_pipeendpoint(this_urb->pipe), i); /* send the data */ - memcpy (this_urb->transfer_buffer, buf, todo); + memcpy(this_urb->transfer_buffer, buf, todo); this_urb->transfer_buffer_length = todo; this_urb->dev = port->serial->dev; @@ -560,7 +571,7 @@ static void option_indat_callback(struct urb *urb) dbg("%s: nonzero status: %d on endpoint %02x.", __func__, status, endpoint); } else { - tty = port->tty; + tty = port->port.tty; if (urb->actual_length) { tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); @@ -570,7 +581,7 @@ static void option_indat_callback(struct urb *urb) } /* Resubmit urb so we continue receiving */ - if (port->open_count && status != -ESHUTDOWN) { + if (port->port.count && status != -ESHUTDOWN) { err = usb_submit_urb(urb, GFP_ATOMIC); if (err) printk(KERN_ERR "%s: resubmit read urb failed. " @@ -611,7 +622,7 @@ static void option_instat_callback(struct urb *urb) struct usb_serial *serial = port->serial; dbg("%s", __func__); - dbg("%s: urb %p port %p has data %p", __func__,urb,port,portdata); + dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); if (status == 0) { struct usb_ctrlrequest *req_pkt = @@ -636,12 +647,12 @@ static void option_instat_callback(struct urb *urb) portdata->dsr_state = ((signals & 0x02) ? 1 : 0); portdata->ri_state = ((signals & 0x08) ? 1 : 0); - if (port->tty && !C_CLOCAL(port->tty) && + if (port->port.tty && !C_CLOCAL(port->port.tty) && old_dcd_state && !portdata->dcd_state) - tty_hangup(port->tty); + tty_hangup(port->port.tty); } else { dbg("%s: type %x req %x", __func__, - req_pkt->bRequestType,req_pkt->bRequest); + req_pkt->bRequestType, req_pkt->bRequest); } } else dbg("%s: error %d", __func__, status); @@ -656,8 +667,9 @@ static void option_instat_callback(struct urb *urb) } } -static int option_write_room(struct usb_serial_port *port) +static int option_write_room(struct tty_struct *tty) { + struct usb_serial_port *port = tty->driver_data; struct option_port_private *portdata; int i; int data_len = 0; @@ -666,7 +678,7 @@ static int option_write_room(struct usb_serial_port *port) portdata = usb_get_serial_port_data(port); - for (i=0; i < N_OUT_URB; i++) { + for (i = 0; i < N_OUT_URB; i++) { this_urb = portdata->out_urbs[i]; if (this_urb && !test_bit(i, &portdata->out_busy)) data_len += OUT_BUFLEN; @@ -676,8 +688,9 @@ static int option_write_room(struct usb_serial_port *port) return data_len; } -static int option_chars_in_buffer(struct usb_serial_port *port) +static int option_chars_in_buffer(struct tty_struct *tty) { + struct usb_serial_port *port = tty->driver_data; struct option_port_private *portdata; int i; int data_len = 0; @@ -685,7 +698,7 @@ static int option_chars_in_buffer(struct usb_serial_port *port) portdata = usb_get_serial_port_data(port); - for (i=0; i < N_OUT_URB; i++) { + for (i = 0; i < N_OUT_URB; i++) { this_urb = portdata->out_urbs[i]; /* FIXME: This locking is insufficient as this_urb may go unused during the test */ @@ -696,7 +709,8 @@ static int option_chars_in_buffer(struct usb_serial_port *port) return data_len; } -static int option_open(struct usb_serial_port *port, struct file *filp) +static int option_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp) { struct option_port_private *portdata; struct usb_serial *serial = port->serial; @@ -714,7 +728,7 @@ static int option_open(struct usb_serial_port *port, struct file *filp) /* Reset low level data toggle and start reading from endpoints */ for (i = 0; i < N_IN_URB; i++) { urb = portdata->in_urbs[i]; - if (! urb) + if (!urb) continue; if (urb->dev != serial->dev) { dbg("%s: dev %p != %p", __func__, @@ -739,21 +753,23 @@ static int option_open(struct usb_serial_port *port, struct file *filp) /* Reset low level data toggle on out endpoints */ for (i = 0; i < N_OUT_URB; i++) { urb = portdata->out_urbs[i]; - if (! urb) + if (!urb) continue; urb->dev = serial->dev; /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */ } - port->tty->low_latency = 1; + if (tty) + tty->low_latency = 1; - option_send_setup(port); + option_send_setup(tty, port); - return (0); + return 0; } -static void option_close(struct usb_serial_port *port, struct file *filp) +static void option_close(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp) { int i; struct usb_serial *serial = port->serial; @@ -768,7 +784,7 @@ static void option_close(struct usb_serial_port *port, struct file *filp) if (serial->dev) { mutex_lock(&serial->disc_mutex); if (!serial->disconnected) - option_send_setup(port); + option_send_setup(tty, port); mutex_unlock(&serial->disc_mutex); /* Stop reading/writing urbs */ @@ -777,7 +793,7 @@ static void option_close(struct usb_serial_port *port, struct file *filp) for (i = 0; i < N_OUT_URB; i++) usb_kill_urb(portdata->out_urbs[i]); } - port->tty = NULL; + port->port.tty = NULL; /* FIXME */ } /* Helper functions used by option_setup_urbs */ @@ -807,7 +823,7 @@ static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint, /* Setup urbs */ static void option_setup_urbs(struct usb_serial *serial) { - int i,j; + int i, j; struct usb_serial_port *port; struct option_port_private *portdata; @@ -817,18 +833,22 @@ static void option_setup_urbs(struct usb_serial *serial) port = serial->port[i]; portdata = usb_get_serial_port_data(port); - /* Do indat endpoints first */ + /* Do indat endpoints first */ for (j = 0; j < N_IN_URB; ++j) { - portdata->in_urbs[j] = option_setup_urb (serial, - port->bulk_in_endpointAddress, USB_DIR_IN, port, - portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); + portdata->in_urbs[j] = option_setup_urb(serial, + port->bulk_in_endpointAddress, + USB_DIR_IN, port, + portdata->in_buffer[j], + IN_BUFLEN, option_indat_callback); } /* outdat endpoints */ for (j = 0; j < N_OUT_URB; ++j) { - portdata->out_urbs[j] = option_setup_urb (serial, - port->bulk_out_endpointAddress, USB_DIR_OUT, port, - portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); + portdata->out_urbs[j] = option_setup_urb(serial, + port->bulk_out_endpointAddress, + USB_DIR_OUT, port, + portdata->out_buffer[j], + OUT_BUFLEN, option_outdat_callback); } } } @@ -839,7 +859,8 @@ static void option_setup_urbs(struct usb_serial *serial) * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN * CDC. */ -static int option_send_setup(struct usb_serial_port *port) +static int option_send_setup(struct tty_struct *tty, + struct usb_serial_port *port) { struct usb_serial *serial = port->serial; struct option_port_private *portdata; @@ -848,7 +869,7 @@ static int option_send_setup(struct usb_serial_port *port) portdata = usb_get_serial_port_data(port); - if (port->tty) { + if (tty) { int val = 0; if (portdata->dtr_state) val |= 0x01; @@ -856,10 +877,9 @@ static int option_send_setup(struct usb_serial_port *port) val |= 0x02; return usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 0x22,0x21,val,ifNum,NULL,0,USB_CTRL_SET_TIMEOUT); + usb_rcvctrlpipe(serial->dev, 0), + 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT); } - return 0; } @@ -879,7 +899,7 @@ static int option_startup(struct usb_serial *serial) if (!portdata) { dbg("%s: kmalloc for option_port_private (%d) failed!.", __func__, i); - return (1); + return 1; } for (j = 0; j < N_IN_URB; j++) { @@ -898,17 +918,15 @@ static int option_startup(struct usb_serial *serial) usb_set_serial_port_data(port, portdata); - if (! port->interrupt_in_urb) + if (!port->interrupt_in_urb) continue; err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (err) dbg("%s: submit irq_in urb failed %d", __func__, err); } - option_setup_urbs(serial); - - return (0); + return 0; bail_out_error2: for (j = 0; j < N_OUT_URB; j++) @@ -947,7 +965,8 @@ static void option_shutdown(struct usb_serial *serial) for (j = 0; j < N_IN_URB; j++) { if (portdata->in_urbs[j]) { usb_free_urb(portdata->in_urbs[j]); - free_page((unsigned long)portdata->in_buffer[j]); + free_page((unsigned long) + portdata->in_buffer[j]); portdata->in_urbs[j] = NULL; } } @@ -972,8 +991,5 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); -#ifdef CONFIG_USB_DEBUG module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug messages"); -#endif - |