oti6858.c 27.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * Ours Technology Inc. OTi-6858 USB to serial adapter driver.
 *
 * Copyleft  (C) 2007 Kees Lemmens (adapted for kernel 2.6.20)
 * Copyright (C) 2006 Tomasz Michal Lukaszewski (FIXME: add e-mail)
 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
 * Copyright (C) 2003 IBM Corp.
 *
 * Many thanks to the authors of pl2303 driver: all functions in this file
 * are heavily based on pl2303 code, buffering code is a 1-to-1 copy.
 *
 * Warning! You use this driver on your own risk! The only official
 * description of this device I have is datasheet from manufacturer,
 * and it doesn't contain almost any information needed to write a driver.
 * Almost all knowlegde used while writing this driver was gathered by:
 *  - analyzing traffic between device and the M$ Windows 2000 driver,
 *  - trying different bit combinations and checking pin states
 *    with a voltmeter,
 *  - receiving malformed frames and producing buffer overflows
 *    to learn how errors are reported,
 * So, THIS CODE CAN DESTROY OTi-6858 AND ANY OTHER DEVICES, THAT ARE
 * CONNECTED TO IT!
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 *
A
Alan Cox 已提交
28 29
 * See Documentation/usb/usb-serial.txt for more information on using this
 * driver
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
 *
 * TODO:
 *  - implement correct flushing for ioctls and oti6858_close()
 *  - check how errors (rx overflow, parity error, framing error) are reported
 *  - implement oti6858_break_ctl()
 *  - implement more ioctls
 *  - test/implement flow control
 *  - allow setting custom baud rates
 */

#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>
#include <linux/usb.h>
#include <linux/usb/serial.h>
A
Alan Cox 已提交
53
#include <linux/uaccess.h>
54
#include <linux/kfifo.h>
55 56 57 58 59
#include "oti6858.h"

#define OTI6858_DESCRIPTION \
	"Ours Technology Inc. OTi-6858 USB to serial adapter driver"
#define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>"
60
#define OTI6858_VERSION "0.2"
61

62
static const struct usb_device_id id_table[] = {
63 64 65 66 67 68 69 70 71 72 73 74 75 76
	{ USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) },
	{ }
};

MODULE_DEVICE_TABLE(usb, id_table);

static struct usb_driver oti6858_driver = {
	.name =		"oti6858",
	.probe =	usb_serial_probe,
	.disconnect =	usb_serial_disconnect,
	.id_table =	id_table,
	.no_dynamic_id = 	1,
};

77
static bool debug;
78 79 80 81 82 83 84 85 86 87 88 89 90

/* requests */
#define	OTI6858_REQ_GET_STATUS		(USB_DIR_IN | USB_TYPE_VENDOR | 0x00)
#define	OTI6858_REQ_T_GET_STATUS	0x01

#define	OTI6858_REQ_SET_LINE		(USB_DIR_OUT | USB_TYPE_VENDOR | 0x00)
#define	OTI6858_REQ_T_SET_LINE		0x00

#define	OTI6858_REQ_CHECK_TXBUFF	(USB_DIR_IN | USB_TYPE_VENDOR | 0x01)
#define	OTI6858_REQ_T_CHECK_TXBUFF	0x00

/* format of the control packet */
struct oti6858_control_pkt {
A
Al Viro 已提交
91
	__le16	divisor;	/* baud rate = 96000000 / (16 * divisor), LE */
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
#define OTI6858_MAX_BAUD_RATE	3000000
	u8	frame_fmt;
#define FMT_STOP_BITS_MASK	0xc0
#define FMT_STOP_BITS_1		0x00
#define FMT_STOP_BITS_2		0x40	/* 1.5 stop bits if FMT_DATA_BITS_5 */
#define FMT_PARITY_MASK		0x38
#define FMT_PARITY_NONE		0x00
#define FMT_PARITY_ODD		0x08
#define FMT_PARITY_EVEN		0x18
#define FMT_PARITY_MARK		0x28
#define FMT_PARITY_SPACE	0x38
#define FMT_DATA_BITS_MASK	0x03
#define FMT_DATA_BITS_5		0x00
#define FMT_DATA_BITS_6		0x01
#define FMT_DATA_BITS_7		0x02
#define FMT_DATA_BITS_8		0x03
	u8	something;	/* always equals 0x43 */
	u8	control;	/* settings of flow control lines */
#define CONTROL_MASK		0x0c
#define CONTROL_DTR_HIGH	0x08
#define CONTROL_RTS_HIGH	0x04
	u8	tx_status;
#define	TX_BUFFER_EMPTIED	0x09
	u8	pin_state;
#define PIN_MASK		0x3f
#define PIN_RTS			0x20	/* output pin */
#define PIN_CTS			0x10	/* input pin, active low */
#define PIN_DSR			0x08	/* input pin, active low */
#define PIN_DTR			0x04	/* output pin */
#define PIN_RI			0x02	/* input pin, active low */
#define PIN_DCD			0x01	/* input pin, active low */
	u8	rx_bytes_avail;		/* number of bytes in rx buffer */;
};

