pl2303.c 23.4 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3
/*
 * Prolific PL2303 USB to serial adaptor driver
 *
4
 * Copyright (C) 2001-2007 Greg Kroah-Hartman (greg@kroah.com)
L
Linus Torvalds 已提交
5 6 7 8
 * Copyright (C) 2003 IBM Corp.
 *
 * Original driver for 2.2.x by anonymous
 *
9 10 11
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License version
 *	2 as published by the Free Software Foundation.
L
Linus Torvalds 已提交
12
 *
A
Alan Cox 已提交
13 14
 * See Documentation/usb/usb-serial.txt for more information on using this
 * driver
L
Linus Torvalds 已提交
15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
A
Alan Cox 已提交
29
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
30
#include <linux/usb.h>
31
#include <linux/usb/serial.h>
L
Linus Torvalds 已提交
32 33 34 35 36 37 38
#include "pl2303.h"

/*
 * Version Information
 */
#define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"

39
static bool debug;
L
Linus Torvalds 已提交
40

41
static const struct usb_device_id id_table[] = {
L
Linus Torvalds 已提交
42 43
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
44
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) },
L
Linus Torvalds 已提交
45 46
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
M
Max Arnold 已提交
47
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
S
Steve Murphy 已提交
48
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
G
Greg Kroah-Hartman 已提交
49
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
50
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
51
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) },
L
Linus Torvalds 已提交
52
	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
53
	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
L
Linus Torvalds 已提交
54 55 56 57 58
	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
	{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
	{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
	{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID_UCSGT) },
	{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
59
	{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) },
L
Linus Torvalds 已提交
60 61 62 63 64 65 66 67
	{ USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
	{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
	{ USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
	{ USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) },
	{ 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) },
68
	{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) },
L
Linus Torvalds 已提交
69
	{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) },
70
	{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) },
71
	{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_EF81) },
72
	{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_ID_S81) }, /* Benq/Siemens S81 */
73
	{ USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },
74 75
	{ USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) },
	{ USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) },
76
	{ USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) },
77
	{ USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) },
78
	{ USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) },
