OSDN Git Service

USB: option: fix port-data abuse
[android-x86/kernel.git] / drivers / usb / serial / option.c
index 3553407..ce02457 100644 (file)
@@ -47,6 +47,7 @@
 /* Function prototypes */
 static int  option_probe(struct usb_serial *serial,
                        const struct usb_device_id *id);
+static void option_release(struct usb_serial *serial);
 static int option_send_setup(struct usb_serial_port *port);
 static void option_instat_callback(struct urb *urb);
 
@@ -426,7 +427,7 @@ static void option_instat_callback(struct urb *urb);
 #define SAMSUNG_VENDOR_ID                       0x04e8
 #define SAMSUNG_PRODUCT_GT_B3730                0x6889
 
-/* YUGA products  www.yuga-info.com*/
+/* YUGA products  www.yuga-info.com gavin.kx@qq.com */
 #define YUGA_VENDOR_ID                         0x257A
 #define YUGA_PRODUCT_CEM600                    0x1601
 #define YUGA_PRODUCT_CEM610                    0x1602
@@ -443,6 +444,8 @@ static void option_instat_callback(struct urb *urb);
 #define YUGA_PRODUCT_CEU516                    0x160C
 #define YUGA_PRODUCT_CEU528                    0x160D
 #define YUGA_PRODUCT_CEU526                    0x160F
+#define YUGA_PRODUCT_CEU881                    0x161F
+#define YUGA_PRODUCT_CEU882                    0x162F
 
 #define YUGA_PRODUCT_CWM600                    0x2601
 #define YUGA_PRODUCT_CWM610                    0x2602
@@ -458,23 +461,26 @@ static void option_instat_callback(struct urb *urb);
 #define YUGA_PRODUCT_CWU518                    0x260B
 #define YUGA_PRODUCT_CWU516                    0x260C
 #define YUGA_PRODUCT_CWU528                    0x260D
+#define YUGA_PRODUCT_CWU581                    0x260E
 #define YUGA_PRODUCT_CWU526                    0x260F
-
-#define YUGA_PRODUCT_CLM600                    0x2601
-#define YUGA_PRODUCT_CLM610                    0x2602
-#define YUGA_PRODUCT_CLM500                    0x2603
-#define YUGA_PRODUCT_CLM510                    0x2604
-#define YUGA_PRODUCT_CLM800                    0x2605
-#define YUGA_PRODUCT_CLM900                    0x2606
-
-#define YUGA_PRODUCT_CLU718                    0x2607
-#define YUGA_PRODUCT_CLU716                    0x2608
-#define YUGA_PRODUCT_CLU728                    0x2609
-#define YUGA_PRODUCT_CLU726                    0x260A
-#define YUGA_PRODUCT_CLU518                    0x260B
-#define YUGA_PRODUCT_CLU516                    0x260C
-#define YUGA_PRODUCT_CLU528                    0x260D
-#define YUGA_PRODUCT_CLU526                    0x260F
+#define YUGA_PRODUCT_CWU582                    0x261F
+#define YUGA_PRODUCT_CWU583                    0x262F
+
+#define YUGA_PRODUCT_CLM600                    0x3601
+#define YUGA_PRODUCT_CLM610                    0x3602
+#define YUGA_PRODUCT_CLM500                    0x3603
+#define YUGA_PRODUCT_CLM510                    0x3604
+#define YUGA_PRODUCT_CLM800                    0x3605
+#define YUGA_PRODUCT_CLM900                    0x3606
+
+#define YUGA_PRODUCT_CLU718                    0x3607
+#define YUGA_PRODUCT_CLU716                    0x3608
+#define YUGA_PRODUCT_CLU728                    0x3609
+#define YUGA_PRODUCT_CLU726                    0x360A
+#define YUGA_PRODUCT_CLU518                    0x360B
+#define YUGA_PRODUCT_CLU516                    0x360C
+#define YUGA_PRODUCT_CLU528                    0x360D
+#define YUGA_PRODUCT_CLU526                    0x360F
 
 /* Viettel products */
 #define VIETTEL_VENDOR_ID                      0x2262
@@ -1213,6 +1219,11 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) },
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) },
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU881) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU882) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU581) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU582) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU583) },
        { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) },
        { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */
@@ -1263,7 +1274,7 @@ static struct usb_serial_driver option_1port_device = {
        .ioctl             = usb_wwan_ioctl,
        .attach            = usb_wwan_startup,
        .disconnect        = usb_wwan_disconnect,
-       .release           = usb_wwan_release,
+       .release           = option_release,
        .read_int_callback = option_instat_callback,
 #ifdef CONFIG_PM
        .suspend           = usb_wwan_suspend,
@@ -1273,35 +1284,6 @@ static struct usb_serial_driver option_1port_device = {
 
 static int debug;
 
-/* per port private data */
-
-#define N_IN_URB 4
-#define N_OUT_URB 4
-#define IN_BUFLEN 4096
-#define OUT_BUFLEN 4096
-
-struct option_port_private {
-       /* Input endpoints and buffer for this port */
-       struct urb *in_urbs[N_IN_URB];
-       u8 *in_buffer[N_IN_URB];
-       /* Output endpoints and buffer for this port */
-       struct urb *out_urbs[N_OUT_URB];
-       u8 *out_buffer[N_OUT_URB];
-       unsigned long out_busy;         /* Bit vector of URBs in use */
-       int opened;
-       struct usb_anchor delayed;
-
-       /* Settings for the port */
-       int rts_state;  /* Handshaking pins (outputs) */
-       int dtr_state;
-       int cts_state;  /* Handshaking pins (inputs) */
-       int dsr_state;
-       int dcd_state;
-       int ri_state;
-
-       unsigned long tx_start_time[N_OUT_URB];
-};
-
 /* Functions used by new usb-serial code. */
 static int __init option_init(void)
 {
@@ -1399,12 +1381,22 @@ static int option_probe(struct usb_serial *serial,
        return 0;
 }
 
+static void option_release(struct usb_serial *serial)
+{
+       struct usb_wwan_intf_private *priv = usb_get_serial_data(serial);
+
+       usb_wwan_release(serial);
+
+       kfree(priv);
+}
+
 static void option_instat_callback(struct urb *urb)
 {
        int err;
        int status = urb->status;
        struct usb_serial_port *port =  urb->context;
-       struct option_port_private *portdata = usb_get_serial_port_data(port);
+       struct usb_wwan_port_private *portdata =
+                                       usb_get_serial_port_data(port);
 
        dbg("%s", __func__);
        dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata);
@@ -1465,7 +1457,7 @@ static int option_send_setup(struct usb_serial_port *port)
        struct usb_serial *serial = port->serial;
        struct usb_wwan_intf_private *intfdata =
                (struct usb_wwan_intf_private *) serial->private;
-       struct option_port_private *portdata;
+       struct usb_wwan_port_private *portdata;
        int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
        int val = 0;
        dbg("%s", __func__);