#define OTI6858_CTRL_PKT_SIZE	sizeof(struct oti6858_control_pkt)
#define OTI6858_CTRL_EQUALS_PENDING(a, priv) \
A
Alan Cox 已提交
128
	(((a)->divisor == (priv)->pending_setup.divisor) \
129
	  && ((a)->control == (priv)->pending_setup.control) \
A
Alan Cox 已提交
130
	  && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt))
131 132

/* function prototypes */
133
static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port);
134
static void oti6858_close(struct usb_serial_port *port);
A
Alan Cox 已提交
135 136
static void oti6858_set_termios(struct tty_struct *tty,
			struct usb_serial_port *port, struct ktermios *old);
A
Alan Cox 已提交
137
static void oti6858_init_termios(struct tty_struct *tty);
138
static int oti6858_ioctl(struct tty_struct *tty,
139 140 141 142
			unsigned int cmd, unsigned long arg);
static void oti6858_read_int_callback(struct urb *urb);
static void oti6858_read_bulk_callback(struct urb *urb);
static void oti6858_write_bulk_callback(struct urb *urb);
A
Alan Cox 已提交
143
static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
144
			const unsigned char *buf, int count);
A
Alan Cox 已提交
145 146
static int oti6858_write_room(struct tty_struct *tty);
static int oti6858_chars_in_buffer(struct tty_struct *tty);
147
static int oti6858_tiocmget(struct tty_struct *tty);
148
static int oti6858_tiocmset(struct tty_struct *tty,
149 150
				unsigned int set, unsigned int clear);
static int oti6858_startup(struct usb_serial *serial);
151
static void oti6858_release(struct usb_serial *serial);
152 153 154 155 156 157 158 159

/* device info */
static struct usb_serial_driver oti6858_device = {
	.driver = {
		.owner =	THIS_MODULE,
		.name =		"oti6858",
	},
	.id_table =		id_table,
160
	.usb_driver =		&oti6858_driver,
161 162 163 164 165 166
	.num_ports =		1,
	.open =			oti6858_open,
	.close =		oti6858_close,
	.write =		oti6858_write,
	.ioctl =		oti6858_ioctl,
	.set_termios =		oti6858_set_termios,
A
Alan Cox 已提交
167
	.init_termios = 	oti6858_init_termios,
168 169 170 171 172 173 174 175
	.tiocmget =		oti6858_tiocmget,
	.tiocmset =		oti6858_tiocmset,
	.read_bulk_callback =	oti6858_read_bulk_callback,
	.read_int_callback =	oti6858_read_int_callback,
	.write_bulk_callback =	oti6858_write_bulk_callback,
	.write_room =		oti6858_write_room,
	.chars_in_buffer =	oti6858_chars_in_buffer,
	.attach =		oti6858_startup,
176
	.release =		oti6858_release,
177 178 179 180 181 182 183 184 185 186 187 188 189 190
};

struct oti6858_private {
	spinlock_t lock;

	struct oti6858_control_pkt status;

	struct {
		u8 read_urb_in_use;
		u8 write_urb_in_use;
	} flags;
	struct delayed_work delayed_write_work;

	struct {
A
Al Viro 已提交
191
		__le16 divisor;
192 193 194 195 196 197 198 199
		u8 frame_fmt;
		u8 control;
	} pending_setup;
	u8 transient;
	u8 setup_done;
	struct delayed_work delayed_setup_work;

	wait_queue_head_t intr_wait;
A
Alan Cox 已提交
200
	struct usb_serial_port *port;   /* USB port with which associated */
201 202 203 204
};