79
	{ USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
80
	{ USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
81
	{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
82
	{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
83
	{ USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
84
	{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
M
Matthew Arnold 已提交
85
	{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
86
	{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
87
	{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
88
	{ USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
89
	{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
90
	{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
91
	{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
92
	{ USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },
L
Linus Torvalds 已提交
93 94 95
	{ }					/* Terminating entry */
};

96
MODULE_DEVICE_TABLE(usb, id_table);
L
Linus Torvalds 已提交
97 98 99 100 101 102 103 104 105 106

#define SET_LINE_REQUEST_TYPE		0x21
#define SET_LINE_REQUEST		0x20

#define SET_CONTROL_REQUEST_TYPE	0x21
#define SET_CONTROL_REQUEST		0x22
#define CONTROL_DTR			0x01
#define CONTROL_RTS			0x02

#define BREAK_REQUEST_TYPE		0x21
A
Alan Cox 已提交
107
#define BREAK_REQUEST			0x23
L
Linus Torvalds 已提交
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
#define BREAK_ON			0xffff
#define BREAK_OFF			0x0000

#define GET_LINE_REQUEST_TYPE		0xa1
#define GET_LINE_REQUEST		0x21

#define VENDOR_WRITE_REQUEST_TYPE	0x40
#define VENDOR_WRITE_REQUEST		0x01

#define VENDOR_READ_REQUEST_TYPE	0xc0
#define VENDOR_READ_REQUEST		0x01

#define UART_STATE			0x08
#define UART_STATE_TRANSIENT_MASK	0x74
#define UART_DCD			0x01
#define UART_DSR			0x02
#define UART_BREAK_ERROR		0x04
#define UART_RING			0x08
#define UART_FRAME_ERROR		0x10
#define UART_PARITY_ERROR		0x20
#define UART_OVERRUN_ERROR		0x40
#define UART_CTS			0x80


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;
	enum pl2303_type type;
};

146 147 148 149 150 151
static int pl2303_vendor_read(__u16 value, __u16 index,
		struct usb_serial *serial, unsigned char *buf)
{
	int res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
			VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE,
			value, index, buf, 1, 100);
152 153 154
	dev_dbg(&serial->dev->dev, "0x%x:0x%x:0x%x:0x%x  %d - %x\n",
		VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, value, index,
		res, buf[0]);
155 156 157 158 159 160 161 162 163
	return res;
}

static int pl2303_vendor_write(__u16 value, __u16 index,
		struct usb_serial *serial)
{
	int res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
			VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE,
			value, index, NULL, 0, 100);
164 165 166
	dev_dbg(&serial->dev->dev, "0x%x:0x%x:0x%x:0x%x  %d\n",
		VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, value, index,
		res);
167 168 169
	return res;
}

170
static int pl2303_startup(struct usb_serial *serial)
L
Linus Torvalds 已提交
171 172 173
{
	struct pl2303_private *priv;
	enum pl2303_type type = type_0;
174
	unsigned char *buf;
L
Linus Torvalds 已提交
175 176
	int i;

177 178 179 180
	buf = kmalloc(10, GFP_KERNEL);
	if (buf == NULL)
		return -ENOMEM;

L
Linus Torvalds 已提交
181 182 183 184 185 186 187 188
	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;
189
	dev_dbg(&serial->interface->dev, "device type: %d\n", type);
L
Linus Torvalds 已提交
190 191

	for (i = 0; i < serial->num_ports; ++i) {
192
		priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL);
L
Linus Torvalds 已提交
193 194 195 196 197 198 199
		if (!priv)
			goto cleanup;
		spin_lock_init(&priv->lock);
		init_waitqueue_head(&priv->delta_msr_wait);
		priv->type = type;
		usb_set_serial_port_data(serial->port[i], priv);
	}
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216

	pl2303_vendor_read(0x8484, 0, serial, buf);
	pl2303_vendor_write(0x0404, 0, serial);
	pl2303_vendor_read(0x8484, 0, serial, buf);
	pl2303_vendor_read(0x8383, 0, serial, buf);
	pl2303_vendor_read(0x8484, 0, serial, buf);
	pl2303_vendor_write(0x0404, 1, serial);
	pl2303_vendor_read(0x8484, 0, serial, buf);
	pl2303_vendor_read(0x8383, 0, serial, buf);
	pl2303_vendor_write(0, 1, serial);
	pl2303_vendor_write(1, 0, serial);
	if (type == HX)
		pl2303_vendor_write(2, 0x44, serial);
	else
		pl2303_vendor_write(2, 0x24, serial);

	kfree(buf);
L
Linus Torvalds 已提交
217 218 219
	return 0;

cleanup:
220
	kfree(buf);
A
Alan Cox 已提交
221
	for (--i; i >= 0; --i) {
L
Linus Torvalds 已提交
222 223 224 225 226 227 228
		priv = usb_get_serial_port_data(serial->port[i]);
		kfree(priv);
		usb_set_serial_port_data(serial->port[i], NULL);
	}
	return -ENOMEM;
}

229
static int set_control_lines(struct usb_device *dev, u8 value)
L
Linus Torvalds 已提交
230 231
{
	int retval;
A
Alan Cox 已提交
232

233 234 235
	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
				 SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,
				 value, 0, NULL, 0, 100);
236 237
	dev_dbg(&dev->dev, "%s - value = %d, retval = %d\n", __func__,
		value, retval);
L
Linus Torvalds 已提交
238 239 240
	return retval;
}

A
Alan Cox 已提交
241 242
static void pl2303_set_termios(struct tty_struct *tty,
		struct usb_serial_port *port, struct ktermios *old_termios)
L
Linus Torvalds 已提交
243 244 245 246 247 248 249 250 251
{
	struct usb_serial *serial = port->serial;
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	unsigned int cflag;
	unsigned char *buf;
	int baud;
	int i;
	u8 control;
252 253 254 255 256 257
	const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600,
	                         4800, 7200, 9600, 14400, 19200, 28800, 38400,
	                         57600, 115200, 230400, 460800, 614400,
	                         921600, 1228800, 2457600, 3000000, 6000000 };
	int baud_floor, baud_ceil;
	int k;
L
Linus Torvalds 已提交
258

A
Alan Cox 已提交
259 260 261 262
	/* The PL2303 is reported to lose bytes if you change
	   serial settings even to the same values as before. Thus
	   we actually need to filter in this specific case */

A
Alan Cox 已提交
263
	if (!tty_termios_hw_change(tty->termios, old_termios))
A
Alan Cox 已提交
264 265
		return;

A
Alan Cox 已提交
266
	cflag = tty->termios->c_cflag;
L
Linus Torvalds 已提交
267

268
	buf = kzalloc(7, GFP_KERNEL);
L
Linus Torvalds 已提交
269
	if (!buf) {
270
		dev_err(&port->dev, "%s - out of memory.\n", __func__);
271
		/* Report back no change occurred */
A
Alan Cox 已提交
272
		*tty->termios = *old_termios;
L
Linus Torvalds 已提交
273 274 275
		return;
	}

276 277 278
	i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
			    GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,
			    0, 0, buf, 7, 100);
279
	dev_dbg(&port->dev, "0xa1:0x21:0:0  %d - %x %x %x %x %x %x %x\n", i,
280
	    buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
L
Linus Torvalds 已提交
281 282 283

	if (cflag & CSIZE) {
		switch (cflag & CSIZE) {
A
Alan Cox 已提交
284 285 286 287 288 289 290 291 292 293 294 295 296
		case CS5:
			buf[6] = 5;
			break;
		case CS6:
			buf[6] = 6;
			break;
		case CS7:
			buf[6] = 7;
			break;
		default:
		case CS8:
			buf[6] = 8;
			break;
L
Linus Torvalds 已提交
297
		}
298
		dev_dbg(&port->dev, "data bits = %d\n", buf[6]);
L
Linus Torvalds 已提交
299 300
	}

301 302 303 304 305
	/* For reference buf[0]:buf[3] baud rate value */
	/* NOTE: Only the values defined in baud_sup are supported !
	 *       => if unsupported values are set, the PL2303 seems to use
	 *          9600 baud (at least my PL2303X always does)
	 */
A
Alan Cox 已提交
306
	baud = tty_get_baud_rate(tty);
307
	dev_dbg(&port->dev, "baud requested = %d\n", baud);
L
Linus Torvalds 已提交
308
	if (baud) {
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
		/* Set baudrate to nearest supported value */
		for (k=0; k<ARRAY_SIZE(baud_sup); k++) {
			if (baud_sup[k] / baud) {
				baud_ceil = baud_sup[k];
				if (k==0) {
					baud = baud_ceil;
				} else {
					baud_floor = baud_sup[k-1];
					if ((baud_ceil % baud)
					    > (baud % baud_floor))
						baud = baud_floor;
					else
						baud = baud_ceil;
				}
				break;
			}
		}
		if (baud > 1228800) {
			/* type_0, type_1 only support up to 1228800 baud */
			if (priv->type != HX)
				baud = 1228800;
			else if (baud > 6000000)
				baud = 6000000;
		}
333
		dev_dbg(&port->dev, "baud set = %d\n", baud);
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
		if (baud <= 115200) {
			buf[0] = baud & 0xff;
			buf[1] = (baud >> 8) & 0xff;
			buf[2] = (baud >> 16) & 0xff;
			buf[3] = (baud >> 24) & 0xff;
		} else {
			/* apparently the formula for higher speeds is:
			 * baudrate = 12M * 32 / (2^buf[1]) / buf[0]
			 */
			unsigned tmp = 12*1000*1000*32 / baud;
			buf[3] = 0x80;
			buf[2] = 0;
			buf[1] = (tmp >= 256);
			while (tmp >= 256) {
				tmp >>= 2;
				buf[1] <<= 1;
			}
			buf[0] = tmp;
		}
L
Linus Torvalds 已提交
353 354 355 356 357 358
	}

	/* For reference buf[4]=0 is 1 stop bits */
	/* For reference buf[4]=1 is 1.5 stop bits */
	/* For reference buf[4]=2 is 2 stop bits */
	if (cflag & CSTOPB) {
359 360 361 362 363
		/* NOTE: Comply with "real" UARTs / RS232:
		 *       use 1.5 instead of 2 stop bits with 5 data bits
		 */
		if ((cflag & CSIZE) == CS5) {
			buf[4] = 1;
364
			dev_dbg(&port->dev, "stop bits = 1.5\n");
365 366
		} else {
			buf[4] = 2;
367
			dev_dbg(&port->dev, "stop bits = 2\n");
368
		}
L
Linus Torvalds 已提交
369 370
	} else {
		buf[4] = 0;
371
		dev_dbg(&port->dev, "stop bits = 1\n");
L
Linus Torvalds 已提交
372 373 374 375 376 377 378 379 380
	}

	if (cflag & PARENB) {
		/* For reference buf[5]=0 is none parity */
		/* For reference buf[5]=1 is odd parity */
		/* For reference buf[5]=2 is even parity */
		/* For reference buf[5]=3 is mark parity */
		/* For reference buf[5]=4 is space parity */
		if (cflag & PARODD) {
381 382
			if (cflag & CMSPAR) {
				buf[5] = 3;
383
				dev_dbg(&port->dev, "parity = mark\n");
384 385
			} else {
				buf[5] = 1;
386
				dev_dbg(&port->dev, "parity = odd\n");
387
			}
L
Linus Torvalds 已提交
388
		} else {
389 390
			if (cflag & CMSPAR) {
				buf[5] = 4;
391
				dev_dbg(&port->dev, "parity = space\n");
392 393
			} else {
				buf[5] = 2;
394
				dev_dbg(&port->dev, "parity = even\n");
395
			}
L
Linus Torvalds 已提交
396 397 398
		}
	} else {
		buf[5] = 0;
399
		dev_dbg(&port->dev, "parity = none\n");
L
Linus Torvalds 已提交
400 401
	}

402 403 404
	i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
			    SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE,
			    0, 0, buf, 7, 100);
405
	dev_dbg(&port->dev, "0x21:0x20:0:0  %d\n", i);
L
Linus Torvalds 已提交
406 407 408 409 410 411

	/* change control lines if we are switching to or from B0 */
	spin_lock_irqsave(&priv->lock, flags);
	control = priv->line_control;
	if ((cflag & CBAUD) == B0)
		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
412
	else if ((old_termios->c_cflag & CBAUD) == B0)
L
Linus Torvalds 已提交
413 414 415 416 417 418 419 420
		priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
	if (control != priv->line_control) {
		control = priv->line_control;
		spin_unlock_irqrestore(&priv->lock, flags);
		set_control_lines(serial->dev, control);
	} else {
		spin_unlock_irqrestore(&priv->lock, flags);
	}
421

L
Linus Torvalds 已提交
422 423
	buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0;

424 425 426
	i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
			    GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,
			    0, 0, buf, 7, 100);
427
	dev_dbg(&port->dev, "0xa1:0x21:0:0  %d - %x %x %x %x %x %x %x\n", i,
L
Linus Torvalds 已提交
428 429 430 431
	     buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);

	if (cflag & CRTSCTS) {
		if (priv->type == HX)
432
			pl2303_vendor_write(0x0, 0x61, serial);
L
Linus Torvalds 已提交
433
		else
434
			pl2303_vendor_write(0x0, 0x41, serial);
T
t.sefzick 已提交
435
	} else {
436
		pl2303_vendor_write(0x0, 0x0, serial);
L
Linus Torvalds 已提交
437
	}
438

439
	/* Save resulting baud rate */
440
	if (baud)
A
Alan Cox 已提交
441
		tty_encode_baud_rate(tty, baud, baud);
442

443 444 445
	kfree(buf);
}

446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
static void pl2303_dtr_rts(struct usb_serial_port *port, int on)
{
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	u8 control;

	spin_lock_irqsave(&priv->lock, flags);
	/* Change DTR and RTS */
	if (on)
		priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
	else
		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
	control = priv->line_control;
	spin_unlock_irqrestore(&priv->lock, flags);
	set_control_lines(port->serial->dev, control);
}

static void pl2303_close(struct usb_serial_port *port)
464
{
J
Johan Hovold 已提交
465
	usb_serial_generic_close(port);
466
	usb_kill_urb(port->interrupt_in_urb);
L
Linus Torvalds 已提交
467 468
}

469
static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
L
Linus Torvalds 已提交
470
{
A
Alan Cox 已提交
471
	struct ktermios tmp_termios;
L
Linus Torvalds 已提交
472 473 474 475
	struct usb_serial *serial = port->serial;
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	int result;

476 477 478
	if (priv->type != HX) {
		usb_clear_halt(serial->dev, port->write_urb->pipe);
		usb_clear_halt(serial->dev, port->read_urb->pipe);
479
	} else {
L
Linus Torvalds 已提交
480
		/* reset upstream data pipes */
481 482
		pl2303_vendor_write(8, 0, serial);
		pl2303_vendor_write(9, 0, serial);
L
Linus Torvalds 已提交
483 484 485
	}

	/* Setup termios */
A
Alan Cox 已提交
486 487
	if (tty)
		pl2303_set_termios(tty, port, &tmp_termios);
L
Linus Torvalds 已提交
488

489
	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
L
Linus Torvalds 已提交
490
	if (result) {
491
		dev_err(&port->dev, "%s - failed submitting interrupt urb,"
492
			" error %d\n", __func__, result);
493
		return result;
L
Linus Torvalds 已提交
494
	}
495

496
	result = usb_serial_generic_open(tty, port);
497 498 499 500 501
	if (result) {
		usb_kill_urb(port->interrupt_in_urb);
		return result;
	}

502
	port->port.drain_delay = 256;
L
Linus Torvalds 已提交
503 504 505
	return 0;
}

506
static int pl2303_tiocmset(struct tty_struct *tty,
507
			   unsigned int set, unsigned int clear)
L
Linus Torvalds 已提交
508
{
A
Alan Cox 已提交
509
	struct usb_serial_port *port = tty->driver_data;
510
	struct usb_serial *serial = port->serial;
L
Linus Torvalds 已提交
511 512 513
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	u8 control;
514
	int ret;
F
Flavio Leitner 已提交
515

516
	spin_lock_irqsave(&priv->lock, flags);
L
Linus Torvalds 已提交
517 518 519 520 521 522 523 524 525
	if (set & TIOCM_RTS)
		priv->line_control |= CONTROL_RTS;
	if (set & TIOCM_DTR)
		priv->line_control |= CONTROL_DTR;
	if (clear & TIOCM_RTS)
		priv->line_control &= ~CONTROL_RTS;
	if (clear & TIOCM_DTR)
		priv->line_control &= ~CONTROL_DTR;
	control = priv->line_control;
526
	spin_unlock_irqrestore(&priv->lock, flags);
L
Linus Torvalds 已提交
527

528 529 530 531 532 533 534 535
	mutex_lock(&serial->disc_mutex);
	if (!serial->disconnected)
		ret = set_control_lines(serial->dev, control);
	else
		ret = -ENODEV;
	mutex_unlock(&serial->disc_mutex);

	return ret;
L
Linus Torvalds 已提交
536 537
}

538
static int pl2303_tiocmget(struct tty_struct *tty)
L
Linus Torvalds 已提交
539
{
A
Alan Cox 已提交
540
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
541 542 543 544 545 546
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	unsigned int mcr;
	unsigned int status;
	unsigned int result;

547
	spin_lock_irqsave(&priv->lock, flags);
L
Linus Torvalds 已提交
548 549
	mcr = priv->line_control;
	status = priv->line_status;
550
	spin_unlock_irqrestore(&priv->lock, flags);
L
Linus Torvalds 已提交
551 552 553 554 555 556 557 558

	result = ((mcr & CONTROL_DTR)		? TIOCM_DTR : 0)
		  | ((mcr & CONTROL_RTS)	? TIOCM_RTS : 0)
		  | ((status & UART_CTS)	? TIOCM_CTS : 0)
		  | ((status & UART_DSR)	? TIOCM_DSR : 0)
		  | ((status & UART_RING)	? TIOCM_RI  : 0)
		  | ((status & UART_DCD)	? TIOCM_CD  : 0);

559
	dev_dbg(&port->dev, "%s - result = %x\n", __func__, result);
L
Linus Torvalds 已提交
560 561 562 563

	return result;
}

564 565 566 567 568 569 570 571
static int pl2303_carrier_raised(struct usb_serial_port *port)
{
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	if (priv->line_status & UART_DCD)
		return 1;
	return 0;
}

L
Linus Torvalds 已提交
572 573 574 575 576 577 578 579
static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
{
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	unsigned int prevstatus;
	unsigned int status;
	unsigned int changed;

580
	spin_lock_irqsave(&priv->lock, flags);
L
Linus Torvalds 已提交
581
	prevstatus = priv->line_status;
582
	spin_unlock_irqrestore(&priv->lock, flags);
L
Linus Torvalds 已提交
583 584 585 586 587 588

	while (1) {
		interruptible_sleep_on(&priv->delta_msr_wait);
		/* see if a signal did it */
		if (signal_pending(current))
			return -ERESTARTSYS;
589 590

		spin_lock_irqsave(&priv->lock, flags);
L
Linus Torvalds 已提交
591
		status = priv->line_status;
592 593
		spin_unlock_irqrestore(&priv->lock, flags);

A
Alan Cox 已提交
594
		changed = prevstatus ^ status;
595

L
Linus Torvalds 已提交
596 597 598
		if (((arg & TIOCM_RNG) && (changed & UART_RING)) ||
		    ((arg & TIOCM_DSR) && (changed & UART_DSR)) ||
		    ((arg & TIOCM_CD)  && (changed & UART_DCD)) ||
A
Alan Cox 已提交
599
		    ((arg & TIOCM_CTS) && (changed & UART_CTS))) {
L
Linus Torvalds 已提交
600 601 602 603 604 605 606 607
			return 0;
		}
		prevstatus = status;
	}
	/* NOTREACHED */
	return 0;
}

608
static int pl2303_ioctl(struct tty_struct *tty,
609
			unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
610
{
611
	struct serial_struct ser;
A
Alan Cox 已提交
612
	struct usb_serial_port *port = tty->driver_data;
613 614

	dev_dbg(&port->dev, "%s cmd = 0x%04x\n", __func__, cmd);
L
Linus Torvalds 已提交
615 616

	switch (cmd) {
617 618 619 620 621 622 623 624 625 626 627 628
	case TIOCGSERIAL:
		memset(&ser, 0, sizeof ser);
		ser.type = PORT_16654;
		ser.line = port->serial->minor;
		ser.port = port->number;
		ser.baud_base = 460800;

		if (copy_to_user((void __user *)arg, &ser, sizeof ser))
			return -EFAULT;

		return 0;

A
Alan Cox 已提交
629
	case TIOCMIWAIT:
630
		dev_dbg(&port->dev, "%s TIOCMIWAIT\n", __func__);
A
Alan Cox 已提交
631 632
		return wait_modem_info(port, arg);
	default:
633
		dev_dbg(&port->dev, "%s not supported = 0x%04x\n", __func__, cmd);
A
Alan Cox 已提交
634
		break;
L
Linus Torvalds 已提交
635 636 637 638
	}
	return -ENOIOCTLCMD;
}

A
Alan Cox 已提交
639
static void pl2303_break_ctl(struct tty_struct *tty, int break_state)
L
Linus Torvalds 已提交
640
{
A
Alan Cox 已提交
641
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
642 643 644 645 646 647 648 649
	struct usb_serial *serial = port->serial;
	u16 state;
	int result;

	if (break_state == 0)
		state = BREAK_OFF;
	else
		state = BREAK_ON;
650
	dev_dbg(&port->dev, "%s - turning break %s\n", __func__,
A
Alan Cox 已提交
651
			state == BREAK_OFF ? "off" : "on");
L
Linus Torvalds 已提交
652

653 654 655
	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
				 BREAK_REQUEST, BREAK_REQUEST_TYPE, state,
				 0, NULL, 0, 100);
L
Linus Torvalds 已提交
656
	if (result)
657
		dev_err(&port->dev, "error sending break = %d\n", result);
L
Linus Torvalds 已提交
658 659
}

660
static void pl2303_release(struct usb_serial *serial)
L
Linus Torvalds 已提交
661 662 663 664 665 666
{
	int i;
	struct pl2303_private *priv;

	for (i = 0; i < serial->num_ports; ++i) {
		priv = usb_get_serial_port_data(serial->port[i]);
667
		kfree(priv);
668
	}
L
Linus Torvalds 已提交
669 670
}

F
Flavio Leitner 已提交
671 672 673 674 675 676
static void pl2303_update_line_status(struct usb_serial_port *port,
				      unsigned char *data,
				      unsigned int actual_length)
{

	struct pl2303_private *priv = usb_get_serial_port_data(port);
677
	struct tty_struct *tty;
F
Flavio Leitner 已提交
678 679
	unsigned long flags;
	u8 status_idx = UART_STATE;
680
	u8 length = UART_STATE + 1;
681
	u8 prev_line_status;
682
	u16 idv, idp;
F
Flavio Leitner 已提交
683

684 685 686 687 688 689 690 691 692 693 694 695
	idv = le16_to_cpu(port->serial->dev->descriptor.idVendor);
	idp = le16_to_cpu(port->serial->dev->descriptor.idProduct);


	if (idv == SIEMENS_VENDOR_ID) {
		if (idp == SIEMENS_PRODUCT_ID_X65 ||
		    idp == SIEMENS_PRODUCT_ID_SX1 ||
		    idp == SIEMENS_PRODUCT_ID_X75) {

			length = 1;
			status_idx = 0;
		}
F
Flavio Leitner 已提交
696 697 698
	}

	if (actual_length < length)
699
		return;
F
Flavio Leitner 已提交
700

A
Alan Cox 已提交
701
	/* Save off the uart status for others to look at */
F
Flavio Leitner 已提交
702
	spin_lock_irqsave(&priv->lock, flags);
703
	prev_line_status = priv->line_status;
F
Flavio Leitner 已提交
704 705
	priv->line_status = data[status_idx];
	spin_unlock_irqrestore(&priv->lock, flags);
706 707
	if (priv->line_status & UART_BREAK_ERROR)
		usb_serial_handle_break(port);
708
	wake_up_interruptible(&priv->delta_msr_wait);
709 710 711 712 713 714 715 716

	tty = tty_port_tty_get(&port->port);
	if (!tty)
		return;
	if ((priv->line_status ^ prev_line_status) & UART_DCD)
		usb_serial_handle_dcd_change(port, tty,
				priv->line_status & UART_DCD);
	tty_kref_put(tty);
F
Flavio Leitner 已提交
717
}
L
Linus Torvalds 已提交
718

719
static void pl2303_read_int_callback(struct urb *urb)
L
Linus Torvalds 已提交
720
{
721
	struct usb_serial_port *port =  urb->context;
L
Linus Torvalds 已提交
722
	unsigned char *data = urb->transfer_buffer;
F
Flavio Leitner 已提交
723
	unsigned int actual_length = urb->actual_length;
724 725
	int status = urb->status;
	int retval;
L
Linus Torvalds 已提交
726

727
	switch (status) {
L
Linus Torvalds 已提交
728 729 730 731 732 733 734
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
735 736
		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
			__func__, status);
L
Linus Torvalds 已提交
737 738
		return;
	default:
739 740
		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
			__func__, status);
L
Linus Torvalds 已提交
741 742 743
		goto exit;
	}

744
	usb_serial_debug_data(debug, &port->dev, __func__,
745 746
			      urb->actual_length, urb->transfer_buffer);

F
Flavio Leitner 已提交
747
	pl2303_update_line_status(port, data, actual_length);
L
Linus Torvalds 已提交
748 749

exit:
750 751
	retval = usb_submit_urb(urb, GFP_ATOMIC);
	if (retval)
752
		dev_err(&port->dev,
753
			"%s - usb_submit_urb failed with result %d\n",
754
			__func__, retval);
L
Linus Torvalds 已提交
755 756
}

757
static void pl2303_process_read_urb(struct urb *urb)
758
{
759 760 761
	struct usb_serial_port *port = urb->context;
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	struct tty_struct *tty;
762 763
	unsigned char *data = urb->transfer_buffer;
	char tty_flag = TTY_NORMAL;
764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781
	unsigned long flags;
	u8 line_status;
	int i;

	/* update line status */
	spin_lock_irqsave(&priv->lock, flags);
	line_status = priv->line_status;
	priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
	spin_unlock_irqrestore(&priv->lock, flags);
	wake_up_interruptible(&priv->delta_msr_wait);

	if (!urb->actual_length)
		return;

	tty = tty_port_tty_get(&port->port);
	if (!tty)
		return;

782 783 784 785 786 787 788 789
	/* break takes precedence over parity, */
	/* which takes precedence over framing errors */
	if (line_status & UART_BREAK_ERROR)
		tty_flag = TTY_BREAK;
	else if (line_status & UART_PARITY_ERROR)
		tty_flag = TTY_PARITY;
	else if (line_status & UART_FRAME_ERROR)
		tty_flag = TTY_FRAME;
790
	dev_dbg(&port->dev, "%s - tty_flag = %d\n", __func__, tty_flag);
791 792 793 794

	/* overrun is special, not associated with a char */
	if (line_status & UART_OVERRUN_ERROR)
		tty_insert_flip_char(tty, 0, TTY_OVERRUN);
795

796
	if (port->port.console && port->sysrq) {
797
		for (i = 0; i < urb->actual_length; ++i)
798
			if (!usb_serial_handle_sysrq_char(port, data[i]))
799
				tty_insert_flip_char(tty, data[i], tty_flag);
800 801 802
	} else {
		tty_insert_flip_string_fixed_flag(tty, data, tty_flag,
							urb->actual_length);
803
	}
L
Linus Torvalds 已提交
804

805
	tty_flip_buffer_push(tty);
A
Alan Cox 已提交
806
	tty_kref_put(tty);
L
Linus Torvalds 已提交
807 808
}

809 810 811 812 813 814 815 816
/* All of the device info needed for the PL2303 SIO serial converter */
static struct usb_serial_driver pl2303_device = {
	.driver = {
		.owner =	THIS_MODULE,
		.name =		"pl2303",
	},
	.id_table =		id_table,
	.num_ports =		1,
817
	.bulk_in_size =		256,
818
	.bulk_out_size =	256,
819 820
	.open =			pl2303_open,
	.close =		pl2303_close,
821 822
	.dtr_rts = 		pl2303_dtr_rts,
	.carrier_raised =	pl2303_carrier_raised,
823 824 825 826 827
	.ioctl =		pl2303_ioctl,
	.break_ctl =		pl2303_break_ctl,
	.set_termios =		pl2303_set_termios,
	.tiocmget =		pl2303_tiocmget,
	.tiocmset =		pl2303_tiocmset,
828
	.process_read_urb =	pl2303_process_read_urb,
829 830
	.read_int_callback =	pl2303_read_int_callback,
	.attach =		pl2303_startup,
831
	.release =		pl2303_release,
832
};
L
Linus Torvalds 已提交
833

834 835 836 837
static struct usb_serial_driver * const serial_drivers[] = {
	&pl2303_device, NULL
};

838
module_usb_serial_driver(serial_drivers, id_table);
L
Linus Torvalds 已提交
839 840 841 842 843 844 845

MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");