X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fusb%2Fserial%2Fpl2303.c;h=af0d230c61c687819bd49c51024a20af3f8a039f;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=e274cec85902365d9e2722fbd2c47e675777f2d5;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index e274cec85..af0d230c6 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -49,23 +49,16 @@ #include #include #include - -#ifdef CONFIG_USB_SERIAL_DEBUG - static int debug = 1; -#else - static int debug; -#endif - #include "usb-serial.h" #include "pl2303.h" /* * Version Information */ -#define DRIVER_VERSION "v0.10" +#define DRIVER_VERSION "v0.11" #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver" - +static int debug; static struct usb_device_id id_table [] = { { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) }, @@ -82,6 +75,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, { USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) }, + { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) }, { } /* Terminating entry */ }; @@ -172,20 +166,38 @@ static struct usb_serial_device_type pl2303_device = { .shutdown = pl2303_shutdown, }; +enum pl2303_type { + type_0, /* don't know the difference between type 0 and */ + type_1, /* type 1, until someone from prolific tells us... */ + HX, /* HX version of the pl2303 chip */ +}; + struct pl2303_private { spinlock_t lock; wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; u8 termios_initialized; + enum pl2303_type type; }; static int pl2303_startup (struct usb_serial *serial) { struct pl2303_private *priv; + enum pl2303_type type = type_0; int i; + if (serial->dev->descriptor.bDeviceClass == 0x02) + type = type_0; + else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) + type = HX; + else if (serial->dev->descriptor.bDeviceClass == 0x00) + type = type_1; + else if (serial->dev->descriptor.bDeviceClass == 0xFF) + type = type_1; + dbg("device type: %d", type); + for (i = 0; i < serial->num_ports; ++i) { priv = kmalloc (sizeof (struct pl2303_private), GFP_KERNEL); if (!priv) @@ -193,6 +205,7 @@ static int pl2303_startup (struct usb_serial *serial) memset (priv, 0x00, sizeof (struct pl2303_private)); spin_lock_init(&priv->lock); init_waitqueue_head(&priv->delta_msr_wait); + priv->type = type; usb_set_serial_port_data(serial->port[i], priv); } return 0; @@ -231,7 +244,7 @@ static int pl2303_write (struct usb_serial_port *port, int from_user, const uns memcpy (port->write_urb->transfer_buffer, buf, count); } - usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer); + usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer); port->write_urb->transfer_buffer_length = count; port->write_urb->dev = port->serial->dev; @@ -395,20 +408,27 @@ static void pl2303_set_termios (struct usb_serial_port *port, struct termios *ol buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); if (cflag & CRTSCTS) { - i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0), - VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE, - 0x0, 0x41, NULL, 0, 100); - dbg ("0x40:0x1:0x0:0x41 %d", i); + __u16 index; + if (priv->type == HX) + index = 0x61; + else + index = 0x41; + i = usb_control_msg(serial->dev, + usb_sndctrlpipe(serial->dev, 0), + VENDOR_WRITE_REQUEST, + VENDOR_WRITE_REQUEST_TYPE, + 0x0, index, NULL, 0, 100); + dbg ("0x40:0x1:0x0:0x%x %d", index, i); } kfree (buf); -} - +} static int pl2303_open (struct usb_serial_port *port, struct file *filp) { struct termios tmp_termios; struct usb_serial *serial = port->serial; + struct pl2303_private *priv = usb_get_serial_port_data(port); unsigned char *buf; int result; @@ -439,6 +459,18 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp) SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 1); FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0); + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1); + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0); + + if (priv->type == HX) { + /* HX chip */ + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x44); + /* reset upstream data pipes */ + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 8, 0); + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 9, 0); + } else { + SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x24); + } kfree(buf); @@ -677,7 +709,7 @@ static void pl2303_read_int_callback (struct urb *urb, struct pt_regs *regs) } - usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, urb->transfer_buffer); + usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, urb->transfer_buffer); if (urb->actual_length < UART_STATE) goto exit; @@ -731,7 +763,7 @@ static void pl2303_read_bulk_callback (struct urb *urb, struct pt_regs *regs) return; } - usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); /* get tty_flag from status */ tty_flag = TTY_NORMAL;