static void setup_line(struct work_struct *work)
{
A
Alan Cox 已提交
205 206
	struct oti6858_private *priv = container_of(work,
			struct oti6858_private, delayed_setup_work.work);
207 208 209 210 211
	struct usb_serial_port *port = priv->port;
	struct oti6858_control_pkt *new_setup;
	unsigned long flags;
	int result;

212
	dbg("%s(port = %d)", __func__, port->number);
213

A
Alan Cox 已提交
214 215
	new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL);
	if (new_setup == NULL) {
216
		dev_err(&port->dev, "%s(): out of memory!\n", __func__);
217
		/* we will try again */
A
Alan Cox 已提交
218 219
		schedule_delayed_work(&priv->delayed_setup_work,
						msecs_to_jiffies(2));
220 221 222 223 224 225 226 227 228 229 230 231
		return;
	}

	result = usb_control_msg(port->serial->dev,
				usb_rcvctrlpipe(port->serial->dev, 0),
				OTI6858_REQ_T_GET_STATUS,
				OTI6858_REQ_GET_STATUS,
				0, 0,
				new_setup, OTI6858_CTRL_PKT_SIZE,
				100);

	if (result != OTI6858_CTRL_PKT_SIZE) {
232
		dev_err(&port->dev, "%s(): error reading status\n", __func__);
233 234
		kfree(new_setup);
		/* we will try again */
A
Alan Cox 已提交
235 236
		schedule_delayed_work(&priv->delayed_setup_work,
							msecs_to_jiffies(2));
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
		return;
	}

	spin_lock_irqsave(&priv->lock, flags);
	if (!OTI6858_CTRL_EQUALS_PENDING(new_setup, priv)) {
		new_setup->divisor = priv->pending_setup.divisor;
		new_setup->control = priv->pending_setup.control;
		new_setup->frame_fmt = priv->pending_setup.frame_fmt;

		spin_unlock_irqrestore(&priv->lock, flags);
		result = usb_control_msg(port->serial->dev,
					usb_sndctrlpipe(port->serial->dev, 0),
					OTI6858_REQ_T_SET_LINE,
					OTI6858_REQ_SET_LINE,
					0, 0,
					new_setup, OTI6858_CTRL_PKT_SIZE,
					100);
	} else {
		spin_unlock_irqrestore(&priv->lock, flags);
		result = 0;
	}
	kfree(new_setup);

	spin_lock_irqsave(&priv->lock, flags);
	if (result != OTI6858_CTRL_PKT_SIZE)
		priv->transient = 0;
	priv->setup_done = 1;
	spin_unlock_irqrestore(&priv->lock, flags);

266
	dbg("%s(): submitting interrupt urb", __func__);
267
	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
268 269
	if (result != 0) {
		dev_err(&port->dev, "%s(): usb_submit_urb() failed"
270
				" with error %d\n", __func__, result);
271 272 273
	}
}

274
static void send_data(struct work_struct *work)
275
{
A
Alan Cox 已提交
276 277
	struct oti6858_private *priv = container_of(work,
			struct oti6858_private, delayed_write_work.work);
278 279 280
	struct usb_serial_port *port = priv->port;
	int count = 0, result;
	unsigned long flags;
281
	u8 *allow;
282

283
	dbg("%s(port = %d)", __func__, port->number);
284 285 286 287

	spin_lock_irqsave(&priv->lock, flags);
	if (priv->flags.write_urb_in_use) {
		spin_unlock_irqrestore(&priv->lock, flags);
A
Alan Cox 已提交
288 289
		schedule_delayed_work(&priv->delayed_write_work,
						msecs_to_jiffies(2));
290 291 292 293
		return;
	}
	priv->flags.write_urb_in_use = 1;
	spin_unlock_irqrestore(&priv->lock, flags);
J
Johan Hovold 已提交
294 295 296 297 298

	spin_lock_irqsave(&port->lock, flags);
	count = kfifo_len(&port->write_fifo);
	spin_unlock_irqrestore(&port->lock, flags);

299 300 301 302
	if (count > port->bulk_out_size)
		count = port->bulk_out_size;

	if (count != 0) {
303 304
		allow = kmalloc(1, GFP_KERNEL);
		if (!allow) {
305
			dev_err_console(port, "%s(): kmalloc failed\n",
306 307 308
					__func__);
			return;
		}
309 310 311 312
		result = usb_control_msg(port->serial->dev,
				usb_rcvctrlpipe(port->serial->dev, 0),
				OTI6858_REQ_T_CHECK_TXBUFF,
				OTI6858_REQ_CHECK_TXBUFF,
313 314
				count, 0, allow, 1, 100);
		if (result != 1 || *allow != 0)
315
			count = 0;
316
		kfree(allow);
317 318 319 320 321
	}

	if (count == 0) {
		priv->flags.write_urb_in_use = 0;

322
		dbg("%s(): submitting interrupt urb", __func__);
323
		result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
324 325
		if (result != 0) {
			dev_err(&port->dev, "%s(): usb_submit_urb() failed"
326
				" with error %d\n", __func__, result);
327 328 329 330
		}
		return;
	}

J
Johan Hovold 已提交
331
	count = kfifo_out_locked(&port->write_fifo,
332
					port->write_urb->transfer_buffer,
J
Johan Hovold 已提交
333
					count, &port->lock);
334
	port->write_urb->transfer_buffer_length = count;
335
	result = usb_submit_urb(port->write_urb, GFP_NOIO);
336
	if (result != 0) {
337
		dev_err_console(port, "%s(): usb_submit_urb() failed"
338
			       " with error %d\n", __func__, result);
339 340 341 342 343 344 345 346
		priv->flags.write_urb_in_use = 0;
	}

	usb_serial_port_softint(port);
}

