diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-02-01 22:28:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-02-01 22:28:57 -0500 |
commit | b6cf160c4b788a31f6a4017a469b956ca77febf4 (patch) | |
tree | d4d525000e283fe08905385d91dd0170454eae9a /drivers/usb/serial/pl2303.c | |
parent | ed50d6cbc394cd0966469d3e249353c9dd1d38b9 (diff) | |
parent | 2c044a4803804708984931bcbd03314732e995d5 (diff) |
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: (128 commits)
USB: fix codingstyle issues in drivers/usb/core/*.c
USB: fix codingstyle issues in drivers/usb/core/message.c
USB: fix codingstyle issues in drivers/usb/core/hcd-pci.c
USB: fix codingstyle issues in drivers/usb/core/devio.c
USB: fix codingstyle issues in drivers/usb/core/devices.c
USB: fix codingstyle issues in drivers/usb/core/*.h
USB: fix codingstyle issues in include/linux/usb/
USB: fix codingstyle issues in include/linux/usb.h
USB: mark USB drivers as being GPL only
USB: use a real vendor and product id for root hubs
USB: mount options: fix usbfs
USB: Fix usb_serial_driver structure for Kobil cardreader driver.
usb: ehci should use u16 for isochronous intervals
usb: ehci, remove false clear-reset path
USB: Use menuconfig objects
usb: ohci-sm501 driver
usb: dma bounce buffer support
USB: last abuses of intfdata in close for usb-serial drivers
USB: kl5kusb105 don't flush to logically disconnected devices
USB: oti6858: cleanup
...
Diffstat (limited to 'drivers/usb/serial/pl2303.c')
-rw-r--r-- | drivers/usb/serial/pl2303.c | 112 |
1 files changed, 58 insertions, 54 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 0da1df9c79bf..ae3ec1a64008 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -65,6 +65,7 @@ static struct usb_device_id id_table [] = { | |||
65 | { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) }, | 65 | { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) }, |
66 | { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, | 66 | { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, |
67 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, | 67 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, |
68 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | ||
68 | { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, | 69 | { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, |
69 | { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) }, | 70 | { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) }, |
70 | { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, | 71 | { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, |
@@ -84,9 +85,10 @@ static struct usb_device_id id_table [] = { | |||
84 | { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) }, | 85 | { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) }, |
85 | { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) }, | 86 | { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) }, |
86 | { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) }, | 87 | { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) }, |
87 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) }, | ||
88 | { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) }, | 88 | { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) }, |
89 | { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) }, | 89 | { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) }, |
90 | { USB_DEVICE(HL340_VENDOR_ID, HL340_PRODUCT_ID) }, | ||
91 | { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, | ||
90 | { } /* Terminating entry */ | 92 | { } /* Terminating entry */ |
91 | }; | 93 | }; |
92 | 94 | ||
@@ -97,7 +99,10 @@ static struct usb_driver pl2303_driver = { | |||
97 | .probe = usb_serial_probe, | 99 | .probe = usb_serial_probe, |
98 | .disconnect = usb_serial_disconnect, | 100 | .disconnect = usb_serial_disconnect, |
99 | .id_table = id_table, | 101 | .id_table = id_table, |
102 | .suspend = usb_serial_suspend, | ||
103 | .resume = usb_serial_resume, | ||
100 | .no_dynamic_id = 1, | 104 | .no_dynamic_id = 1, |
105 | .supports_autosuspend = 1, | ||
101 | }; | 106 | }; |
102 | 107 | ||
103 | #define SET_LINE_REQUEST_TYPE 0x21 | 108 | #define SET_LINE_REQUEST_TYPE 0x21 |
@@ -310,12 +315,39 @@ static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, | |||
310 | return count; | 315 | return count; |
311 | } | 316 | } |
312 | 317 | ||
318 | static int pl2303_vendor_read(__u16 value, __u16 index, | ||
319 | struct usb_serial *serial, unsigned char *buf) | ||
320 | { | ||
321 | int res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | ||
322 | VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE, | ||
323 | value, index, buf, 1, 100); | ||
324 | dbg("0x%x:0x%x:0x%x:0x%x %d - %x", VENDOR_READ_REQUEST_TYPE, | ||
325 | VENDOR_READ_REQUEST, value, index, res, buf[0]); | ||
326 | return res; | ||
327 | } | ||
328 | |||
329 | static int pl2303_vendor_write(__u16 value, __u16 index, | ||
330 | struct usb_serial *serial) | ||
331 | { | ||
332 | int res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | ||
333 | VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE, | ||
334 | value, index, NULL, 0, 100); | ||
335 | dbg("0x%x:0x%x:0x%x:0x%x %d", VENDOR_WRITE_REQUEST_TYPE, | ||
336 | VENDOR_WRITE_REQUEST, value, index, res); | ||
337 | return res; | ||
338 | } | ||
339 | |||
313 | static int pl2303_startup(struct usb_serial *serial) | 340 | static int pl2303_startup(struct usb_serial *serial) |
314 | { | 341 | { |
315 | struct pl2303_private *priv; | 342 | struct pl2303_private *priv; |
316 | enum pl2303_type type = type_0; | 343 | enum pl2303_type type = type_0; |
344 | unsigned char *buf; | ||
317 | int i; | 345 | int i; |
318 | 346 | ||
347 | buf = kmalloc(10, GFP_KERNEL); | ||
348 | if (buf == NULL) | ||
349 | return -ENOMEM; | ||
350 | |||
319 | if (serial->dev->descriptor.bDeviceClass == 0x02) | 351 | if (serial->dev->descriptor.bDeviceClass == 0x02) |
320 | type = type_0; | 352 | type = type_0; |
321 | else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) | 353 | else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) |
@@ -340,9 +372,27 @@ static int pl2303_startup(struct usb_serial *serial) | |||
340 | priv->type = type; | 372 | priv->type = type; |
341 | usb_set_serial_port_data(serial->port[i], priv); | 373 | usb_set_serial_port_data(serial->port[i], priv); |
342 | } | 374 | } |
375 | |||
376 | pl2303_vendor_read(0x8484, 0, serial, buf); | ||
377 | pl2303_vendor_write(0x0404, 0, serial); | ||
378 | pl2303_vendor_read(0x8484, 0, serial, buf); | ||
379 | pl2303_vendor_read(0x8383, 0, serial, buf); | ||
380 | pl2303_vendor_read(0x8484, 0, serial, buf); | ||
381 | pl2303_vendor_write(0x0404, 1, serial); | ||
382 | pl2303_vendor_read(0x8484, 0, serial, buf); | ||
383 | pl2303_vendor_read(0x8383, 0, serial, buf); | ||
384 | pl2303_vendor_write(0, 1, serial); | ||
385 | pl2303_vendor_write(1, 0, serial); | ||
386 | if (type == HX) | ||
387 | pl2303_vendor_write(2, 0x44, serial); | ||
388 | else | ||
389 | pl2303_vendor_write(2, 0x24, serial); | ||
390 | |||
391 | kfree(buf); | ||
343 | return 0; | 392 | return 0; |
344 | 393 | ||
345 | cleanup: | 394 | cleanup: |
395 | kfree(buf); | ||
346 | for (--i; i>=0; --i) { | 396 | for (--i; i>=0; --i) { |
347 | priv = usb_get_serial_port_data(serial->port[i]); | 397 | priv = usb_get_serial_port_data(serial->port[i]); |
348 | pl2303_buf_free(priv->buf); | 398 | pl2303_buf_free(priv->buf); |
@@ -582,24 +632,12 @@ static void pl2303_set_termios(struct usb_serial_port *port, | |||
582 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); | 632 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); |
583 | 633 | ||
584 | if (cflag & CRTSCTS) { | 634 | if (cflag & CRTSCTS) { |
585 | __u16 index; | ||
586 | if (priv->type == HX) | 635 | if (priv->type == HX) |
587 | index = 0x61; | 636 | pl2303_vendor_write(0x0, 0x61, serial); |
588 | else | 637 | else |
589 | index = 0x41; | 638 | pl2303_vendor_write(0x0, 0x41, serial); |
590 | i = usb_control_msg(serial->dev, | ||
591 | usb_sndctrlpipe(serial->dev, 0), | ||
592 | VENDOR_WRITE_REQUEST, | ||
593 | VENDOR_WRITE_REQUEST_TYPE, | ||
594 | 0x0, index, NULL, 0, 100); | ||
595 | dbg("0x40:0x1:0x0:0x%x %d", index, i); | ||
596 | } else { | 639 | } else { |
597 | i = usb_control_msg(serial->dev, | 640 | pl2303_vendor_write(0x0, 0x0, serial); |
598 | usb_sndctrlpipe(serial->dev, 0), | ||
599 | VENDOR_WRITE_REQUEST, | ||
600 | VENDOR_WRITE_REQUEST_TYPE, | ||
601 | 0x0, 0x0, NULL, 0, 100); | ||
602 | dbg ("0x40:0x1:0x0:0x0 %d", i); | ||
603 | } | 641 | } |
604 | 642 | ||
605 | /* FIXME: Need to read back resulting baud rate */ | 643 | /* FIXME: Need to read back resulting baud rate */ |
@@ -629,7 +667,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp) | |||
629 | set_current_state(TASK_INTERRUPTIBLE); | 667 | set_current_state(TASK_INTERRUPTIBLE); |
630 | if (pl2303_buf_data_avail(priv->buf) == 0 || | 668 | if (pl2303_buf_data_avail(priv->buf) == 0 || |
631 | timeout == 0 || signal_pending(current) || | 669 | timeout == 0 || signal_pending(current) || |
632 | !usb_get_intfdata(port->serial->interface)) /* disconnect */ | 670 | port->serial->disconnected) |
633 | break; | 671 | break; |
634 | spin_unlock_irqrestore(&priv->lock, flags); | 672 | spin_unlock_irqrestore(&priv->lock, flags); |
635 | timeout = schedule_timeout(timeout); | 673 | timeout = schedule_timeout(timeout); |
@@ -678,7 +716,6 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp) | |||
678 | struct ktermios tmp_termios; | 716 | struct ktermios tmp_termios; |
679 | struct usb_serial *serial = port->serial; | 717 | struct usb_serial *serial = port->serial; |
680 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 718 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
681 | unsigned char *buf; | ||
682 | int result; | 719 | int result; |
683 | 720 | ||
684 | dbg("%s - port %d", __FUNCTION__, port->number); | 721 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -686,45 +723,12 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp) | |||
686 | if (priv->type != HX) { | 723 | if (priv->type != HX) { |
687 | usb_clear_halt(serial->dev, port->write_urb->pipe); | 724 | usb_clear_halt(serial->dev, port->write_urb->pipe); |
688 | usb_clear_halt(serial->dev, port->read_urb->pipe); | 725 | usb_clear_halt(serial->dev, port->read_urb->pipe); |
689 | } | ||
690 | |||
691 | buf = kmalloc(10, GFP_KERNEL); | ||
692 | if (buf==NULL) | ||
693 | return -ENOMEM; | ||
694 | |||
695 | #define FISH(a,b,c,d) \ | ||
696 | result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \ | ||
697 | b, a, c, d, buf, 1, 100); \ | ||
698 | dbg("0x%x:0x%x:0x%x:0x%x %d - %x",a,b,c,d,result,buf[0]); | ||
699 | |||
700 | #define SOUP(a,b,c,d) \ | ||
701 | result=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0), \ | ||
702 | b, a, c, d, NULL, 0, 100); \ | ||
703 | dbg("0x%x:0x%x:0x%x:0x%x %d",a,b,c,d,result); | ||
704 | |||
705 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); | ||
706 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 0); | ||
707 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); | ||
708 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0); | ||
709 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); | ||
710 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 1); | ||
711 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); | ||
712 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0); | ||
713 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1); | ||
714 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0); | ||
715 | |||
716 | if (priv->type == HX) { | ||
717 | /* HX chip */ | ||
718 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x44); | ||
719 | /* reset upstream data pipes */ | ||
720 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 8, 0); | ||
721 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 9, 0); | ||
722 | } else { | 726 | } else { |
723 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x24); | 727 | /* reset upstream data pipes */ |
728 | pl2303_vendor_write(8, 0, serial); | ||
729 | pl2303_vendor_write(9, 0, serial); | ||
724 | } | 730 | } |
725 | 731 | ||
726 | kfree(buf); | ||
727 | |||
728 | /* Setup termios */ | 732 | /* Setup termios */ |
729 | if (port->tty) { | 733 | if (port->tty) { |
730 | pl2303_set_termios(port, &tmp_termios); | 734 | pl2303_set_termios(port, &tmp_termios); |