aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSarah Sharp <saharabeara@gmail.com>2007-12-14 17:08:35 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-02-01 17:34:55 -0500
commit3e152505a57db6622deb1322c22551c046e33d16 (patch)
treec6fd97a1a5a882e41e30c6e97efe6ca1182fe13e /drivers/usb
parenteb44da0b3aa0105cb38d81c5747a8feae64834be (diff)
USB: pl2303: Move pl2303 vendor specific init to probe function.
Without this fix, the pl2303 usb-serial adapter would not suspend properly unless it had been opened first. A pl2303 type_1 chip will still break if the system is hibernated while the RS-232 connector is powered by another system. This was broken before, and a reset resume does not fix it. All other suspend and autosuspend scenarios work with ATEN pl2303 adaptors with HX and type_1 chips. Signed-off-by: Sarah Sharp <saharabeara@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/pl2303.c49
1 files changed, 24 insertions, 25 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index fd8c09fd3288..c27f2f822f13 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -338,8 +338,13 @@ static int pl2303_startup(struct usb_serial *serial)
338{ 338{
339 struct pl2303_private *priv; 339 struct pl2303_private *priv;
340 enum pl2303_type type = type_0; 340 enum pl2303_type type = type_0;
341 unsigned char *buf;
341 int i; 342 int i;
342 343
344 buf = kmalloc(10, GFP_KERNEL);
345 if (buf == NULL)
346 return -ENOMEM;
347
343 if (serial->dev->descriptor.bDeviceClass == 0x02) 348 if (serial->dev->descriptor.bDeviceClass == 0x02)
344 type = type_0; 349 type = type_0;
345 else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) 350 else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40)
@@ -364,9 +369,27 @@ static int pl2303_startup(struct usb_serial *serial)
364 priv->type = type; 369 priv->type = type;
365 usb_set_serial_port_data(serial->port[i], priv); 370 usb_set_serial_port_data(serial->port[i], priv);
366 } 371 }
372
373 pl2303_vendor_read(0x8484, 0, serial, buf);
374 pl2303_vendor_write(0x0404, 0, serial);
375 pl2303_vendor_read(0x8484, 0, serial, buf);
376 pl2303_vendor_read(0x8383, 0, serial, buf);
377 pl2303_vendor_read(0x8484, 0, serial, buf);
378 pl2303_vendor_write(0x0404, 1, serial);
379 pl2303_vendor_read(0x8484, 0, serial, buf);
380 pl2303_vendor_read(0x8383, 0, serial, buf);
381 pl2303_vendor_write(0, 1, serial);
382 pl2303_vendor_write(1, 0, serial);
383 if (type == HX)
384 pl2303_vendor_write(2, 0x44, serial);
385 else
386 pl2303_vendor_write(2, 0x24, serial);
387
388 kfree(buf);
367 return 0; 389 return 0;
368 390
369cleanup: 391cleanup:
392 kfree(buf);
370 for (--i; i>=0; --i) { 393 for (--i; i>=0; --i) {
371 priv = usb_get_serial_port_data(serial->port[i]); 394 priv = usb_get_serial_port_data(serial->port[i]);
372 pl2303_buf_free(priv->buf); 395 pl2303_buf_free(priv->buf);
@@ -690,7 +713,6 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp)
690 struct ktermios tmp_termios; 713 struct ktermios tmp_termios;
691 struct usb_serial *serial = port->serial; 714 struct usb_serial *serial = port->serial;
692 struct pl2303_private *priv = usb_get_serial_port_data(port); 715 struct pl2303_private *priv = usb_get_serial_port_data(port);
693 unsigned char *buf;
694 int result; 716 int result;
695 717
696 dbg("%s - port %d", __FUNCTION__, port->number); 718 dbg("%s - port %d", __FUNCTION__, port->number);
@@ -698,35 +720,12 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp)
698 if (priv->type != HX) { 720 if (priv->type != HX) {
699 usb_clear_halt(serial->dev, port->write_urb->pipe); 721 usb_clear_halt(serial->dev, port->write_urb->pipe);
700 usb_clear_halt(serial->dev, port->read_urb->pipe); 722 usb_clear_halt(serial->dev, port->read_urb->pipe);
701 } 723 } else {
702
703 buf = kmalloc(10, GFP_KERNEL);
704 if (buf==NULL)
705 return -ENOMEM;
706
707 pl2303_vendor_read(0x8484, 0, serial, buf);
708 pl2303_vendor_write(0x0404, 0, serial);
709 pl2303_vendor_read(0x8484, 0, serial, buf);
710 pl2303_vendor_read(0x8383, 0, serial, buf);
711 pl2303_vendor_read(0x8484, 0, serial, buf);
712 pl2303_vendor_write(0x0404, 1, serial);
713 pl2303_vendor_read(0x8484, 0, serial, buf);
714 pl2303_vendor_read(0x8383, 0, serial, buf);
715 pl2303_vendor_write(0, 1, serial);
716 pl2303_vendor_write(1, 0, serial);
717
718 if (priv->type == HX) {
719 /* HX chip */
720 pl2303_vendor_write(2, 0x44, serial);
721 /* reset upstream data pipes */ 724 /* reset upstream data pipes */
722 pl2303_vendor_write(8, 0, serial); 725 pl2303_vendor_write(8, 0, serial);
723 pl2303_vendor_write(9, 0, serial); 726 pl2303_vendor_write(9, 0, serial);
724 } else {
725 pl2303_vendor_write(2, 0x24, serial);
726 } 727 }
727 728
728 kfree(buf);
729
730 /* Setup termios */ 729 /* Setup termios */
731 if (port->tty) { 730 if (port->tty) {
732 pl2303_set_termios(port, &tmp_termios); 731 pl2303_set_termios(port, &tmp_termios);