static int oti6858_startup(struct usb_serial *serial)
{
A
Alan Cox 已提交
347 348
	struct usb_serial_port *port = serial->port[0];
	struct oti6858_private *priv;
349 350 351 352 353 354 355 356 357
	int i;

	for (i = 0; i < serial->num_ports; ++i) {
		priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL);
		if (!priv)
			break;

		spin_lock_init(&priv->lock);
		init_waitqueue_head(&priv->intr_wait);
A
Alan Cox 已提交
358 359
/*		INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */
/*		INIT_WORK(&priv->write_work, send_data, serial->port[i]); */
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
		priv->port = port;
		INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
		INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);

		usb_set_serial_port_data(serial->port[i], priv);
	}
	if (i == serial->num_ports)
		return 0;

	for (--i; i >= 0; --i) {
		priv = usb_get_serial_port_data(serial->port[i]);
		kfree(priv);
		usb_set_serial_port_data(serial->port[i], NULL);
	}
	return -ENOMEM;
}

A
Alan Cox 已提交
377
static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
378 379
			const unsigned char *buf, int count)
{
380
	dbg("%s(port = %d, count = %d)", __func__, port->number, count);
381 382 383 384

	if (!count)
		return count;

J
Johan Hovold 已提交
385
	count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock);
386 387 388 389

	return count;
}

A
Alan Cox 已提交
390
static int oti6858_write_room(struct tty_struct *tty)
391
{
A
Alan Cox 已提交
392
	struct usb_serial_port *port = tty->driver_data;
393 394 395
	int room = 0;
	unsigned long flags;

396
	dbg("%s(port = %d)", __func__, port->number);
397

J
Johan Hovold 已提交
398 399 400
	spin_lock_irqsave(&port->lock, flags);
	room = kfifo_avail(&port->write_fifo);
	spin_unlock_irqrestore(&port->lock, flags);
401 402 403 404

	return room;
}

A
Alan Cox 已提交
405
static int oti6858_chars_in_buffer(struct tty_struct *tty)
406
{
A
Alan Cox 已提交
407
	struct usb_serial_port *port = tty->driver_data;
408 409 410
	int chars = 0;
	unsigned long flags;

411
	dbg("%s(port = %d)", __func__, port->number);
412

J
Johan Hovold 已提交
413 414 415
	spin_lock_irqsave(&port->lock, flags);
	chars = kfifo_len(&port->write_fifo);
	spin_unlock_irqrestore(&port->lock, flags);
416 417 418 419

	return chars;
}

A
Alan Cox 已提交
420 421 422 423 424 425 426 427
static void oti6858_init_termios(struct tty_struct *tty)
{
	*(tty->termios) = tty_std_termios;
	tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
	tty->termios->c_ispeed = 38400;
	tty->termios->c_ospeed = 38400;
}

A
Alan Cox 已提交
428 429
static void oti6858_set_termios(struct tty_struct *tty,
		struct usb_serial_port *port, struct ktermios *old_termios)
