pl2303.c 32.7 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
Linus Torvalds's avatar
Linus Torvalds committed
2
3
4
/*
 * Prolific PL2303 USB to serial adaptor driver
 *
5
 * Copyright (C) 2001-2007 Greg Kroah-Hartman (greg@kroah.com)
Linus Torvalds's avatar
Linus Torvalds committed
6
7
8
9
 * Copyright (C) 2003 IBM Corp.
 *
 * Original driver for 2.2.x by anonymous
 *
10
 * See Documentation/usb/usb-serial.rst for more information on using this
Alan Cox's avatar
Alan Cox committed
11
 * driver
Linus Torvalds's avatar
Linus Torvalds committed
12
13
14
15
16
17
18
19
20
21
22
23
 */

#include <linux/kernel.h>
#include <linux/errno.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>
Alan Cox's avatar
Alan Cox committed
24
#include <linux/uaccess.h>
Linus Torvalds's avatar
Linus Torvalds committed
25
#include <linux/usb.h>
26
#include <linux/usb/serial.h>
27
#include <asm/unaligned.h>
Linus Torvalds's avatar
Linus Torvalds committed
28
29
#include "pl2303.h"

30
31

#define PL2303_QUIRK_UART_STATE_IDX0		BIT(0)
32
#define PL2303_QUIRK_LEGACY			BIT(1)
33
#define PL2303_QUIRK_ENDPOINT_HACK		BIT(2)
34

35
static const struct usb_device_id id_table[] = {
36
37
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID),
		.driver_info = PL2303_QUIRK_ENDPOINT_HACK },
Linus Torvalds's avatar
Linus Torvalds committed
38
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
39
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) },
Linus Torvalds's avatar
Linus Torvalds committed
40
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
41
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_CHILITAG) },
Linus Torvalds's avatar
Linus Torvalds committed
42
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
Max Arnold's avatar
Max Arnold committed
43
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
Steve Murphy's avatar
Steve Murphy committed
44
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
45
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
46
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
47
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) },
48
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ZTEK) },
49
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_TB) },
50
51
52
53
54
55
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GC) },
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GB) },
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GT) },
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GL) },
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GE) },
	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GS) },
Linus Torvalds's avatar
Linus Torvalds committed
56
	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
57
	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
58
59
	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID),
		.driver_info = PL2303_QUIRK_ENDPOINT_HACK },
60
61
	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_UC485),
		.driver_info = PL2303_QUIRK_ENDPOINT_HACK },
62
63
	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_UC232B),
		.driver_info = PL2303_QUIRK_ENDPOINT_HACK },
64
	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID2) },
Linus Torvalds's avatar
Linus Torvalds committed
65
66
67
68
	{ 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) },
69
	{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) },
Linus Torvalds's avatar
Linus Torvalds committed
70
71
72
73
74
75
76
	{ 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) },
77
78
79
80
81
82
	{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1),
		.driver_info = PL2303_QUIRK_UART_STATE_IDX0 },
	{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65),
		.driver_info = PL2303_QUIRK_UART_STATE_IDX0 },
	{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75),
		.driver_info = PL2303_QUIRK_UART_STATE_IDX0 },
83
84
	{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_EF81),
		.driver_info = PL2303_QUIRK_ENDPOINT_HACK },
85
	{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_ID_S81) }, /* Benq/Siemens S81 */
86
	{ USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },
87
88
	{ USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) },
	{ USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) },
89
	{ USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) },
90
	{ USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) },
91
	{ USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) },
