Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[pandora-kernel.git] / drivers / usb / serial / option.c
index a73420d..e4eca95 100644 (file)
 #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,6 +169,7 @@ 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
@@ -305,6 +302,7 @@ static struct usb_device_id option_ids[] = {
        { 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(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 */
@@ -340,11 +338,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,
@@ -401,47 +395,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 +436,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 +454,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 +473,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 +494,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 +534,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 +544,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 +585,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 +610,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 +630,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 +641,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 +651,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 +661,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 +672,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 +691,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 +716,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 +747,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 +756,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 +786,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 +796,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 +822,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 +832,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 +840,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 +862,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 +881,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 +928,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;
                        }
                }