430 431 432 433 434
{
	struct oti6858_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	unsigned int cflag;
	u8 frame_fmt, control;
A
Al Viro 已提交
435
	__le16 divisor;
436 437
	int br;

438
	dbg("%s(port = %d)", __func__, port->number);
439

A
Alan Cox 已提交
440
	if (!tty) {
441
		dbg("%s(): no tty structures", __func__);
442 443 444
		return;
	}

A
Alan Cox 已提交
445
	cflag = tty->termios->c_cflag;
446 447 448 449 450 451 452 453 454

	spin_lock_irqsave(&priv->lock, flags);
	divisor = priv->pending_setup.divisor;
	frame_fmt = priv->pending_setup.frame_fmt;
	control = priv->pending_setup.control;
	spin_unlock_irqrestore(&priv->lock, flags);

	frame_fmt &= ~FMT_DATA_BITS_MASK;
	switch (cflag & CSIZE) {
A
Alan Cox 已提交
455 456 457 458 459 460 461 462 463 464 465 466 467
	case CS5:
		frame_fmt |= FMT_DATA_BITS_5;
		break;
	case CS6:
		frame_fmt |= FMT_DATA_BITS_6;
		break;
	case CS7:
		frame_fmt |= FMT_DATA_BITS_7;
		break;
	default:
	case CS8:
		frame_fmt |= FMT_DATA_BITS_8;
		break;
468 469 470 471 472 473 474
	}

	/* manufacturer claims that this device can work with baud rates
	 * up to 3 Mbps; I've tested it only on 115200 bps, so I can't
	 * guarantee that any other baud rate will work (especially
	 * the higher ones)
	 */
A
Alan Cox 已提交
475
	br = tty_get_baud_rate(tty);
476 477
	if (br == 0) {
		divisor = 0;
A
Alan Cox 已提交
478
	} else {
479
		int real_br;
A
Al Viro 已提交
480
		int new_divisor;
A
Alan Cox 已提交
481
		br = min(br, OTI6858_MAX_BAUD_RATE);
482

A
Al Viro 已提交
483 484 485
		new_divisor = (96000000 + 8 * br) / (16 * br);
		real_br = 96000000 / (16 * new_divisor);
		divisor = cpu_to_le16(new_divisor);
A
Alan Cox 已提交
486
		tty_encode_baud_rate(tty, real_br, real_br);
487 488 489
	}

	frame_fmt &= ~FMT_STOP_BITS_MASK;
A
Alan Cox 已提交
490
	if ((cflag & CSTOPB) != 0)
491
		frame_fmt |= FMT_STOP_BITS_2;
A
Alan Cox 已提交
492
	else
493 494 495 496
		frame_fmt |= FMT_STOP_BITS_1;

	frame_fmt &= ~FMT_PARITY_MASK;
	if ((cflag & PARENB) != 0) {
A
Alan Cox 已提交
497
		if ((cflag & PARODD) != 0)
498
			frame_fmt |= FMT_PARITY_ODD;
A
Alan Cox 已提交
499
		else
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
			frame_fmt |= FMT_PARITY_EVEN;
	} else {
		frame_fmt |= FMT_PARITY_NONE;
	}

	control &= ~CONTROL_MASK;
	if ((cflag & CRTSCTS) != 0)
		control |= (CONTROL_DTR_HIGH | CONTROL_RTS_HIGH);

	/* change control lines if we are switching to or from B0 */
	/* FIXME:
	spin_lock_irqsave(&priv->lock, flags);
	control = priv->line_control;
	if ((cflag & CBAUD) == B0)
		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
	else
		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);
	}
	*/

	spin_lock_irqsave(&priv->lock, flags);
	if (divisor != priv->pending_setup.divisor
			|| control != priv->pending_setup.control
			|| frame_fmt != priv->pending_setup.frame_fmt) {
		priv->pending_setup.divisor = divisor;
		priv->pending_setup.control = control;
		priv->pending_setup.frame_fmt = frame_fmt;
	}
	spin_unlock_irqrestore(&priv->lock, flags);
}

537
static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port)
538 539 540 541 542 543 544 545
{
	struct oti6858_private *priv = usb_get_serial_port_data(port);
	struct ktermios tmp_termios;
	struct usb_serial *serial = port->serial;
	struct oti6858_control_pkt *buf;
	unsigned long flags;
	int result;

546
	dbg("%s(port = %d)", __func__, port->number);
547 548 549 550

	usb_clear_halt(serial->dev, port->write_urb->pipe);
	usb_clear_halt(serial->dev, port->read_urb->pipe);

A
Alan Cox 已提交
551 552
	buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL);
	if (buf == NULL) {
553
		dev_err(&port->dev, "%s(): out of memory!\n", __func__);
554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
		return -ENOMEM;
	}

	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
				OTI6858_REQ_T_GET_STATUS,
				OTI6858_REQ_GET_STATUS,
				0, 0,
				buf, OTI6858_CTRL_PKT_SIZE,
				100);
	if (result != OTI6858_CTRL_PKT_SIZE) {
		/* assume default (after power-on reset) values */
		buf->divisor = cpu_to_le16(0x009c);	/* 38400 bps */
		buf->frame_fmt = 0x03;	/* 8N1 */
		buf->something = 0x43;
		buf->control = 0x4c;	/* DTR, RTS */
		buf->tx_status = 0x00;
		buf->pin_state = 0x5b;	/* RTS, CTS, DSR, DTR, RI, DCD */
		buf->rx_bytes_avail = 0x00;
	}

	spin_lock_irqsave(&priv->lock, flags);
	memcpy(&priv->status, buf, OTI6858_CTRL_PKT_SIZE);
	priv->pending_setup.divisor = buf->divisor;
	priv->pending_setup.frame_fmt = buf->frame_fmt;
	priv->pending_setup.control = buf->control;
	spin_unlock_irqrestore(&priv->lock, flags);
	kfree(buf);

582
	dbg("%s(): submitting interrupt urb", __func__);