92
	{ USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
93
	{ USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
94
95
	{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID),
		.driver_info = PL2303_QUIRK_ENDPOINT_HACK },
96
	{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
97
	{ USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
98
	{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
Matthew Arnold's avatar
Matthew Arnold committed
99
	{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
100
	{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
101
	{ USB_DEVICE(HP_VENDOR_ID, HP_LD220TA_PRODUCT_ID) },
102
	{ USB_DEVICE(HP_VENDOR_ID, HP_LD381_PRODUCT_ID) },
103
	{ USB_DEVICE(HP_VENDOR_ID, HP_LD381GC_PRODUCT_ID) },
104
	{ USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) },
105
	{ USB_DEVICE(HP_VENDOR_ID, HP_LD960TA_PRODUCT_ID) },
106
107
	{ USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) },
	{ USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) },
108
109
110
	{ USB_DEVICE(HP_VENDOR_ID, HP_LM920_PRODUCT_ID) },
	{ USB_DEVICE(HP_VENDOR_ID, HP_LM940_PRODUCT_ID) },
	{ USB_DEVICE(HP_VENDOR_ID, HP_TD620_PRODUCT_ID) },
111
	{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
112
	{ USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
113
	{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
114
	{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
115
	{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
116
	{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530GC_PRODUCT_ID) },
117
	{ USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },
118
	{ USB_DEVICE(AT_VENDOR_ID, AT_VTKIT3_PRODUCT_ID) },
Linus Torvalds's avatar
Linus Torvalds committed
119
120
121
	{ }					/* Terminating entry */
};

122
MODULE_DEVICE_TABLE(usb, id_table);
Linus Torvalds's avatar
Linus Torvalds committed
123
124
125
126
127
128
129
130
131
132

#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
Alan Cox's avatar
Alan Cox committed
133
#define BREAK_REQUEST			0x23
Linus Torvalds's avatar
Linus Torvalds committed
134
135
136
137
138
139
140
141
#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
142
#define VENDOR_WRITE_NREQUEST		0x80
Linus Torvalds's avatar
Linus Torvalds committed
143
144
145

#define VENDOR_READ_REQUEST_TYPE	0xc0
#define VENDOR_READ_REQUEST		0x01
146
#define VENDOR_READ_NREQUEST		0x81
Linus Torvalds's avatar
Linus Torvalds committed
147

148
#define UART_STATE_INDEX		8
149
#define UART_STATE_MSR_MASK		0x8b
Linus Torvalds's avatar
Linus Torvalds committed
150
151
152
153
154
155
156
157
158
159
#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

160
161
#define PL2303_FLOWCTRL_MASK		0xf0

162
163
164
165
166
167
168
169
170
171
172
173
#define PL2303_READ_TYPE_HX_STATUS	0x8080

#define PL2303_HXN_RESET_REG		0x07
#define PL2303_HXN_RESET_UPSTREAM_PIPE	0x02
#define PL2303_HXN_RESET_DOWNSTREAM_PIPE	0x01

#define PL2303_HXN_FLOWCTRL_REG		0x0a
#define PL2303_HXN_FLOWCTRL_MASK	0x1c
#define PL2303_HXN_FLOWCTRL_NONE	0x1c
#define PL2303_HXN_FLOWCTRL_RTS_CTS	0x18
#define PL2303_HXN_FLOWCTRL_XON_XOFF	0x0c

174
static void pl2303_set_break(struct usb_serial_port *port, bool enable);
Linus Torvalds's avatar
Linus Torvalds committed
175
176

enum pl2303_type {
177
	TYPE_H,
178
179
180
181
182
	TYPE_HX,
	TYPE_TA,
	TYPE_TB,
	TYPE_HXD,
	TYPE_HXN,
183
184
185
186
	TYPE_COUNT
};

struct pl2303_type_data {
187
	const char *name;
188
189
	speed_t max_baud_rate;
	unsigned long quirks;
190
	unsigned int no_autoxonxoff:1;
191
	unsigned int no_divisors:1;
192
	unsigned int alt_divisors:1;
Linus Torvalds's avatar
Linus Torvalds committed
193
194
};

195
struct pl2303_serial_private {
196
	const struct pl2303_type_data *type;
197
	unsigned long quirks;
198
199
};

Linus Torvalds's avatar
Linus Torvalds committed
200
201
202
203
struct pl2303_private {
	spinlock_t lock;
	u8 line_control;
	u8 line_status;
204
205

	u8 line_settings[7];
Linus Torvalds's avatar
Linus Torvalds committed
206
207
};

208
static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {
209
	[TYPE_H] = {
210
		.name			= "H",
211
212
213
		.max_baud_rate		= 1228800,
		.quirks			= PL2303_QUIRK_LEGACY,
		.no_autoxonxoff		= true,
214
	},
215
	[TYPE_HX] = {
216
		.name			= "HX",
217
218
219
		.max_baud_rate		= 6000000,
	},
	[TYPE_TA] = {
220
		.name			= "TA",
221
		.max_baud_rate		= 6000000,
222
		.alt_divisors		= true,
223
224
	},
	[TYPE_TB] = {
225
		.name			= "TB",
226
		.max_baud_rate		= 12000000,
227
		.alt_divisors		= true,
228
229
	},
	[TYPE_HXD] = {
230
		.name			= "HXD",
231
		.max_baud_rate		= 12000000,
232
	},
233
	[TYPE_HXN] = {
234
		.name			= "G",
235
		.max_baud_rate		= 12000000,
236
		.no_divisors		= true,
237
	},
238
239
};

240
241
static int pl2303_vendor_read(struct usb_serial *serial, u16 value,
							unsigned char buf[1])
242
{
243
	struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
244
	struct device *dev = &serial->interface->dev;
245
	u8 request;
246
247
	int res;

248
249
250
251
252
	if (spriv->type == &pl2303_type_data[TYPE_HXN])
		request = VENDOR_READ_NREQUEST;
	else
		request = VENDOR_READ_REQUEST;

253
	res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
254
			request, VENDOR_READ_REQUEST_TYPE,
255
256
257
258
259
260
261
262
263
			value, 0, buf, 1, 100);
	if (res != 1) {
		dev_err(dev, "%s - failed to read [%04x]: %d\n", __func__,
								value, res);
		if (res >= 0)
			res = -EIO;

		return res;
	}
264

265
	dev_dbg(dev, "%s - [%04x] = %02x\n", __func__, value, buf[0]);
266

267
	return 0;
268
269
}

270
static int pl2303_vendor_write(struct usb_serial *serial, u16 value, u16 index)
271
{
272
	struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
273
	struct device *dev = &serial->interface->dev;
274
	u8 request;
275
276
	int res;

277
278
	dev_dbg(dev, "%s - [%04x] = %02x\n", __func__, value, index);

279
280
281
282
283
	if (spriv->type == &pl2303_type_data[TYPE_HXN])
		request = VENDOR_WRITE_NREQUEST;
	else
		request = VENDOR_WRITE_REQUEST;

284
	res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
285
			request, VENDOR_WRITE_REQUEST_TYPE,
286
			value, index, NULL, 0, 100);
287
288
289
290
291
	if (res) {
		dev_err(dev, "%s - failed to write [%04x]: %d\n", __func__,
								value, res);
		return res;
	}
292

293
	return 0;
294
295
}

296
297
static int pl2303_update_reg(struct usb_serial *serial, u8 reg, u8 mask, u8 val)
{
298
	struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
299
300
301
302
303
304
305
	int ret = 0;
	u8 *buf;

	buf = kmalloc(1, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

306
307
308
309
310
	if (spriv->type == &pl2303_type_data[TYPE_HXN])
		ret = pl2303_vendor_read(serial, reg, buf);
	else
		ret = pl2303_vendor_read(serial, reg | 0x80, buf);

311
312
313
314
315
316
317
318
319
320
321
322
323
	if (ret)
		goto out_free;

	*buf &= ~mask;
	*buf |= val & mask;

	ret = pl2303_vendor_write(serial, reg, *buf);
out_free:
	kfree(buf);

	return ret;
}

324
325
326
327
328
329
330
331
static int pl2303_probe(struct usb_serial *serial,
					const struct usb_device_id *id)
{
	usb_set_serial_data(serial, (void *)id->driver_info);

	return 0;
}

332
333
334
335
336
337
/*
 * Use interrupt endpoint from first interface if available.
 *
 * This is needed due to the looney way its endpoints are set up.
 */
static int pl2303_endpoint_hack(struct usb_serial *serial,
338
339
340
341
342
343
344
345
346
					struct usb_serial_endpoints *epds)
{
	struct usb_interface *interface = serial->interface;
	struct usb_device *dev = serial->dev;
	struct device *ddev = &interface->dev;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	unsigned int i;

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
	if (interface == dev->actconfig->interface[0])
		return 0;

	/* check out the endpoints of the other interface */
	iface_desc = dev->actconfig->interface[0]->cur_altsetting;

	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (!usb_endpoint_is_int_in(endpoint))
			continue;

		dev_dbg(ddev, "found interrupt in on separate interface\n");
		if (epds->num_interrupt_in < ARRAY_SIZE(epds->interrupt_in))
			epds->interrupt_in[epds->num_interrupt_in++] = endpoint;
	}

	return 0;
}

static int pl2303_calc_num_ports(struct usb_serial *serial,
					struct usb_serial_endpoints *epds)
{
	unsigned long quirks = (unsigned long)usb_get_serial_data(serial);
	struct device *dev = &serial->interface->dev;
	int ret;

	if (quirks & PL2303_QUIRK_ENDPOINT_HACK) {
		ret = pl2303_endpoint_hack(serial, epds);
		if (ret)
			return ret;
378
379
380
	}

	if (epds->num_interrupt_in < 1) {
381
		dev_err(dev, "required interrupt-in endpoint missing\n");
382
383
384
385
386
387
		return -ENODEV;
	}

	return 1;
}

388
389
390
391
392
393
394
395
396
397
398
399
static bool pl2303_supports_hx_status(struct usb_serial *serial)
{
	int ret;
	u8 buf;

	ret = usb_control_msg_recv(serial->dev, 0, VENDOR_READ_REQUEST,
			VENDOR_READ_REQUEST_TYPE, PL2303_READ_TYPE_HX_STATUS,
			0, &buf, 1, 100, GFP_KERNEL);

	return ret == 0;
}

400
static int pl2303_detect_type(struct usb_serial *serial)
401
402
{
	struct usb_device_descriptor *desc = &serial->dev->descriptor;
403
	u16 bcdDevice, bcdUSB;
404
405

	/*
406
	 * Legacy PL2303H, variants 0 and 1 (difference unknown).
407
408
	 */
	if (desc->bDeviceClass == 0x02)
409
		return TYPE_H;		/* variant 0 */
410
411
412

	if (desc->bMaxPacketSize0 != 0x40) {
		if (desc->bDeviceClass == 0x00 || desc->bDeviceClass == 0xff)
413
			return TYPE_H;	/* variant 1 */
414

415
		return TYPE_H;		/* variant 0 */
416
417
	}

418
419
420
	bcdDevice = le16_to_cpu(desc->bcdDevice);
	bcdUSB = le16_to_cpu(desc->bcdUSB);

421
422
423
424
425
426
427
428
429
430
	switch (bcdUSB) {
	case 0x110:
		switch (bcdDevice) {
		case 0x300:
			return TYPE_HX;
		case 0x400:
			return TYPE_HXD;
		default:
			return TYPE_HX;
		}
431
		break;
432
433
434
	case 0x200:
		switch (bcdDevice) {
		case 0x100:
435
		case 0x305:
436
		case 0x405:
437
438
439
440
441
442
443
444
			/*
			 * Assume it's an HXN-type if the device doesn't
			 * support the old read request value.
			 */
			if (!pl2303_supports_hx_status(serial))
				return TYPE_HXN;
			break;
		case 0x300:
445
			return TYPE_TA;
446
447
448
449
		case 0x500:
			return TYPE_TB;
		}
		break;
450
451
452
453
454
	}

	dev_err(&serial->interface->dev,
			"unknown device type, please report to linux-usb@vger.kernel.org\n");
	return -ENODEV;
455
456
}

457
static int pl2303_startup(struct usb_serial *serial)
Linus Torvalds's avatar
Linus Torvalds committed
458
{
459
	struct pl2303_serial_private *spriv;
460
	enum pl2303_type type;
461
	unsigned char *buf;
462
463
464
465
466
467
468
	int ret;

	ret = pl2303_detect_type(serial);
	if (ret < 0)
		return ret;

	type = ret;
469
	dev_dbg(&serial->interface->dev, "device type: %s\n", pl2303_type_data[type].name);
470
471
472
473

	spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
	if (!spriv)
		return -ENOMEM;
Linus Torvalds's avatar
Linus Torvalds committed
474

475
	spriv->type = &pl2303_type_data[type];
476
	spriv->quirks = (unsigned long)usb_get_serial_data(serial);
477
	spriv->quirks |= spriv->type->quirks;
478

479
	usb_set_serial_data(serial, spriv);
480

481
	if (type != TYPE_HXN) {
482
483
484
485
486
487
		buf = kmalloc(1, GFP_KERNEL);
		if (!buf) {
			kfree(spriv);
			return -ENOMEM;
		}

488
489
490
491
492
493
494
495
496
497
498
499
500
501
		pl2303_vendor_read(serial, 0x8484, buf);
		pl2303_vendor_write(serial, 0x0404, 0);
		pl2303_vendor_read(serial, 0x8484, buf);
		pl2303_vendor_read(serial, 0x8383, buf);
		pl2303_vendor_read(serial, 0x8484, buf);
		pl2303_vendor_write(serial, 0x0404, 1);
		pl2303_vendor_read(serial, 0x8484, buf);
		pl2303_vendor_read(serial, 0x8383, buf);
		pl2303_vendor_write(serial, 0, 1);
		pl2303_vendor_write(serial, 1, 0);
		if (spriv->quirks & PL2303_QUIRK_LEGACY)
			pl2303_vendor_write(serial, 2, 0x24);
		else
			pl2303_vendor_write(serial, 2, 0x44);
502

503
504
		kfree(buf);
	}
505

Linus Torvalds's avatar
Linus Torvalds committed
506
	return 0;
507
}
Linus Torvalds's avatar
Linus Torvalds committed
508

509
510
static void pl2303_release(struct usb_serial *serial)
{
511
	struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

	kfree(spriv);
}

static int pl2303_port_probe(struct usb_serial_port *port)
{
	struct pl2303_private *priv;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	spin_lock_init(&priv->lock);

	usb_set_serial_port_data(port, priv);

528
529
	port->port.drain_delay = 256;

530
531
532
	return 0;
}

533
static void pl2303_port_remove(struct usb_serial_port *port)
534
{
535
	struct pl2303_private *priv = usb_get_serial_port_data(port);
536
537

	kfree(priv);
Linus Torvalds's avatar
Linus Torvalds committed
538
539
}

540
static int pl2303_set_control_lines(struct usb_serial_port *port, u8 value)
Linus Torvalds's avatar
Linus Torvalds committed
541
{
542
	struct usb_device *dev = port->serial->dev;
Linus Torvalds's avatar
Linus Torvalds committed
543
	int retval;
Alan Cox's avatar
Alan Cox committed
544

545
546
	dev_dbg(&port->dev, "%s - %02x\n", __func__, value);

547
548
549
	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
				 SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,
				 value, 0, NULL, 0, 100);
550
551
	if (retval)
		dev_err(&port->dev, "%s - failed: %d\n", __func__, retval);
552

Linus Torvalds's avatar
Linus Torvalds committed
553
554
555
	return retval;
}

556
/*
557
558
 * Returns the nearest supported baud rate that can be set directly without
 * using divisors.
559
560
 */
static speed_t pl2303_get_supported_baud_rate(speed_t baud)
Linus Torvalds's avatar
Linus Torvalds committed
561
{
562
563
564
	static const speed_t baud_sup[] = {
		75, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600,
		14400, 19200, 28800, 38400, 57600, 115200, 230400, 460800,
565
		614400, 921600, 1228800, 2457600, 3000000, 6000000
566
	};
Linus Torvalds's avatar
Linus Torvalds committed
567

568
	unsigned i;
569

570
571
572
573
	for (i = 0; i < ARRAY_SIZE(baud_sup); ++i) {
		if (baud_sup[i] > baud)
			break;
	}
574

575
576
577
578
579
580
	if (i == ARRAY_SIZE(baud_sup))
		baud = baud_sup[i - 1];
	else if (i > 0 && (baud_sup[i] - baud) > (baud - baud_sup[i - 1]))
		baud = baud_sup[i - 1];
	else
		baud = baud_sup[i];
581

582
583
584
	return baud;
}

585
586
587
588
589
590
591
592
593
594
595
596
/*
 * NOTE: If unsupported baud rates are set directly, the PL2303 seems to
 *       use 9600 baud.
 */
static speed_t pl2303_encode_baud_rate_direct(unsigned char buf[4],
								speed_t baud)
{
	put_unaligned_le32(baud, buf);

	return baud;
}

597
598
599
static speed_t pl2303_encode_baud_rate_divisor(unsigned char buf[4],
								speed_t baud)
{
600
	unsigned int baseline, mantissa, exponent;
601
602
603

	/*
	 * Apparently the formula is:
604
605
606
607
	 *   baudrate = 12M * 32 / (mantissa * 4^exponent)
	 * where
	 *   mantissa = buf[8:0]
	 *   exponent = buf[11:9]
608
	 */
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
	baseline = 12000000 * 32;
	mantissa = baseline / baud;
	if (mantissa == 0)
		mantissa = 1;	/* Avoid dividing by zero if baud > 32*12M. */
	exponent = 0;
	while (mantissa >= 512) {
		if (exponent < 7) {
			mantissa >>= 2;	/* divide by 4 */
			exponent++;
		} else {
			/* Exponent is maxed. Trim mantissa and leave. */
			mantissa = 511;
			break;
		}
	}

625
626
	buf[3] = 0x80;
	buf[2] = 0;
627
628
629
630
631
	buf[1] = exponent << 1 | mantissa >> 8;
	buf[0] = mantissa & 0xff;

	/* Calculate and return the exact baud rate. */
	baud = (baseline / mantissa) >> (exponent << 1);
632
633
634
635

	return baud;
}

636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
static speed_t pl2303_encode_baud_rate_divisor_alt(unsigned char buf[4],
								speed_t baud)
{
	unsigned int baseline, mantissa, exponent;

	/*
	 * Apparently, for the TA version the formula is:
	 *   baudrate = 12M * 32 / (mantissa * 2^exponent)
	 * where
	 *   mantissa = buf[10:0]
	 *   exponent = buf[15:13 16]
	 */
	baseline = 12000000 * 32;
	mantissa = baseline / baud;
	if (mantissa == 0)
		mantissa = 1;   /* Avoid dividing by zero if baud > 32*12M. */
	exponent = 0;
	while (mantissa >= 2048) {
		if (exponent < 15) {
			mantissa >>= 1; /* divide by 2 */
			exponent++;
		} else {
			/* Exponent is maxed. Trim mantissa and leave. */
			mantissa = 2047;
			break;
		}
	}

	buf[3] = 0x80;
	buf[2] = exponent & 0x01;
	buf[1] = (exponent & ~0x01) << 4 | mantissa >> 8;
	buf[0] = mantissa & 0xff;

	/* Calculate and return the exact baud rate. */
	baud = (baseline / mantissa) >> exponent;

	return baud;
}

675
676
677
678
679
680
static void pl2303_encode_baud_rate(struct tty_struct *tty,
					struct usb_serial_port *port,
					u8 buf[4])
{
	struct usb_serial *serial = port->serial;
	struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
681
	speed_t	baud_sup;
682
683
684
685
686
687
	speed_t baud;

	baud = tty_get_baud_rate(tty);
	dev_dbg(&port->dev, "baud requested = %u\n", baud);
	if (!baud)
		return;
688
689
690

	if (spriv->type->max_baud_rate)
		baud = min_t(speed_t, baud, spriv->type->max_baud_rate);
691
	/*
692
	 * Use direct method for supported baud rates, otherwise use divisors.
693
	 * Newer chip types do not support divisor encoding.
694
	 */
695
696
697
698
	if (spriv->type->no_divisors)
		baud_sup = baud;
	else
		baud_sup = pl2303_get_supported_baud_rate(baud);
699

700
701
	if (baud == baud_sup)
		baud = pl2303_encode_baud_rate_direct(buf, baud);
702
703
	else if (spriv->type->alt_divisors)
		baud = pl2303_encode_baud_rate_divisor_alt(buf, baud);
704
	else
705
		baud = pl2303_encode_baud_rate_divisor(buf, baud);
706

707
	/* Save resulting baud rate */
708
	tty_encode_baud_rate(tty, baud, baud);
709
	dev_dbg(&port->dev, "baud set = %u\n", baud);
710
711
}

712
713
714
715
716
717
718
719
720
721
722
723
static int pl2303_get_line_request(struct usb_serial_port *port,
							unsigned char buf[7])
{
	struct usb_device *udev = port->serial->dev;
	int ret;

	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
				GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,
				0, 0, buf, 7, 100);
	if (ret != 7) {
		dev_err(&port->dev, "%s - failed: %d\n", __func__, ret);

724
		if (ret >= 0)
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
			ret = -EIO;

		return ret;
	}

	dev_dbg(&port->dev, "%s - %7ph\n", __func__, buf);

	return 0;
}

static int pl2303_set_line_request(struct usb_serial_port *port,
							unsigned char buf[7])
{
	struct usb_device *udev = port->serial->dev;
	int ret;

	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
				SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE,
				0, 0, buf, 7, 100);
744
	if (ret < 0) {
745
746
747
748
749
750
751
752
753
		dev_err(&port->dev, "%s - failed: %d\n", __func__, ret);
		return ret;
	}

	dev_dbg(&port->dev, "%s - %7ph\n", __func__, buf);

	return 0;
}

754
755
756
757
758
759
760
761
762
763
764
static bool pl2303_termios_change(const struct ktermios *a, const struct ktermios *b)
{
	bool ixon_change;

	ixon_change = ((a->c_iflag ^ b->c_iflag) & (IXON | IXANY)) ||
			a->c_cc[VSTART] != b->c_cc[VSTART] ||
			a->c_cc[VSTOP] != b->c_cc[VSTOP];

	return tty_termios_hw_change(a, b) || ixon_change;
}

765
766
767
768
769
770
771
772
773
774
775
776
777
778
static bool pl2303_enable_xonxoff(struct tty_struct *tty, const struct pl2303_type_data *type)
{
	if (!I_IXON(tty) || I_IXANY(tty))
		return false;

	if (START_CHAR(tty) != 0x11 || STOP_CHAR(tty) != 0x13)
		return false;

	if (type->no_autoxonxoff)
		return false;

	return true;
}

779
780
781
782
783
784
785
786
static void pl2303_set_termios(struct tty_struct *tty,
		struct usb_serial_port *port, struct ktermios *old_termios)
{
	struct usb_serial *serial = port->serial;
	struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	unsigned char *buf;
787
	int ret;
788
789
	u8 control;

790
	if (old_termios && !pl2303_termios_change(&tty->termios, old_termios))
791
792
793
794
795
796
797
798
799
800
		return;

	buf = kzalloc(7, GFP_KERNEL);
	if (!buf) {
		/* Report back no change occurred */
		if (old_termios)
			tty->termios = *old_termios;
		return;
	}

801
	pl2303_get_line_request(port, buf);
802

803
	buf[6] = tty_get_char_size(tty->termios.c_cflag);
804
	dev_dbg(&port->dev, "data bits = %d\n", buf[6]);
805

806
	/* For reference buf[0]:buf[3] baud rate value */
807
	pl2303_encode_baud_rate(tty, port, &buf[0]);
808

Linus Torvalds's avatar
Linus Torvalds committed
809
810
811
	/* 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 */
812
813
814
	if (C_CSTOPB(tty)) {
		/*
		 * NOTE: Comply with "real" UARTs / RS232:
815
816
		 *       use 1.5 instead of 2 stop bits with 5 data bits
		 */
817
		if (C_CSIZE(tty) == CS5) {
818
			buf[4] = 1;
819
			dev_dbg(&port->dev, "stop bits = 1.5\n");
820
821
		} else {
			buf[4] = 2;
822
			dev_dbg(&port->dev, "stop bits = 2\n");
823
		}
Linus Torvalds's avatar
Linus Torvalds committed
824
825
	} else {
		buf[4] = 0;
826
		dev_dbg(&port->dev, "stop bits = 1\n");
Linus Torvalds's avatar
Linus Torvalds committed
827
828
	}

829
	if (C_PARENB(tty)) {
Linus Torvalds's avatar
Linus Torvalds committed
830
831
832
833
834
		/* 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 */
835
		if (C_PARODD(tty)) {
Johan Hovold's avatar
Johan Hovold committed
836
			if (C_CMSPAR(tty)) {
837
				buf[5] = 3;
838
				dev_dbg(&port->dev, "parity = mark\n");
839
840
			} else {
				buf[5] = 1;
841
				dev_dbg(&port->dev, "parity = odd\n");
842
			}
Linus Torvalds's avatar
Linus Torvalds committed
843
		} else {
Johan Hovold's avatar
Johan Hovold committed
844
			if (C_CMSPAR(tty)) {
845
				buf[5] = 4;
846
				dev_dbg(&port->dev, "parity = space\n");
847
848
			} else {
				buf[5] = 2;
849
				dev_dbg(&port->dev, "parity = even\n");
850
			}
Linus Torvalds's avatar
Linus Torvalds committed
851
852
853
		}
	} else {
		buf[5] = 0;
854
		dev_dbg(&port->dev, "parity = none\n");
Linus Torvalds's avatar
Linus Torvalds committed
855
856
	}

857
858
859
860
861
862
863
864
865
866
867
868
869
	/*
	 * Some PL2303 are known 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.
	 *
	 * Note that the tty_termios_hw_change check above is not sufficient
	 * as a previously requested baud rate may differ from the one
	 * actually used (and stored in old_termios).
	 *
	 * NOTE: No additional locking needed for line_settings as it is
	 *       only used in set_termios, which is serialised against itself.
	 */
	if (!old_termios || memcmp(buf, priv->line_settings, 7)) {
870
871
		ret = pl2303_set_line_request(port, buf);
		if (!ret)
872
873
			memcpy(priv->line_settings, buf, 7);
	}
Linus Torvalds's avatar
Linus Torvalds committed
874
875
876
877

	/* change control lines if we are switching to or from B0 */
	spin_lock_irqsave(&priv->lock, flags);
	control = priv->line_control;
878
	if (C_BAUD(tty) == B0)
Linus Torvalds's avatar
Linus Torvalds committed
879
		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
880
	else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
Linus Torvalds's avatar
Linus Torvalds committed
881
882
883
884
		priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
	if (control != priv->line_control) {
		control = priv->line_control;
		spin_unlock_irqrestore(&priv->lock, flags);
885
		pl2303_set_control_lines(port, control);
Linus Torvalds's avatar
Linus Torvalds committed
886
887
888
	} else {
		spin_unlock_irqrestore(&priv->lock, flags);
	}
889

890
	if (C_CRTSCTS(tty)) {
891
		if (spriv->quirks & PL2303_QUIRK_LEGACY) {
892
			pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0x40);
893
894
895
896
897
		} else if (spriv->type == &pl2303_type_data[TYPE_HXN]) {
			pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG,
					PL2303_HXN_FLOWCTRL_MASK,
					PL2303_HXN_FLOWCTRL_RTS_CTS);
		} else {
898
			pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0x60);
899
		}
900
	} else if (pl2303_enable_xonxoff(tty, spriv->type)) {
901
902
903
904
905
906
907
		if (spriv->type == &pl2303_type_data[TYPE_HXN]) {
			pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG,
					PL2303_HXN_FLOWCTRL_MASK,
					PL2303_HXN_FLOWCTRL_XON_XOFF);
		} else {
			pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0xc0);
		}
t.sefzick's avatar
t.sefzick committed
908
	} else {
909
910
911
912
913
914
915
		if (spriv->type == &pl2303_type_data[TYPE_HXN]) {
			pl2303_update_reg(serial, PL2303_HXN_FLOWCTRL_REG,
					PL2303_HXN_FLOWCTRL_MASK,
					PL2303_HXN_FLOWCTRL_NONE);
		} else {
			pl2303_update_reg(serial, 0, PL2303_FLOWCTRL_MASK, 0);
		}
Linus Torvalds's avatar
Linus Torvalds committed
916
	}
917
918
919
920

	kfree(buf);
}

921
922
923
924
925
926
927
928
929
930
931
932
933
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);
	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);
934

935
	pl2303_set_control_lines(port, control);
936
937
938
}

static void pl2303_close(struct usb_serial_port *port)
939
{
Johan Hovold's avatar
Johan Hovold committed
940
	usb_serial_generic_close(port);
941
	usb_kill_urb(port->interrupt_in_urb);
942
	pl2303_set_break(port, false);
Linus Torvalds's avatar
Linus Torvalds committed
943
944
}