583 584 585
	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
	if (result != 0) {
		dev_err(&port->dev, "%s(): usb_submit_urb() failed"
586
			       " with error %d\n", __func__, result);
587
		oti6858_close(port);
588
		return result;
589 590 591
	}

	/* setup termios */
A
Alan Cox 已提交
592 593
	if (tty)
		oti6858_set_termios(tty, port, &tmp_termios);
594
	port->port.drain_delay = 256;	/* FIXME: check the FIFO length */
595 596 597
	return 0;
}

598
static void oti6858_close(struct usb_serial_port *port)
599 600 601 602
{
	struct oti6858_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;

603
	dbg("%s(port = %d)", __func__, port->number);
604

J
Johan Hovold 已提交
605
	spin_lock_irqsave(&port->lock, flags);
606
	/* clear out any remaining data in the buffer */
J
Johan Hovold 已提交
607 608
	kfifo_reset_out(&port->write_fifo);
	spin_unlock_irqrestore(&port->lock, flags);
609

610
	dbg("%s(): after buf_clear()", __func__);
611 612

	/* cancel scheduled setup */
T
Tejun Heo 已提交
613 614
	cancel_delayed_work_sync(&priv->delayed_setup_work);
	cancel_delayed_work_sync(&priv->delayed_write_work);
615 616

	/* shutdown our urbs */
617
	dbg("%s(): shutting down urbs", __func__);
618 619 620 621 622
	usb_kill_urb(port->write_urb);
	usb_kill_urb(port->read_urb);
	usb_kill_urb(port->interrupt_in_urb);
}

623
static int oti6858_tiocmset(struct tty_struct *tty,
624 625
				unsigned int set, unsigned int clear)
{
A
Alan Cox 已提交
626
	struct usb_serial_port *port = tty->driver_data;
627 628 629 630 631
	struct oti6858_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	u8 control;

	dbg("%s(port = %d, set = 0x%08x, clear = 0x%08x)",
632
				__func__, port->number, set, clear);
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648

	if (!usb_get_intfdata(port->serial->interface))
		return -ENODEV;

	/* FIXME: check if this is correct (active high/low) */
	spin_lock_irqsave(&priv->lock, flags);
	control = priv->pending_setup.control;
	if ((set & TIOCM_RTS) != 0)
		control |= CONTROL_RTS_HIGH;
	if ((set & TIOCM_DTR) != 0)
		control |= CONTROL_DTR_HIGH;
	if ((clear & TIOCM_RTS) != 0)
		control &= ~CONTROL_RTS_HIGH;
	if ((clear & TIOCM_DTR) != 0)
		control &= ~CONTROL_DTR_HIGH;

A
Alan Cox 已提交
649
	if (control != priv->pending_setup.control)
650 651
		priv->pending_setup.control = control;

A
Alan Cox 已提交
652
	spin_unlock_irqrestore(&priv->lock, flags);
653 654 655
	return 0;
}

656
static int oti6858_tiocmget(struct tty_struct *tty)
657
{
A
Alan Cox 已提交
658
	struct usb_serial_port *port = tty->driver_data;
659 660 661 662 663
	struct oti6858_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	unsigned pin_state;
	unsigned result = 0;

664
	dbg("%s(port = %d)", __func__, port->number);
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686

	if (!usb_get_intfdata(port->serial->interface))
		return -ENODEV;

	spin_lock_irqsave(&priv->lock, flags);
	pin_state = priv->status.pin_state & PIN_MASK;
	spin_unlock_irqrestore(&priv->lock, flags);

	/* FIXME: check if this is correct (active high/low) */
	if ((pin_state & PIN_RTS) != 0)
		result |= TIOCM_RTS;
	if ((pin_state & PIN_CTS) != 0)
		result |= TIOCM_CTS;
	if ((pin_state & PIN_DSR) != 0)
		result |= TIOCM_DSR;
	if ((pin_state & PIN_DTR) != 0)
		result |= TIOCM_DTR;
	if ((pin_state & PIN_RI) != 0)
		result |= TIOCM_RI;
	if ((pin_state & PIN_DCD) != 0)
		result |= TIOCM_CD;

687
	dbg("%s() = 0x%08x", __func__, result);
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703

	return result;
}