945
static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
Linus Torvalds's avatar
Linus Torvalds committed
946
947
{
	struct usb_serial *serial = port->serial;
948
	struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
Linus Torvalds's avatar
Linus Torvalds committed
949
950
	int result;

951
	if (spriv->quirks & PL2303_QUIRK_LEGACY) {
952
953
		usb_clear_halt(serial->dev, port->write_urb->pipe);
		usb_clear_halt(serial->dev, port->read_urb->pipe);
954
	} else {
Linus Torvalds's avatar
Linus Torvalds committed
955
		/* reset upstream data pipes */
956
957
958
959
960
961
962
963
		if (spriv->type == &pl2303_type_data[TYPE_HXN]) {
			pl2303_vendor_write(serial, PL2303_HXN_RESET_REG,
					PL2303_HXN_RESET_UPSTREAM_PIPE |
					PL2303_HXN_RESET_DOWNSTREAM_PIPE);
		} else {
			pl2303_vendor_write(serial, 8, 0);
			pl2303_vendor_write(serial, 9, 0);
		}
Linus Torvalds's avatar
Linus Torvalds committed
964
965
966
	}

	/* Setup termios */
Alan Cox's avatar
Alan Cox committed
967
	if (tty)
968
		pl2303_set_termios(tty, port, NULL);
Linus Torvalds's avatar
Linus Torvalds committed
969

970
	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
Linus Torvalds's avatar
Linus Torvalds committed
971
	if (result) {
972
973
		dev_err(&port->dev, "failed to submit interrupt urb: %d\n",
			result);
974
		return result;
Linus Torvalds's avatar
Linus Torvalds committed
975
	}
976

977
	result = usb_serial_generic_open(tty, port);
978
979
980
981
982
	if (result) {
		usb_kill_urb(port->interrupt_in_urb);
		return result;
	}

Linus Torvalds's avatar
Linus Torvalds committed
983
984
985
	return 0;
}