static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
{
	struct oti6858_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	unsigned int prev, status;
	unsigned int changed;

	spin_lock_irqsave(&priv->lock, flags);
	prev = priv->status.pin_state;
	spin_unlock_irqrestore(&priv->lock, flags);

	while (1) {
A
Alan Cox 已提交
704 705
		wait_event_interruptible(priv->intr_wait,
					priv->status.pin_state != prev);
706 707 708 709 710 711 712 713 714
		if (signal_pending(current))
			return -ERESTARTSYS;

		spin_lock_irqsave(&priv->lock, flags);
		status = priv->status.pin_state & PIN_MASK;
		spin_unlock_irqrestore(&priv->lock, flags);

		changed = prev ^ status;
		/* FIXME: check if this is correct (active high/low) */
A
Alan Cox 已提交
715 716 717 718 719
		if (((arg & TIOCM_RNG) && (changed & PIN_RI)) ||
		    ((arg & TIOCM_DSR) && (changed & PIN_DSR)) ||
		    ((arg & TIOCM_CD)  && (changed & PIN_DCD)) ||
		    ((arg & TIOCM_CTS) && (changed & PIN_CTS)))
			return 0;
720 721 722 723 724 725 726
		prev = status;
	}

	/* NOTREACHED */
	return 0;
}

727
static int oti6858_ioctl(struct tty_struct *tty,
728 729
			unsigned int cmd, unsigned long arg)
{
A
Alan Cox 已提交
730
	struct usb_serial_port *port = tty->driver_data;
731 732

	dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)",
733
				__func__, port->number, cmd, arg);
734 735

	switch (cmd) {
A
Alan Cox 已提交
736 737 738 739 740 741
	case TIOCMIWAIT:
		dbg("%s(): TIOCMIWAIT", __func__);
		return wait_modem_info(port, arg);
	default:
		dbg("%s(): 0x%04x not supported", __func__, cmd);
		break;
742 743 744 745 746
	}
	return -ENOIOCTLCMD;
}


747
static void oti6858_release(struct usb_serial *serial)
748 749 750
{
	int i;

751
	dbg("%s()", __func__);
752

J
Johan Hovold 已提交
753 754
	for (i = 0; i < serial->num_ports; ++i)
		kfree(usb_get_serial_port_data(serial->port[i]));
755 756 757 758
}

static void oti6858_read_int_callback(struct urb *urb)
{
759
	struct usb_serial_port *port =  urb->context;
760 761
	struct oti6858_private *priv = usb_get_serial_port_data(port);
	int transient = 0, can_recv = 0, resubmit = 1;
762
	int status = urb->status;
763

764
	dbg("%s(port = %d, status = %d)",
765
				__func__, port->number, status);
766

767
	switch (status) {
768 769 770 771 772 773 774 775
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
		dbg("%s(): urb shutting down with status: %d",
776
					__func__, status);
777 778 779
		return;
	default:
		dbg("%s(): nonzero urb status received: %d",
780
					__func__, status);
781 782 783
		break;
	}

784
	if (status == 0 && urb->actual_length == OTI6858_CTRL_PKT_SIZE) {
785 786 787 788 789 790 791 792 793 794 795 796
		struct oti6858_control_pkt *xs = urb->transfer_buffer;
		unsigned long flags;

		spin_lock_irqsave(&priv->lock, flags);

		if (!priv->transient) {
			if (!OTI6858_CTRL_EQUALS_PENDING(xs, priv)) {
				if (xs->rx_bytes_avail == 0) {
					priv->transient = 4;
					priv->setup_done = 0;
					resubmit = 0;
					dbg("%s(): scheduling setup_line()",
797
					    __func__);
798 799 800 801 802 803 804 805 806 807 808 809 810 811
					schedule_delayed_work(&priv->delayed_setup_work, 0);
				}
			}
		} else {
			if (OTI6858_CTRL_EQUALS_PENDING(xs, priv)) {
				priv->transient = 0;
			} else if (!priv->setup_done) {
				resubmit = 0;
			} else if (--priv->transient == 0) {
				if (xs->rx_bytes_avail == 0) {
					priv->transient = 4;
					priv->setup_done = 0;
					resubmit = 0;
					dbg("%s(): scheduling setup_line()",
812
					    __func__);
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
					schedule_delayed_work(&priv->delayed_setup_work, 0);
				}
			}
		}

		if (!priv->transient) {
			if (xs->pin_state != priv->status.pin_state)
				wake_up_interruptible(&priv->intr_wait);
			memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
		}

		if (!priv->transient && xs->rx_bytes_avail != 0) {
			can_recv = xs->rx_bytes_avail;
			priv->flags.read_urb_in_use = 1;
		}

		transient = priv->transient;
		spin_unlock_irqrestore(&priv->lock, flags);
	}

	if (can_recv) {
		int result;

		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
		if (result != 0) {
			priv->flags.read_urb_in_use = 0;
			dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
840
					" error %d\n", __func__, result);
841 842 843 844 845
		} else {
			resubmit = 0;
		}
	} else if (!transient) {
		unsigned long flags;
J
Johan Hovold 已提交
846 847 848 849 850
		int count;

		spin_lock_irqsave(&port->lock, flags);
		count = kfifo_len(&port->write_fifo);
		spin_unlock_irqrestore(&port->lock, flags);
851 852

		spin_lock_irqsave(&priv->lock, flags);
J
Johan Hovold 已提交
853
		if (priv->flags.write_urb_in_use == 0 && count != 0) {
A
Alan Cox 已提交
854
			schedule_delayed_work(&priv->delayed_write_work, 0);
855 856 857 858 859 860 861 862
			resubmit = 0;
		}
		spin_unlock_irqrestore(&priv->lock, flags);
	}

	if (resubmit) {
		int result;

A
Alan Cox 已提交
863
/*		dbg("%s(): submitting interrupt urb", __func__); */
864 865 866 867
		result = usb_submit_urb(urb, GFP_ATOMIC);
		if (result != 0) {
			dev_err(&urb->dev->dev,
					"%s(): usb_submit_urb() failed with"
868
					" error %d\n", __func__, result);
869 870 871 872 873 874
		}
	}
}