986
static int pl2303_tiocmset(struct tty_struct *tty,
987
			   unsigned int set, unsigned int clear)
Linus Torvalds's avatar
Linus Torvalds committed
988
{
Alan Cox's avatar
Alan Cox committed
989
	struct usb_serial_port *port = tty->driver_data;
Linus Torvalds's avatar
Linus Torvalds committed
990
991
992
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	u8 control;
993
	int ret;
994

995
	spin_lock_irqsave(&priv->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
996
997
998
999
1000
1001
1002
1003
1004
	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;
1005
	spin_unlock_irqrestore(&priv->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
1006

1007
1008
1009
	ret = pl2303_set_control_lines(port, control);
	if (ret)
		return usb_translate_errors(ret);
1010

1011
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
1012
1013
}

1014
static int pl2303_tiocmget(struct tty_struct *tty)
Linus Torvalds's avatar
Linus Torvalds committed
1015
{
Alan Cox's avatar
Alan Cox committed
1016
	struct usb_serial_port *port = tty->driver_data;
Linus Torvalds's avatar
Linus Torvalds committed
1017
1018
1019
1020
1021
1022
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	unsigned int mcr;
	unsigned int status;
	unsigned int result;

1023
	spin_lock_irqsave(&priv->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
1024
1025
	mcr = priv->line_control;
	status = priv->line_status;
1026
	spin_unlock_irqrestore(&priv->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
1027
1028
1029
1030
1031
1032
1033
1034

	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);

1035
	dev_dbg(&port->dev, "%s - result = %x\n", __func__, result);
Linus Torvalds's avatar
Linus Torvalds committed
1036
1037
1038
1039

	return result;
}

1040
1041
1042
static int pl2303_carrier_raised(struct usb_serial_port *port)
{
	struct pl2303_private *priv = usb_get_serial_port_data(port);
1043

1044
1045
	if (priv->line_status & UART_DCD)
		return 1;
1046

1047
1048
1049
	return 0;
}

1050
static void pl2303_set_break(struct usb_serial_port *port, bool enable)
Linus Torvalds's avatar
Linus Torvalds committed
1051
1052
1053
1054
1055
{
	struct usb_serial *serial = port->serial;
	u16 state;
	int result;

1056
	if (enable)
Linus Torvalds's avatar
Linus Torvalds committed
1057
		state = BREAK_ON;
1058
1059
	else
		state = BREAK_OFF;
1060

1061
	dev_dbg(&port->dev, "%s - turning break %s\n", __func__,
Alan Cox's avatar
Alan Cox committed
1062
			state == BREAK_OFF ? "off" : "on");
Linus Torvalds's avatar
Linus Torvalds committed