static void oti6858_read_bulk_callback(struct urb *urb)
{
875
	struct usb_serial_port *port =  urb->context;
876 877 878 879
	struct oti6858_private *priv = usb_get_serial_port_data(port);
	struct tty_struct *tty;
	unsigned char *data = urb->transfer_buffer;
	unsigned long flags;
880
	int status = urb->status;
A
Alan Cox 已提交
881
	int result;
882

883
	dbg("%s(port = %d, status = %d)",
884
				__func__, port->number, status);
885 886 887 888 889

	spin_lock_irqsave(&priv->lock, flags);
	priv->flags.read_urb_in_use = 0;
	spin_unlock_irqrestore(&priv->lock, flags);

890
	if (status != 0) {
891
		dbg("%s(): unable to handle the error, exiting", __func__);
892 893 894
		return;
	}

A
Alan Cox 已提交
895
	tty = tty_port_tty_get(&port->port);
896
	if (tty != NULL && urb->actual_length > 0) {
A
Alan Cox 已提交
897
		tty_insert_flip_string(tty, data, urb->actual_length);
898 899
		tty_flip_buffer_push(tty);
	}
A
Alan Cox 已提交
900
	tty_kref_put(tty);
901

902 903 904 905 906
	/* schedule the interrupt urb */
	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
	if (result != 0 && result != -EPERM) {
		dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
				" error %d\n", __func__, result);
907 908 909 910 911
	}
}

static void oti6858_write_bulk_callback(struct urb *urb)
{
912
	struct usb_serial_port *port =  urb->context;
913
	struct oti6858_private *priv = usb_get_serial_port_data(port);
914
	int status = urb->status;
915 916
	int result;

917
	dbg("%s(port = %d, status = %d)",
918
				__func__, port->number, status);
919

920
	switch (status) {
921 922 923 924 925 926 927 928
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
		dbg("%s(): urb shutting down with status: %d",
929
					__func__, status);
930 931 932 933 934
		priv->flags.write_urb_in_use = 0;
		return;
	default:
		/* error in the urb, so we have to resubmit it */
		dbg("%s(): nonzero write bulk status received: %d",
935 936
					__func__, status);
		dbg("%s(): overflow in write", __func__);
937 938 939 940

		port->write_urb->transfer_buffer_length = 1;
		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
		if (result) {
941
			dev_err_console(port, "%s(): usb_submit_urb() failed,"
942
					" error %d\n", __func__, result);
943 944 945 946 947 948 949
		} else {
			return;
		}
	}

	priv->flags.write_urb_in_use = 0;

A
Alan Cox 已提交
950
	/* schedule the interrupt urb if we are still open */
951
	dbg("%s(): submitting interrupt urb", __func__);
952 953 954
	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
	if (result != 0) {
		dev_err(&port->dev, "%s(): failed submitting int urb,"
955
					" error %d\n", __func__, result);
956 957 958 959 960 961 962 963 964
	}
}

/* module description and (de)initialization */

static int __init oti6858_init(void)
{
	int retval;

A
Alan Cox 已提交
965 966 967 968
	retval = usb_serial_register(&oti6858_device);
	if (retval == 0) {
		retval = usb_register(&oti6858_driver);
		if (retval)
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
			usb_serial_deregister(&oti6858_device);
	}
	return retval;
}

static void __exit oti6858_exit(void)
{
	usb_deregister(&oti6858_driver);
	usb_serial_deregister(&oti6858_device);
}

module_init(oti6858_init);
module_exit(oti6858_exit);

MODULE_DESCRIPTION(OTI6858_DESCRIPTION);
MODULE_AUTHOR(OTI6858_AUTHOR);
MODULE_VERSION(OTI6858_VERSION);
MODULE_LICENSE("GPL");

module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "enable debug output");