keyspan.c 65.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2
/*
  Keyspan USB to Serial Converter driver
A
Alan Cox 已提交
3

L
Linus Torvalds 已提交
4 5
  (C) Copyright (C) 2000-2001	Hugh Blemings <hugh@blemings.org>
  (C) Copyright (C) 2002	Greg Kroah-Hartman <greg@kroah.com>
A
Alan Cox 已提交
6

L
Linus Torvalds 已提交
7 8 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 as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

12
  See http://blemings.org/hugh/keyspan.html for more information.
A
Alan Cox 已提交
13

L
Linus Torvalds 已提交
14 15 16 17 18 19
  Code in this driver inspired by and in a number of places taken
  from Brian Warner's original Keyspan-PDA driver.

  This driver has been put together with the support of Innosys, Inc.
  and Keyspan, Inc the manufacturers of the Keyspan USB-serial products.
  Thanks Guys :)
A
Alan Cox 已提交
20

L
Linus Torvalds 已提交
21 22 23
  Thanks to Paulus for miscellaneous tidy ups, some largish chunks
  of much nicer and/or completely new code and (perhaps most uniquely)
  having the patience to sit down and explain why and where he'd changed
A
Alan Cox 已提交
24 25 26
  stuff.

  Tip 'o the hat to IBM (and previously Linuxcare :) for supporting
L
Linus Torvalds 已提交
27 28 29 30 31 32 33 34 35 36 37 38 39
  staff in their work on open source projects.
*/


#include <linux/kernel.h>
#include <linux/jiffies.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/module.h>
#include <linux/spinlock.h>
A
Alan Cox 已提交
40
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
41
#include <linux/usb.h>
42
#include <linux/usb/serial.h>
43
#include <linux/usb/ezusb.h>
L
Linus Torvalds 已提交
44 45 46 47 48 49 50
#include "keyspan.h"

#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu"
#define DRIVER_DESC "Keyspan USB to Serial Converter Driver"

#define INSTAT_BUFLEN	32
#define GLOCONT_BUFLEN	64
51
#define INDAT49W_BUFLEN	512
52 53 54 55
#define IN_BUFLEN	64
#define OUT_BUFLEN	64
#define INACK_BUFLEN	1
#define OUTCONT_BUFLEN	64
L
Linus Torvalds 已提交
56 57 58 59 60 61

	/* Per device and per port private data */
struct keyspan_serial_private {
	const struct keyspan_device_details	*device_details;

	struct urb	*instat_urb;
62
	char		*instat_buf;
L
Linus Torvalds 已提交
63

A
Alan Cox 已提交
64 65
	/* added to support 49wg, where data from all 4 ports comes in
	   on 1 EP and high-speed supported */
66
	struct urb	*indat_urb;
67
	char		*indat_buf;
68

L
Linus Torvalds 已提交
69 70
	/* XXX this one probably will need a lock */
	struct urb	*glocont_urb;
71 72
	char		*glocont_buf;
	char		*ctrl_buf;	/* for EP0 control message */
L
Linus Torvalds 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86
};

struct keyspan_port_private {
	/* Keep track of which input & output endpoints to use */
	int		in_flip;
	int		out_flip;

	/* Keep duplicate of device details in each port
	   structure as well - simplifies some of the
	   callback functions etc. */
	const struct keyspan_device_details	*device_details;

	/* Input endpoints and buffer for this port */
	struct urb	*in_urbs[2];
87
	char		*in_buffer[2];
L
Linus Torvalds 已提交
88 89
	/* Output endpoints and buffer for this port */
	struct urb	*out_urbs[2];
90
	char		*out_buffer[2];
L
Linus Torvalds 已提交
91 92 93

	/* Input ack endpoint */
	struct urb	*inack_urb;
94
	char		*inack_buffer;
L
Linus Torvalds 已提交
95 96 97

	/* Output control endpoint */
	struct urb	*outcont_urb;
98
	char		*outcont_buffer;
L
Linus Torvalds 已提交
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118

	/* Settings for the port */
	int		baud;
	int		old_baud;
	unsigned int	cflag;
	unsigned int	old_cflag;
	enum		{flow_none, flow_cts, flow_xon} flow_control;
	int		rts_state;	/* Handshaking pins (outputs) */
	int		dtr_state;
	int		cts_state;	/* Handshaking pins (inputs) */
	int		dsr_state;
	int		dcd_state;
	int		ri_state;
	int		break_on;

	unsigned long	tx_start_time[2];
	int		resend_cont;	/* need to resend control packet */
};

/* Include Keyspan message headers.  All current Keyspan Adapters
119
   make use of one of five message formats which are referred
A
Alan Cox 已提交
120 121
   to as USA-26, USA-28, USA-49, USA-90, USA-67 by Keyspan and
   within this driver. */
L
Linus Torvalds 已提交
122 123 124 125
#include "keyspan_usa26msg.h"
#include "keyspan_usa28msg.h"
#include "keyspan_usa49msg.h"
#include "keyspan_usa90msg.h"
126
#include "keyspan_usa67msg.h"
A
Alan Cox 已提交
127

L
Linus Torvalds 已提交
128

129
module_usb_serial_driver(serial_drivers, keyspan_ids_combined);
L
Linus Torvalds 已提交
130

A
Alan Cox 已提交
131
static void keyspan_break_ctl(struct tty_struct *tty, int break_state)
L
Linus Torvalds 已提交
132
{
A
Alan Cox 已提交
133
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
134 135 136 137 138 139 140 141 142 143 144 145 146
	struct keyspan_port_private 	*p_priv;

	p_priv = usb_get_serial_port_data(port);

	if (break_state == -1)
		p_priv->break_on = 1;
	else
		p_priv->break_on = 0;

	keyspan_send_setup(port, 0);
}


A
Alan Cox 已提交
147
static void keyspan_set_termios(struct tty_struct *tty,
A
Alan Cox 已提交
148
		struct usb_serial_port *port, struct ktermios *old_termios)
L
Linus Torvalds 已提交
149 150 151 152 153 154 155 156
{
	int				baud_rate, device_port;
	struct keyspan_port_private 	*p_priv;
	const struct keyspan_device_details	*d_details;
	unsigned int 			cflag;

	p_priv = usb_get_serial_port_data(port);
	d_details = p_priv->device_details;
157
	cflag = tty->termios.c_cflag;
158
	device_port = port->port_number;
L
Linus Torvalds 已提交
159 160 161

	/* Baud rate calculation takes baud rate as an integer
	   so other rates can be generated if desired. */
A
Alan Cox 已提交
162
	baud_rate = tty_get_baud_rate(tty);
A
Alan Cox 已提交
163
	/* If no match or invalid, don't change */
164
	if (d_details->calculate_baud_rate(port, baud_rate, d_details->baudclk,
L
Linus Torvalds 已提交
165 166
				NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
		/* FIXME - more to do here to ensure rate changes cleanly */
167
		/* FIXME - calculate exact rate from divisor ? */
L
Linus Torvalds 已提交
168
		p_priv->baud = baud_rate;
A
Alan Cox 已提交
169 170
	} else
		baud_rate = tty_termios_baud_rate(old_termios);
L
Linus Torvalds 已提交
171

A
Alan Cox 已提交
172
	tty_encode_baud_rate(tty, baud_rate, baud_rate);
L
Linus Torvalds 已提交
173 174
	/* set CTS/RTS handshake etc. */
	p_priv->cflag = cflag;
175
	p_priv->flow_control = (cflag & CRTSCTS) ? flow_cts : flow_none;
L
Linus Torvalds 已提交
176

A
Alan Cox 已提交
177
	/* Mark/Space not supported */
178
	tty->termios.c_cflag &= ~CMSPAR;
A
Alan Cox 已提交
179

L
Linus Torvalds 已提交
180 181 182
	keyspan_send_setup(port, 0);
}

183
static int keyspan_tiocmget(struct tty_struct *tty)
L
Linus Torvalds 已提交
184
{
A
Alan Cox 已提交
185 186
	struct usb_serial_port *port = tty->driver_data;
	struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);
L
Linus Torvalds 已提交
187
	unsigned int			value;
A
Alan Cox 已提交
188

L
Linus Torvalds 已提交
189 190 191 192 193
	value = ((p_priv->rts_state) ? TIOCM_RTS : 0) |
		((p_priv->dtr_state) ? TIOCM_DTR : 0) |
		((p_priv->cts_state) ? TIOCM_CTS : 0) |
		((p_priv->dsr_state) ? TIOCM_DSR : 0) |
		((p_priv->dcd_state) ? TIOCM_CAR : 0) |
A
Alan Cox 已提交
194
		((p_priv->ri_state) ? TIOCM_RNG : 0);
L
Linus Torvalds 已提交
195 196 197 198

	return value;
}

199
static int keyspan_tiocmset(struct tty_struct *tty,
L
Linus Torvalds 已提交
200 201
			    unsigned int set, unsigned int clear)
{
A
Alan Cox 已提交
202 203
	struct usb_serial_port *port = tty->driver_data;
	struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);
A
Alan Cox 已提交
204

L
Linus Torvalds 已提交
205 206 207 208 209 210 211 212 213 214 215 216
	if (set & TIOCM_RTS)
		p_priv->rts_state = 1;
	if (set & TIOCM_DTR)
		p_priv->dtr_state = 1;
	if (clear & TIOCM_RTS)
		p_priv->rts_state = 0;
	if (clear & TIOCM_DTR)
		p_priv->dtr_state = 0;
	keyspan_send_setup(port, 0);
	return 0;
}

A
Alan Cox 已提交
217 218 219 220
/* Write function is similar for the four protocols used
   with only a minor change for usa90 (usa19hs) required */
static int keyspan_write(struct tty_struct *tty,
	struct usb_serial_port *port, const unsigned char *buf, int count)
L
Linus Torvalds 已提交
221 222 223 224 225 226
{
	struct keyspan_port_private 	*p_priv;
	const struct keyspan_device_details	*d_details;
	int				flip;
	int 				left, todo;
	struct urb			*this_urb;
A
Alan Cox 已提交
227
	int 				err, maxDataLen, dataOffset;
L
Linus Torvalds 已提交
228 229 230 231 232

	p_priv = usb_get_serial_port_data(port);
	d_details = p_priv->device_details;

	if (d_details->msg_format == msg_usa90) {
A
Alan Cox 已提交
233
		maxDataLen = 64;
L
Linus Torvalds 已提交
234 235 236 237 238
		dataOffset = 0;
	} else {
		maxDataLen = 63;
		dataOffset = 1;
	}
A
Alan Cox 已提交
239

240 241
	dev_dbg(&port->dev, "%s - %d chars, flip=%d\n", __func__, count,
		p_priv->out_flip);
L
Linus Torvalds 已提交
242 243 244 245 246 247 248

	for (left = count; left > 0; left -= todo) {
		todo = left;
		if (todo > maxDataLen)
			todo = maxDataLen;

		flip = p_priv->out_flip;
A
Alan Cox 已提交
249

L
Linus Torvalds 已提交
250
		/* Check we have a valid urb/endpoint before we use it... */
A
Alan Cox 已提交
251 252
		this_urb = p_priv->out_urbs[flip];
		if (this_urb == NULL) {
L
Linus Torvalds 已提交
253
			/* no bulk out, so return 0 bytes written */
254
			dev_dbg(&port->dev, "%s - no output urb :(\n", __func__);
L
Linus Torvalds 已提交
255 256 257
			return count;
		}

258
		dev_dbg(&port->dev, "%s - endpoint %d flip %d\n",
A
Alan Cox 已提交
259
			__func__, usb_pipeendpoint(this_urb->pipe), flip);
L
Linus Torvalds 已提交
260 261

		if (this_urb->status == -EINPROGRESS) {
A
Alan Cox 已提交
262 263
			if (time_before(jiffies,
					p_priv->tx_start_time[flip] + 10 * HZ))
L
Linus Torvalds 已提交
264 265 266 267 268
				break;
			usb_unlink_urb(this_urb);
			break;
		}

A
Alan Cox 已提交
269 270
		/* First byte in buffer is "last flag" (except for usa19hx)
		   - unused so for now so set to zero */
L
Linus Torvalds 已提交
271 272
		((char *)this_urb->transfer_buffer)[0] = 0;

A
Alan Cox 已提交
273
		memcpy(this_urb->transfer_buffer + dataOffset, buf, todo);
L
Linus Torvalds 已提交
274 275 276 277 278
		buf += todo;

		/* send the data out the bulk port */
		this_urb->transfer_buffer_length = todo + dataOffset;

A
Alan Cox 已提交
279 280
		err = usb_submit_urb(this_urb, GFP_ATOMIC);
		if (err != 0)
281
			dev_dbg(&port->dev, "usb_submit_urb(write bulk) failed (%d)\n", err);
L
Linus Torvalds 已提交
282 283 284 285 286 287 288 289 290 291
		p_priv->tx_start_time[flip] = jiffies;

		/* Flip for next time if usa26 or usa28 interface
		   (not used on usa49) */
		p_priv->out_flip = (flip + 1) & d_details->outdat_endp_flip;
	}

	return count - left;
}

292
static void	usa26_indat_callback(struct urb *urb)
L
Linus Torvalds 已提交
293 294 295 296 297
{
	int			i, err;
	int			endpoint;
	struct usb_serial_port	*port;
	unsigned char 		*data = urb->transfer_buffer;
298
	int status = urb->status;
L
Linus Torvalds 已提交
299 300 301

	endpoint = usb_pipeendpoint(urb->pipe);

302
	if (status) {
303
		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x on endpoint %d.\n",
304
			__func__, status, endpoint);
L
Linus Torvalds 已提交
305 306 307
		return;
	}

308
	port =  urb->context;
J
Jiri Slaby 已提交
309
	if (urb->actual_length) {
L
Linus Torvalds 已提交
310 311
		/* 0x80 bit is error flag */
		if ((data[0] & 0x80) == 0) {
A
Alan Cox 已提交
312 313
			/* no errors on individual bytes, only
			   possible overrun err */
L
Linus Torvalds 已提交
314
			if (data[0] & RXERROR_OVERRUN)
A
Alan Cox 已提交
315 316 317 318
				err = TTY_OVERRUN;
			else
				err = 0;
			for (i = 1; i < urb->actual_length ; ++i)
J
Jiri Slaby 已提交
319
				tty_insert_flip_char(&port->port, data[i], err);
L
Linus Torvalds 已提交
320 321
		} else {
			/* some bytes had errors, every byte has status */
322
			dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__);
L
Linus Torvalds 已提交
323 324 325 326 327 328 329 330 331
			for (i = 0; i + 1 < urb->actual_length; i += 2) {
				int stat = data[i], flag = 0;
				if (stat & RXERROR_OVERRUN)
					flag |= TTY_OVERRUN;
				if (stat & RXERROR_FRAMING)
					flag |= TTY_FRAME;
				if (stat & RXERROR_PARITY)
					flag |= TTY_PARITY;
				/* XXX should handle break (0x10) */
J
Jiri Slaby 已提交
332 333
				tty_insert_flip_char(&port->port, data[i+1],
						flag);
L
Linus Torvalds 已提交
334 335
			}
		}
J
Jiri Slaby 已提交
336
		tty_flip_buffer_push(&port->port);
L
Linus Torvalds 已提交
337
	}
A
Alan Cox 已提交
338 339

	/* Resubmit urb so we continue receiving */
340 341
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err != 0)
342
		dev_dbg(&port->dev, "%s - resubmit read urb failed. (%d)\n", __func__, err);
L
Linus Torvalds 已提交
343 344
}

A
Alan Cox 已提交
345
/* Outdat handling is common for all devices */
346
static void	usa2x_outdat_callback(struct urb *urb)
L
Linus Torvalds 已提交
347 348 349 350
{
	struct usb_serial_port *port;
	struct keyspan_port_private *p_priv;

351
	port =  urb->context;
L
Linus Torvalds 已提交
352
	p_priv = usb_get_serial_port_data(port);
353
	dev_dbg(&port->dev, "%s - urb %d\n", __func__, urb == p_priv->out_urbs[1]);
L
Linus Torvalds 已提交
354

355
	usb_serial_port_softint(port);
L
Linus Torvalds 已提交
356 357
}

358
static void	usa26_inack_callback(struct urb *urb)
L
Linus Torvalds 已提交
359 360 361
{
}

362
static void	usa26_outcont_callback(struct urb *urb)
L
Linus Torvalds 已提交
363 364 365 366
{
	struct usb_serial_port *port;
	struct keyspan_port_private *p_priv;

367
	port =  urb->context;
L
Linus Torvalds 已提交
368 369 370
	p_priv = usb_get_serial_port_data(port);

	if (p_priv->resend_cont) {
371
		dev_dbg(&port->dev, "%s - sending setup\n", __func__);
A
Alan Cox 已提交
372 373
		keyspan_usa26_send_setup(port->serial, port,
						p_priv->resend_cont - 1);
L
Linus Torvalds 已提交
374 375 376
	}
}

377
static void	usa26_instat_callback(struct urb *urb)
L
Linus Torvalds 已提交
378 379 380 381 382 383 384
{
	unsigned char 				*data = urb->transfer_buffer;
	struct keyspan_usa26_portStatusMessage	*msg;
	struct usb_serial			*serial;
	struct usb_serial_port			*port;
	struct keyspan_port_private	 	*p_priv;
	int old_dcd_state, err;
385
	int status = urb->status;
L
Linus Torvalds 已提交
386

387
	serial =  urb->context;
L
Linus Torvalds 已提交
388

389
	if (status) {
390
		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
L
Linus Torvalds 已提交
391 392 393
		return;
	}
	if (urb->actual_length != 9) {
394
		dev_dbg(&urb->dev->dev, "%s - %d byte report??\n", __func__, urb->actual_length);
L
Linus Torvalds 已提交
395 396 397 398 399
		goto exit;
	}

	msg = (struct keyspan_usa26_portStatusMessage *)data;

A
Alan Cox 已提交
400
	/* Check port number from message and retrieve private data */
L
Linus Torvalds 已提交
401
	if (msg->port >= serial->num_ports) {
402
		dev_dbg(&urb->dev->dev, "%s - Unexpected port number %d\n", __func__, msg->port);
L
Linus Torvalds 已提交
403 404 405 406
		goto exit;
	}
	port = serial->port[msg->port];
	p_priv = usb_get_serial_port_data(port);
A
Alan Cox 已提交
407

L
Linus Torvalds 已提交
408 409 410 411 412 413 414
	/* Update handshaking pin state information */
	old_dcd_state = p_priv->dcd_state;
	p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);
	p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
	p_priv->ri_state = ((msg->ri) ? 1 : 0);

J
Jiri Slaby 已提交
415 416
	if (old_dcd_state != p_priv->dcd_state)
		tty_port_tty_hangup(&port->port, true);
A
Alan Cox 已提交
417

L
Linus Torvalds 已提交
418
	/* Resubmit urb so we continue receiving */
A
Alan Cox 已提交
419 420
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err != 0)
421
		dev_dbg(&port->dev, "%s - resubmit read urb failed. (%d)\n", __func__, err);
L
Linus Torvalds 已提交
422 423 424
exit: ;
}

425
static void	usa26_glocont_callback(struct urb *urb)
L
Linus Torvalds 已提交
426 427 428 429
{
}


430
static void usa28_indat_callback(struct urb *urb)
L
Linus Torvalds 已提交
431
{
432
	int                     err;
L
Linus Torvalds 已提交
433 434 435
	struct usb_serial_port  *port;
	unsigned char           *data;
	struct keyspan_port_private             *p_priv;
436
	int status = urb->status;
L
Linus Torvalds 已提交
437

438
	port =  urb->context;
L
Linus Torvalds 已提交
439 440 441 442 443 444 445
	p_priv = usb_get_serial_port_data(port);
	data = urb->transfer_buffer;

	if (urb != p_priv->in_urbs[p_priv->in_flip])
		return;

	do {
446
		if (status) {
447 448
			dev_dbg(&urb->dev->dev, "%s - nonzero status: %x on endpoint %d.\n",
				__func__, status, usb_pipeendpoint(urb->pipe));
L
Linus Torvalds 已提交
449 450 451
			return;
		}

452
		port =  urb->context;
L
Linus Torvalds 已提交
453 454 455
		p_priv = usb_get_serial_port_data(port);
		data = urb->transfer_buffer;

J
Jiri Slaby 已提交
456
		if (urb->actual_length) {
J
Jiri Slaby 已提交
457 458
			tty_insert_flip_string(&port->port, data,
					urb->actual_length);
J
Jiri Slaby 已提交
459
			tty_flip_buffer_push(&port->port);
L
Linus Torvalds 已提交
460 461 462
		}

		/* Resubmit urb so we continue receiving */
463 464
		err = usb_submit_urb(urb, GFP_ATOMIC);
		if (err != 0)
465
			dev_dbg(&port->dev, "%s - resubmit read urb failed. (%d)\n",
466
							__func__, err);
L
Linus Torvalds 已提交
467 468 469 470 471 472
		p_priv->in_flip ^= 1;

		urb = p_priv->in_urbs[p_priv->in_flip];
	} while (urb->status != -EINPROGRESS);
}

473
static void	usa28_inack_callback(struct urb *urb)
L
Linus Torvalds 已提交
474 475 476
{
}

477
static void	usa28_outcont_callback(struct urb *urb)
L
Linus Torvalds 已提交
478 479 480 481
{
	struct usb_serial_port *port;
	struct keyspan_port_private *p_priv;

482
	port =  urb->context;
L
Linus Torvalds 已提交
483 484 485
	p_priv = usb_get_serial_port_data(port);

	if (p_priv->resend_cont) {
486
		dev_dbg(&port->dev, "%s - sending setup\n", __func__);
A
Alan Cox 已提交
487 488
		keyspan_usa28_send_setup(port->serial, port,
						p_priv->resend_cont - 1);
L
Linus Torvalds 已提交
489 490 491
	}
}

492
static void	usa28_instat_callback(struct urb *urb)
L
Linus Torvalds 已提交
493 494 495 496 497 498 499 500
{
	int					err;
	unsigned char 				*data = urb->transfer_buffer;
	struct keyspan_usa28_portStatusMessage	*msg;
	struct usb_serial			*serial;
	struct usb_serial_port			*port;
	struct keyspan_port_private	 	*p_priv;
	int old_dcd_state;
501
	int status = urb->status;
L
Linus Torvalds 已提交
502

503
	serial =  urb->context;
L
Linus Torvalds 已提交
504

505
	if (status) {
506
		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
L
Linus Torvalds 已提交
507 508 509 510
		return;
	}

	if (urb->actual_length != sizeof(struct keyspan_usa28_portStatusMessage)) {
511
		dev_dbg(&urb->dev->dev, "%s - bad length %d\n", __func__, urb->actual_length);
L
Linus Torvalds 已提交
512 513 514
		goto exit;
	}

A
Alan Cox 已提交
515
	msg = (struct keyspan_usa28_portStatusMessage *)data;
L
Linus Torvalds 已提交
516

A
Alan Cox 已提交
517
	/* Check port number from message and retrieve private data */
L
Linus Torvalds 已提交
518
	if (msg->port >= serial->num_ports) {
519
		dev_dbg(&urb->dev->dev, "%s - Unexpected port number %d\n", __func__, msg->port);
L
Linus Torvalds 已提交
520 521 522 523
		goto exit;
	}
	port = serial->port[msg->port];
	p_priv = usb_get_serial_port_data(port);
A
Alan Cox 已提交
524

L
Linus Torvalds 已提交
525 526 527 528 529 530 531
	/* Update handshaking pin state information */
	old_dcd_state = p_priv->dcd_state;
	p_priv->cts_state = ((msg->cts) ? 1 : 0);
	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);
	p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
	p_priv->ri_state = ((msg->ri) ? 1 : 0);

J
Jiri Slaby 已提交
532 533
	if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
		tty_port_tty_hangup(&port->port, true);
L
Linus Torvalds 已提交
534 535

		/* Resubmit urb so we continue receiving */
A
Alan Cox 已提交
536 537
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err != 0)
538
		dev_dbg(&port->dev, "%s - resubmit read urb failed. (%d)\n", __func__, err);
L
Linus Torvalds 已提交
539 540 541
exit: ;
}

542
static void	usa28_glocont_callback(struct urb *urb)
L
Linus Torvalds 已提交
543 544 545 546
{
}


547
static void	usa49_glocont_callback(struct urb *urb)
L
Linus Torvalds 已提交
548 549 550 551 552 553
{
	struct usb_serial *serial;
	struct usb_serial_port *port;
	struct keyspan_port_private *p_priv;
	int i;

554
	serial =  urb->context;
L
Linus Torvalds 已提交
555 556 557 558 559
	for (i = 0; i < serial->num_ports; ++i) {
		port = serial->port[i];
		p_priv = usb_get_serial_port_data(port);

		if (p_priv->resend_cont) {
560
			dev_dbg(&port->dev, "%s - sending setup\n", __func__);
A
Alan Cox 已提交
561 562
			keyspan_usa49_send_setup(serial, port,
						p_priv->resend_cont - 1);
L
Linus Torvalds 已提交
563 564 565 566 567 568 569
			break;
		}
	}
}

	/* This is actually called glostat in the Keyspan
	   doco */
570
static void	usa49_instat_callback(struct urb *urb)
L
Linus Torvalds 已提交
571 572 573 574 575 576 577 578
{
	int					err;
	unsigned char 				*data = urb->transfer_buffer;
	struct keyspan_usa49_portStatusMessage	*msg;
	struct usb_serial			*serial;
	struct usb_serial_port			*port;
	struct keyspan_port_private	 	*p_priv;
	int old_dcd_state;
579
	int status = urb->status;
L
Linus Torvalds 已提交
580

581
	serial =  urb->context;
L
Linus Torvalds 已提交
582

583
	if (status) {
584
		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
L
Linus Torvalds 已提交
585 586 587
		return;
	}

A
Alan Cox 已提交
588 589
	if (urb->actual_length !=
			sizeof(struct keyspan_usa49_portStatusMessage)) {
590
		dev_dbg(&urb->dev->dev, "%s - bad length %d\n", __func__, urb->actual_length);
L
Linus Torvalds 已提交
591 592 593 594 595
		goto exit;
	}

	msg = (struct keyspan_usa49_portStatusMessage *)data;

A
Alan Cox 已提交
596
	/* Check port number from message and retrieve private data */
L
Linus Torvalds 已提交
597
	if (msg->portNumber >= serial->num_ports) {
598 599
		dev_dbg(&urb->dev->dev, "%s - Unexpected port number %d\n",
			__func__, msg->portNumber);
L
Linus Torvalds 已提交
600 601 602 603
		goto exit;
	}
	port = serial->port[msg->portNumber];
	p_priv = usb_get_serial_port_data(port);
A
Alan Cox 已提交
604

L
Linus Torvalds 已提交
605 606 607 608 609 610 611
	/* Update handshaking pin state information */
	old_dcd_state = p_priv->dcd_state;
	p_priv->cts_state = ((msg->cts) ? 1 : 0);
	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);
	p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
	p_priv->ri_state = ((msg->ri) ? 1 : 0);

J
Jiri Slaby 已提交
612 613
	if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
		tty_port_tty_hangup(&port->port, true);
L
Linus Torvalds 已提交
614

A
Alan Cox 已提交
615 616 617
	/* Resubmit urb so we continue receiving */
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err != 0)
618
		dev_dbg(&port->dev, "%s - resubmit read urb failed. (%d)\n", __func__, err);
L
Linus Torvalds 已提交
619 620 621
exit:	;
}

622
static void	usa49_inack_callback(struct urb *urb)
L
Linus Torvalds 已提交
623 624 625
{
}

626
static void	usa49_indat_callback(struct urb *urb)
L
Linus Torvalds 已提交
627 628 629 630 631
{
	int			i, err;
	int			endpoint;
	struct usb_serial_port	*port;
	unsigned char 		*data = urb->transfer_buffer;
632
	int status = urb->status;
L
Linus Torvalds 已提交
633 634 635

	endpoint = usb_pipeendpoint(urb->pipe);

636
	if (status) {
637 638
		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x on endpoint %d.\n",
			__func__, status, endpoint);
L
Linus Torvalds 已提交
639 640 641
		return;
	}

642
	port =  urb->context;
J
Jiri Slaby 已提交
643
	if (urb->actual_length) {
L
Linus Torvalds 已提交
644 645 646
		/* 0x80 bit is error flag */
		if ((data[0] & 0x80) == 0) {
			/* no error on any byte */
J
Jiri Slaby 已提交
647
			tty_insert_flip_string(&port->port, data + 1,
648
						urb->actual_length - 1);
L
Linus Torvalds 已提交
649 650 651 652 653 654 655 656 657 658 659
		} else {
			/* some bytes had errors, every byte has status */
			for (i = 0; i + 1 < urb->actual_length; i += 2) {
				int stat = data[i], flag = 0;
				if (stat & RXERROR_OVERRUN)
					flag |= TTY_OVERRUN;
				if (stat & RXERROR_FRAMING)
					flag |= TTY_FRAME;
				if (stat & RXERROR_PARITY)
					flag |= TTY_PARITY;
				/* XXX should handle break (0x10) */
J
Jiri Slaby 已提交
660 661
				tty_insert_flip_char(&port->port, data[i+1],
						flag);
L
Linus Torvalds 已提交
662 663
			}
		}
J
Jiri Slaby 已提交
664
		tty_flip_buffer_push(&port->port);
L
Linus Torvalds 已提交
665
	}
A
Alan Cox 已提交
666 667

	/* Resubmit urb so we continue receiving */
668 669
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err != 0)
670
		dev_dbg(&port->dev, "%s - resubmit read urb failed. (%d)\n", __func__, err);
L
Linus Torvalds 已提交
671 672
}

673 674 675 676 677 678
static void usa49wg_indat_callback(struct urb *urb)
{
	int			i, len, x, err;
	struct usb_serial	*serial;
	struct usb_serial_port	*port;
	unsigned char 		*data = urb->transfer_buffer;
679
	int status = urb->status;
680 681 682

	serial = urb->context;

683
	if (status) {
684
		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
685 686 687 688 689 690 691
		return;
	}

	/* inbound data is in the form P#, len, status, data */
	i = 0;
	len = 0;

692
	while (i < urb->actual_length) {
693

694 695 696 697 698 699 700 701
		/* Check port number from message */
		if (data[i] >= serial->num_ports) {
			dev_dbg(&urb->dev->dev, "%s - Unexpected port number %d\n",
				__func__, data[i]);
			return;
		}
		port = serial->port[data[i++]];
		len = data[i++];
702

703 704 705 706
		/* 0x80 bit is error flag */
		if ((data[i] & 0x80) == 0) {
			/* no error on any byte */
			i++;
707
			for (x = 1; x < len && i < urb->actual_length; ++x)
708 709 710 711 712 713
				tty_insert_flip_char(&port->port,
						data[i++], 0);
		} else {
			/*
			 * some bytes had errors, every byte has status
			 */
714 715
			for (x = 0; x + 1 < len &&
				    i + 1 < urb->actual_length; x += 2) {
716 717 718 719 720 721 722 723 724 725 726 727
				int stat = data[i], flag = 0;

				if (stat & RXERROR_OVERRUN)
					flag |= TTY_OVERRUN;
				if (stat & RXERROR_FRAMING)
					flag |= TTY_FRAME;
				if (stat & RXERROR_PARITY)
					flag |= TTY_PARITY;
				/* XXX should handle break (0x10) */
				tty_insert_flip_char(&port->port, data[i+1],
						     flag);
				i += 2;
728 729
			}
		}
730
		tty_flip_buffer_push(&port->port);
731 732 733 734 735
	}

	/* Resubmit urb so we continue receiving */
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err != 0)
736
		dev_dbg(&urb->dev->dev, "%s - resubmit read urb failed. (%d)\n", __func__, err);
737 738
}

L
Linus Torvalds 已提交
739
/* not used, usa-49 doesn't have per-port control endpoints */
740
static void usa49_outcont_callback(struct urb *urb)
L
Linus Torvalds 已提交
741 742 743
{
}

744
static void usa90_indat_callback(struct urb *urb)
L
Linus Torvalds 已提交
745 746 747 748 749 750
{
	int			i, err;
	int			endpoint;
	struct usb_serial_port	*port;
	struct keyspan_port_private	 	*p_priv;
	unsigned char 		*data = urb->transfer_buffer;
751
	int status = urb->status;
L
Linus Torvalds 已提交
752 753 754

	endpoint = usb_pipeendpoint(urb->pipe);

755
	if (status) {
756
		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x on endpoint %d.\n",
757
		    __func__, status, endpoint);
L
Linus Torvalds 已提交
758 759 760
		return;
	}

761
	port =  urb->context;
L
Linus Torvalds 已提交
762 763 764 765
	p_priv = usb_get_serial_port_data(port);

	if (urb->actual_length) {
		/* if current mode is DMA, looks like usa28 format
A
Alan Cox 已提交
766
		   otherwise looks like usa26 data format */
L
Linus Torvalds 已提交
767

768
		if (p_priv->baud > 57600)
J
Jiri Slaby 已提交
769 770
			tty_insert_flip_string(&port->port, data,
					urb->actual_length);
771
		else {
L
Linus Torvalds 已提交
772 773
			/* 0x80 bit is error flag */
			if ((data[0] & 0x80) == 0) {
A
Alan Cox 已提交
774 775
				/* no errors on individual bytes, only
				   possible overrun err*/
L
Linus Torvalds 已提交
776
				if (data[0] & RXERROR_OVERRUN)
A
Alan Cox 已提交
777 778 779 780
					err = TTY_OVERRUN;
				else
					err = 0;
				for (i = 1; i < urb->actual_length ; ++i)
J
Jiri Slaby 已提交
781 782
					tty_insert_flip_char(&port->port,
							data[i], err);
A
Alan Cox 已提交
783
			}  else {
L
Linus Torvalds 已提交
784
			/* some bytes had errors, every byte has status */
785
				dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__);
L
Linus Torvalds 已提交
786 787 788 789 790 791 792 793 794
				for (i = 0; i + 1 < urb->actual_length; i += 2) {
					int stat = data[i], flag = 0;
					if (stat & RXERROR_OVERRUN)
						flag |= TTY_OVERRUN;
					if (stat & RXERROR_FRAMING)
						flag |= TTY_FRAME;
					if (stat & RXERROR_PARITY)
						flag |= TTY_PARITY;
					/* XXX should handle break (0x10) */
J
Jiri Slaby 已提交
795 796
					tty_insert_flip_char(&port->port,
							data[i+1], flag);
L
Linus Torvalds 已提交
797 798 799
				}
			}
		}
J
Jiri Slaby 已提交
800
		tty_flip_buffer_push(&port->port);
L
Linus Torvalds 已提交
801
	}
A
Alan Cox 已提交
802

L
Linus Torvalds 已提交
803
	/* Resubmit urb so we continue receiving */
804 805
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err != 0)
806
		dev_dbg(&port->dev, "%s - resubmit read urb failed. (%d)\n", __func__, err);
L
Linus Torvalds 已提交
807 808 809
}


810
static void	usa90_instat_callback(struct urb *urb)
L
Linus Torvalds 已提交
811 812 813 814 815 816 817
{
	unsigned char 				*data = urb->transfer_buffer;
	struct keyspan_usa90_portStatusMessage	*msg;
	struct usb_serial			*serial;
	struct usb_serial_port			*port;
	struct keyspan_port_private	 	*p_priv;
	int old_dcd_state, err;
818
	int status = urb->status;
L
Linus Torvalds 已提交
819

820
	serial =  urb->context;
L
Linus Torvalds 已提交
821

822
	if (status) {
823
		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
L
Linus Torvalds 已提交
824 825 826
		return;
	}
	if (urb->actual_length < 14) {
827
		dev_dbg(&urb->dev->dev, "%s - %d byte report??\n", __func__, urb->actual_length);
L
Linus Torvalds 已提交
828 829 830 831 832 833 834 835 836
		goto exit;
	}

	msg = (struct keyspan_usa90_portStatusMessage *)data;

	/* Now do something useful with the data */

	port = serial->port[0];
	p_priv = usb_get_serial_port_data(port);
A
Alan Cox 已提交
837

L
Linus Torvalds 已提交
838 839 840 841 842 843 844
	/* Update handshaking pin state information */
	old_dcd_state = p_priv->dcd_state;
	p_priv->cts_state = ((msg->cts) ? 1 : 0);
	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);
	p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
	p_priv->ri_state = ((msg->ri) ? 1 : 0);

J
Jiri Slaby 已提交
845 846
	if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
		tty_port_tty_hangup(&port->port, true);
A
Alan Cox 已提交
847

L
Linus Torvalds 已提交
848
	/* Resubmit urb so we continue receiving */
A
Alan Cox 已提交
849 850
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err != 0)
851
		dev_dbg(&port->dev, "%s - resubmit read urb failed. (%d)\n", __func__, err);
L
Linus Torvalds 已提交
852 853 854 855
exit:
	;
}

856
static void	usa90_outcont_callback(struct urb *urb)
L
Linus Torvalds 已提交
857 858 859 860
{
	struct usb_serial_port *port;
	struct keyspan_port_private *p_priv;

861
	port =  urb->context;
L
Linus Torvalds 已提交
862 863 864
	p_priv = usb_get_serial_port_data(port);

	if (p_priv->resend_cont) {
865
		dev_dbg(&urb->dev->dev, "%s - sending setup\n", __func__);
A
Alan Cox 已提交
866 867
		keyspan_usa90_send_setup(port->serial, port,
						p_priv->resend_cont - 1);
L
Linus Torvalds 已提交
868 869 870
	}
}

871 872 873 874 875 876 877 878 879 880
/* Status messages from the 28xg */
static void	usa67_instat_callback(struct urb *urb)
{
	int					err;
	unsigned char 				*data = urb->transfer_buffer;
	struct keyspan_usa67_portStatusMessage	*msg;
	struct usb_serial			*serial;
	struct usb_serial_port			*port;
	struct keyspan_port_private	 	*p_priv;
	int old_dcd_state;
881
	int status = urb->status;
882 883 884

	serial = urb->context;

885
	if (status) {
886
		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
887 888 889
		return;
	}

A
Alan Cox 已提交
890 891
	if (urb->actual_length !=
			sizeof(struct keyspan_usa67_portStatusMessage)) {
892
		dev_dbg(&urb->dev->dev, "%s - bad length %d\n", __func__, urb->actual_length);
893 894 895 896 897 898 899 900 901
		return;
	}


	/* Now do something useful with the data */
	msg = (struct keyspan_usa67_portStatusMessage *)data;

	/* Check port number from message and retrieve private data */
	if (msg->port >= serial->num_ports) {
902
		dev_dbg(&urb->dev->dev, "%s - Unexpected port number %d\n", __func__, msg->port);
903 904 905 906 907 908 909 910 911 912 913
		return;
	}

	port = serial->port[msg->port];
	p_priv = usb_get_serial_port_data(port);

	/* Update handshaking pin state information */
	old_dcd_state = p_priv->dcd_state;
	p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
	p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);

J
Jiri Slaby 已提交
914 915
	if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
		tty_port_tty_hangup(&port->port, true);
916 917 918 919

	/* Resubmit urb so we continue receiving */
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err != 0)
920
		dev_dbg(&port->dev, "%s - resubmit read urb failed. (%d)\n", __func__, err);
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
}

static void usa67_glocont_callback(struct urb *urb)
{
	struct usb_serial *serial;
	struct usb_serial_port *port;
	struct keyspan_port_private *p_priv;
	int i;

	serial = urb->context;
	for (i = 0; i < serial->num_ports; ++i) {
		port = serial->port[i];
		p_priv = usb_get_serial_port_data(port);

		if (p_priv->resend_cont) {
936
			dev_dbg(&port->dev, "%s - sending setup\n", __func__);
937 938 939 940 941 942 943
			keyspan_usa67_send_setup(serial, port,
						p_priv->resend_cont - 1);
			break;
		}
	}
}

A
Alan Cox 已提交
944
static int keyspan_write_room(struct tty_struct *tty)
L
Linus Torvalds 已提交
945
{
A
Alan Cox 已提交
946
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
947 948 949 950 951 952 953 954 955
	struct keyspan_port_private	*p_priv;
	const struct keyspan_device_details	*d_details;
	int				flip;
	int				data_len;
	struct urb			*this_urb;

	p_priv = usb_get_serial_port_data(port);
	d_details = p_priv->device_details;

956
	/* FIXME: locking */
L
Linus Torvalds 已提交
957
	if (d_details->msg_format == msg_usa90)
A
Alan Cox 已提交
958
		data_len = 64;
L
Linus Torvalds 已提交
959 960 961 962 963 964
	else
		data_len = 63;

	flip = p_priv->out_flip;

	/* Check both endpoints to see if any are available. */
A
Alan Cox 已提交
965 966
	this_urb = p_priv->out_urbs[flip];
	if (this_urb != NULL) {
L
Linus Torvalds 已提交
967
		if (this_urb->status != -EINPROGRESS)
A
Alan Cox 已提交
968 969 970 971
			return data_len;
		flip = (flip + 1) & d_details->outdat_endp_flip;
		this_urb = p_priv->out_urbs[flip];
		if (this_urb != NULL) {
L
Linus Torvalds 已提交
972
			if (this_urb->status != -EINPROGRESS)
A
Alan Cox 已提交
973 974
				return data_len;
		}
L
Linus Torvalds 已提交
975
	}
976
	return 0;
L
Linus Torvalds 已提交
977 978 979
}


980
static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port)
L
Linus Torvalds 已提交
981
{
982
	struct keyspan_port_private 	*p_priv;
L
Linus Torvalds 已提交
983 984
	const struct keyspan_device_details	*d_details;
	int				i, err;
985
	int				baud_rate, device_port;
L
Linus Torvalds 已提交
986
	struct urb			*urb;
A
Alan Cox 已提交
987
	unsigned int			cflag = 0;
L
Linus Torvalds 已提交
988 989 990

	p_priv = usb_get_serial_port_data(port);
	d_details = p_priv->device_details;
B
Borislav Petkov 已提交
991

L
Linus Torvalds 已提交
992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
	/* Set some sane defaults */
	p_priv->rts_state = 1;
	p_priv->dtr_state = 1;
	p_priv->baud = 9600;

	/* force baud and lcr to be set on open */
	p_priv->old_baud = 0;
	p_priv->old_cflag = 0;

	p_priv->out_flip = 0;
	p_priv->in_flip = 0;

	/* Reset low level data toggle and start reading from endpoints */
	for (i = 0; i < 2; i++) {
A
Alan Cox 已提交
1006 1007
		urb = p_priv->in_urbs[i];
		if (urb == NULL)
L
Linus Torvalds 已提交
1008 1009
			continue;

A
Alan Cox 已提交
1010 1011
		/* make sure endpoint data toggle is synchronized
		   with the device */
L
Linus Torvalds 已提交
1012
		usb_clear_halt(urb->dev, urb->pipe);
A
Alan Cox 已提交
1013 1014
		err = usb_submit_urb(urb, GFP_KERNEL);
		if (err != 0)
1015
			dev_dbg(&port->dev, "%s - submit urb %d failed (%d)\n", __func__, i, err);
L
Linus Torvalds 已提交
1016 1017 1018 1019
	}

	/* Reset low level data toggle on out endpoints */
	for (i = 0; i < 2; i++) {
A
Alan Cox 已提交
1020 1021
		urb = p_priv->out_urbs[i];
		if (urb == NULL)
L
Linus Torvalds 已提交
1022
			continue;
A
Alan Cox 已提交
1023 1024
		/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
						usb_pipeout(urb->pipe), 0); */
L
Linus Torvalds 已提交
1025 1026
	}

1027 1028 1029
	/* get the terminal config for the setup message now so we don't
	 * need to send 2 of them */

1030
	device_port = port->port_number;
A
Alan Cox 已提交
1031
	if (tty) {
1032
		cflag = tty->termios.c_cflag;
A
Alan Cox 已提交
1033 1034 1035 1036 1037
		/* Baud rate calculation takes baud rate as an integer
		   so other rates can be generated if desired. */
		baud_rate = tty_get_baud_rate(tty);
		/* If no match or invalid, leave as default */
		if (baud_rate >= 0
1038
		    && d_details->calculate_baud_rate(port, baud_rate, d_details->baudclk,
A
Alan Cox 已提交
1039 1040 1041
					NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
			p_priv->baud = baud_rate;
		}
1042 1043 1044
	}
	/* set CTS/RTS handshake etc. */
	p_priv->cflag = cflag;
1045
	p_priv->flow_control = (cflag & CRTSCTS) ? flow_cts : flow_none;
1046 1047

	keyspan_send_setup(port, 1);
A
Alan Cox 已提交
1048 1049
	/* mdelay(100); */
	/* keyspan_set_termios(port, NULL); */
1050

1051
	return 0;
L
Linus Torvalds 已提交
1052 1053 1054 1055
}

static inline void stop_urb(struct urb *urb)
{
1056
	if (urb && urb->status == -EINPROGRESS)
L
Linus Torvalds 已提交
1057 1058 1059
		usb_kill_urb(urb);
}

1060 1061 1062 1063 1064 1065 1066 1067 1068 1069
static void keyspan_dtr_rts(struct usb_serial_port *port, int on)
{
	struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);

	p_priv->rts_state = on;
	p_priv->dtr_state = on;
	keyspan_send_setup(port, 0);
}

static void keyspan_close(struct usb_serial_port *port)
L
Linus Torvalds 已提交
1070 1071 1072 1073 1074
{
	int			i;
	struct keyspan_port_private 	*p_priv;

	p_priv = usb_get_serial_port_data(port);
A
Alan Cox 已提交
1075

L
Linus Torvalds 已提交
1076 1077
	p_priv->rts_state = 0;
	p_priv->dtr_state = 0;
A
Alan Cox 已提交
1078

1079 1080 1081
	keyspan_send_setup(port, 2);
	/* pilot-xfer seems to work best with this delay */
	mdelay(100);
L
Linus Torvalds 已提交
1082 1083 1084 1085

	p_priv->out_flip = 0;
	p_priv->in_flip = 0;

1086 1087 1088 1089
	stop_urb(p_priv->inack_urb);
	for (i = 0; i < 2; i++) {
		stop_urb(p_priv->in_urbs[i]);
		stop_urb(p_priv->out_urbs[i]);
L
Linus Torvalds 已提交
1090 1091 1092
	}
}

A
Alan Cox 已提交
1093 1094
/* download the firmware to a pre-renumeration device */
static int keyspan_fake_startup(struct usb_serial *serial)
L
Linus Torvalds 已提交
1095
{
1096
	char	*fw_name;
L
Linus Torvalds 已提交
1097

1098 1099 1100
	dev_dbg(&serial->dev->dev, "Keyspan startup version %04x product %04x\n",
		le16_to_cpu(serial->dev->descriptor.bcdDevice),
		le16_to_cpu(serial->dev->descriptor.idProduct));
A
Alan Cox 已提交
1101 1102 1103

	if ((le16_to_cpu(serial->dev->descriptor.bcdDevice) & 0x8000)
								!= 0x8000) {
1104
		dev_dbg(&serial->dev->dev, "Firmware already loaded.  Quitting.\n");
A
Alan Cox 已提交
1105
		return 1;
L
Linus Torvalds 已提交
1106 1107 1108 1109 1110
	}

		/* Select firmware image on the basis of idProduct */
	switch (le16_to_cpu(serial->dev->descriptor.idProduct)) {
	case keyspan_usa28_pre_product_id:
1111
		fw_name = "keyspan/usa28.fw";
L
Linus Torvalds 已提交
1112 1113 1114
		break;

	case keyspan_usa28x_pre_product_id:
1115
		fw_name = "keyspan/usa28x.fw";
L
Linus Torvalds 已提交
1116 1117 1118
		break;

	case keyspan_usa28xa_pre_product_id:
1119
		fw_name = "keyspan/usa28xa.fw";
L
Linus Torvalds 已提交
1120 1121 1122
		break;

	case keyspan_usa28xb_pre_product_id:
1123
		fw_name = "keyspan/usa28xb.fw";
L
Linus Torvalds 已提交
1124 1125 1126
		break;

	case keyspan_usa19_pre_product_id:
1127
		fw_name = "keyspan/usa19.fw";
L
Linus Torvalds 已提交
1128
		break;
A
Alan Cox 已提交
1129

L
Linus Torvalds 已提交
1130
	case keyspan_usa19qi_pre_product_id:
1131
		fw_name = "keyspan/usa19qi.fw";
L
Linus Torvalds 已提交
1132
		break;
A
Alan Cox 已提交
1133

L
Linus Torvalds 已提交
1134
	case keyspan_mpr_pre_product_id:
1135
		fw_name = "keyspan/mpr.fw";
L
Linus Torvalds 已提交
1136 1137 1138
		break;

	case keyspan_usa19qw_pre_product_id:
1139
		fw_name = "keyspan/usa19qw.fw";
L
Linus Torvalds 已提交
1140
		break;
A
Alan Cox 已提交
1141

L
Linus Torvalds 已提交
1142
	case keyspan_usa18x_pre_product_id:
1143
		fw_name = "keyspan/usa18x.fw";
L
Linus Torvalds 已提交
1144
		break;
A
Alan Cox 已提交
1145

L
Linus Torvalds 已提交
1146
	case keyspan_usa19w_pre_product_id:
1147
		fw_name = "keyspan/usa19w.fw";
L
Linus Torvalds 已提交
1148
		break;
A
Alan Cox 已提交
1149

L
Linus Torvalds 已提交
1150
	case keyspan_usa49w_pre_product_id:
1151
		fw_name = "keyspan/usa49w.fw";
L
Linus Torvalds 已提交
1152 1153 1154
		break;

	case keyspan_usa49wlc_pre_product_id:
1155
		fw_name = "keyspan/usa49wlc.fw";
L
Linus Torvalds 已提交
1156 1157 1158
		break;

	default:
1159 1160 1161
		dev_err(&serial->dev->dev, "Unknown product ID (%04x)\n",
			le16_to_cpu(serial->dev->descriptor.idProduct));
		return 1;
L
Linus Torvalds 已提交
1162 1163
	}

1164
	dev_dbg(&serial->dev->dev, "Uploading Keyspan %s firmware.\n", fw_name);
L
Linus Torvalds 已提交
1165

1166 1167 1168 1169
	if (ezusb_fx1_ihex_firmware_download(serial->dev, fw_name) < 0) {
		dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n",
			fw_name);
		return -ENOENT;
L
Linus Torvalds 已提交
1170
	}
1171 1172 1173

	/* after downloading firmware Renumeration will occur in a
	  moment and the new device will bind to the real driver */
L
Linus Torvalds 已提交
1174 1175

	/* we don't want this device to have a driver assigned to it. */
A
Alan Cox 已提交
1176
	return 1;
L
Linus Torvalds 已提交
1177 1178 1179
}

/* Helper functions used by keyspan_setup_urbs */
1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197
static struct usb_endpoint_descriptor const *find_ep(struct usb_serial const *serial,
						     int endpoint)
{
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *ep;
	int i;

	iface_desc = serial->interface->cur_altsetting;
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		ep = &iface_desc->endpoint[i].desc;
		if (ep->bEndpointAddress == endpoint)
			return ep;
	}
	dev_warn(&serial->interface->dev, "found no endpoint descriptor for "
		 "endpoint %x\n", endpoint);
	return NULL;
}

A
Alan Cox 已提交
1198
static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint,
L
Linus Torvalds 已提交
1199
				      int dir, void *ctx, char *buf, int len,
1200
				      void (*callback)(struct urb *))
L
Linus Torvalds 已提交
1201 1202
{
	struct urb *urb;
1203 1204
	struct usb_endpoint_descriptor const *ep_desc;
	char const *ep_type_name;
L
Linus Torvalds 已提交
1205 1206 1207 1208

	if (endpoint == -1)
		return NULL;		/* endpoint not needed */

1209
	dev_dbg(&serial->interface->dev, "%s - alloc for endpoint %d.\n", __func__, endpoint);
L
Linus Torvalds 已提交
1210
	urb = usb_alloc_urb(0, GFP_KERNEL);		/* No ISO */
1211
	if (!urb)
L
Linus Torvalds 已提交
1212 1213
		return NULL;

1214 1215 1216 1217 1218
	if (endpoint == 0) {
		/* control EP filled in when used */
		return urb;
	}

1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237
	ep_desc = find_ep(serial, endpoint);
	if (!ep_desc) {
		/* leak the urb, something's wrong and the callers don't care */
		return urb;
	}
	if (usb_endpoint_xfer_int(ep_desc)) {
		ep_type_name = "INT";
		usb_fill_int_urb(urb, serial->dev,
				 usb_sndintpipe(serial->dev, endpoint) | dir,
				 buf, len, callback, ctx,
				 ep_desc->bInterval);
	} else if (usb_endpoint_xfer_bulk(ep_desc)) {
		ep_type_name = "BULK";
		usb_fill_bulk_urb(urb, serial->dev,
				  usb_sndbulkpipe(serial->dev, endpoint) | dir,
				  buf, len, callback, ctx);
	} else {
		dev_warn(&serial->interface->dev,
			 "unsupported endpoint type %x\n",
1238
			 usb_endpoint_type(ep_desc));
1239 1240 1241
		usb_free_urb(urb);
		return NULL;
	}
L
Linus Torvalds 已提交
1242

1243
	dev_dbg(&serial->interface->dev, "%s - using urb %p for %s endpoint %x\n",
1244
	    __func__, urb, ep_type_name, endpoint);
L
Linus Torvalds 已提交
1245 1246 1247 1248
	return urb;
}

static struct callbacks {
1249 1250 1251 1252 1253 1254
	void	(*instat_callback)(struct urb *);
	void	(*glocont_callback)(struct urb *);
	void	(*indat_callback)(struct urb *);
	void	(*outdat_callback)(struct urb *);
	void	(*inack_callback)(struct urb *);
	void	(*outcont_callback)(struct urb *);
L
Linus Torvalds 已提交
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282
} keyspan_callbacks[] = {
	{
		/* msg_usa26 callbacks */
		.instat_callback =	usa26_instat_callback,
		.glocont_callback =	usa26_glocont_callback,
		.indat_callback =	usa26_indat_callback,
		.outdat_callback =	usa2x_outdat_callback,
		.inack_callback =	usa26_inack_callback,
		.outcont_callback =	usa26_outcont_callback,
	}, {
		/* msg_usa28 callbacks */
		.instat_callback =	usa28_instat_callback,
		.glocont_callback =	usa28_glocont_callback,
		.indat_callback =	usa28_indat_callback,
		.outdat_callback =	usa2x_outdat_callback,
		.inack_callback =	usa28_inack_callback,
		.outcont_callback =	usa28_outcont_callback,
	}, {
		/* msg_usa49 callbacks */
		.instat_callback =	usa49_instat_callback,
		.glocont_callback =	usa49_glocont_callback,
		.indat_callback =	usa49_indat_callback,
		.outdat_callback =	usa2x_outdat_callback,
		.inack_callback =	usa49_inack_callback,
		.outcont_callback =	usa49_outcont_callback,
	}, {
		/* msg_usa90 callbacks */
		.instat_callback =	usa90_instat_callback,
A
Alan Cox 已提交
1283
		.glocont_callback =	usa28_glocont_callback,
L
Linus Torvalds 已提交
1284 1285 1286 1287
		.indat_callback =	usa90_indat_callback,
		.outdat_callback =	usa2x_outdat_callback,
		.inack_callback =	usa28_inack_callback,
		.outcont_callback =	usa90_outcont_callback,
1288 1289 1290 1291 1292 1293 1294 1295
	}, {
		/* msg_usa67 callbacks */
		.instat_callback =	usa67_instat_callback,
		.glocont_callback =	usa67_glocont_callback,
		.indat_callback =	usa26_indat_callback,
		.outdat_callback =	usa2x_outdat_callback,
		.inack_callback =	usa26_inack_callback,
		.outcont_callback =	usa26_outcont_callback,
L
Linus Torvalds 已提交
1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309
	}
};

	/* Generic setup urbs function that uses
	   data in device_details */
static void keyspan_setup_urbs(struct usb_serial *serial)
{
	struct keyspan_serial_private 	*s_priv;
	const struct keyspan_device_details	*d_details;
	struct callbacks		*cback;

	s_priv = usb_get_serial_data(serial);
	d_details = s_priv->device_details;

A
Alan Cox 已提交
1310
	/* Setup values for the various callback routines */
L
Linus Torvalds 已提交
1311 1312
	cback = &keyspan_callbacks[d_details->msg_format];

A
Alan Cox 已提交
1313 1314
	/* Allocate and set up urbs for each one that is in use,
	   starting with instat endpoints */
L
Linus Torvalds 已提交
1315 1316 1317 1318 1319
	s_priv->instat_urb = keyspan_setup_urb
		(serial, d_details->instat_endpoint, USB_DIR_IN,
		 serial, s_priv->instat_buf, INSTAT_BUFLEN,
		 cback->instat_callback);

1320 1321 1322 1323 1324
	s_priv->indat_urb = keyspan_setup_urb
		(serial, d_details->indat_endpoint, USB_DIR_IN,
		 serial, s_priv->indat_buf, INDAT49W_BUFLEN,
		 usa49wg_indat_callback);

L
Linus Torvalds 已提交
1325 1326 1327 1328 1329 1330 1331
	s_priv->glocont_urb = keyspan_setup_urb
		(serial, d_details->glocont_endpoint, USB_DIR_OUT,
		 serial, s_priv->glocont_buf, GLOCONT_BUFLEN,
		 cback->glocont_callback);
}

/* usa19 function doesn't require prescaler */
1332 1333
static int keyspan_usa19_calc_baud(struct usb_serial_port *port,
				   u32 baud_rate, u32 baudclk, u8 *rate_hi,
L
Linus Torvalds 已提交
1334 1335 1336
				   u8 *rate_low, u8 *prescaler, int portnum)
{
	u32 	b16,	/* baud rate times 16 (actual rate used internally) */
A
Alan Cox 已提交
1337
		div,	/* divisor */
L
Linus Torvalds 已提交
1338 1339
		cnt;	/* inverse of divisor (programmed into 8051) */

1340
	dev_dbg(&port->dev, "%s - %d.\n", __func__, baud_rate);
A
Alan Cox 已提交
1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355

	/* prevent divide by zero...  */
	b16 = baud_rate * 16L;
	if (b16 == 0)
		return KEYSPAN_INVALID_BAUD_RATE;
	/* Any "standard" rate over 57k6 is marginal on the USA-19
	   as we run out of divisor resolution. */
	if (baud_rate > 57600)
		return KEYSPAN_INVALID_BAUD_RATE;

	/* calculate the divisor and the counter (its inverse) */
	div = baudclk / b16;
	if (div == 0)
		return KEYSPAN_INVALID_BAUD_RATE;
	else
L
Linus Torvalds 已提交
1356 1357
		cnt = 0 - div;

A
Alan Cox 已提交
1358 1359
	if (div > 0xffff)
		return KEYSPAN_INVALID_BAUD_RATE;
L
Linus Torvalds 已提交
1360

A
Alan Cox 已提交
1361 1362
	/* return the counter values if non-null */
	if (rate_low)
L
Linus Torvalds 已提交
1363
		*rate_low = (u8) (cnt & 0xff);
A
Alan Cox 已提交
1364
	if (rate_hi)
L
Linus Torvalds 已提交
1365
		*rate_hi = (u8) ((cnt >> 8) & 0xff);
A
Alan Cox 已提交
1366
	if (rate_low && rate_hi)
1367
		dev_dbg(&port->dev, "%s - %d %02x %02x.\n",
A
Alan Cox 已提交
1368 1369
				__func__, baud_rate, *rate_hi, *rate_low);
	return KEYSPAN_BAUD_RATE_OK;
L
Linus Torvalds 已提交
1370 1371 1372
}

/* usa19hs function doesn't require prescaler */
1373 1374 1375
static int keyspan_usa19hs_calc_baud(struct usb_serial_port *port,
				     u32 baud_rate, u32 baudclk, u8 *rate_hi,
				     u8 *rate_low, u8 *prescaler, int portnum)
L
Linus Torvalds 已提交
1376 1377
{
	u32 	b16,	/* baud rate times 16 (actual rate used internally) */
A
Alan Cox 已提交
1378
			div;	/* divisor */
L
Linus Torvalds 已提交
1379

1380
	dev_dbg(&port->dev, "%s - %d.\n", __func__, baud_rate);
L
Linus Torvalds 已提交
1381

A
Alan Cox 已提交
1382 1383 1384 1385
	/* prevent divide by zero...  */
	b16 = baud_rate * 16L;
	if (b16 == 0)
		return KEYSPAN_INVALID_BAUD_RATE;
L
Linus Torvalds 已提交
1386

A
Alan Cox 已提交
1387 1388 1389 1390
	/* calculate the divisor */
	div = baudclk / b16;
	if (div == 0)
		return KEYSPAN_INVALID_BAUD_RATE;
L
Linus Torvalds 已提交
1391

A
Alan Cox 已提交
1392 1393
	if (div > 0xffff)
		return KEYSPAN_INVALID_BAUD_RATE;
L
Linus Torvalds 已提交
1394

A
Alan Cox 已提交
1395 1396
	/* return the counter values if non-null */
	if (rate_low)
L
Linus Torvalds 已提交
1397
		*rate_low = (u8) (div & 0xff);
A
Alan Cox 已提交
1398 1399

	if (rate_hi)
L
Linus Torvalds 已提交
1400
		*rate_hi = (u8) ((div >> 8) & 0xff);
A
Alan Cox 已提交
1401 1402

	if (rate_low && rate_hi)
1403
		dev_dbg(&port->dev, "%s - %d %02x %02x.\n",
A
Alan Cox 已提交
1404 1405 1406
			__func__, baud_rate, *rate_hi, *rate_low);

	return KEYSPAN_BAUD_RATE_OK;
L
Linus Torvalds 已提交
1407 1408
}

1409 1410
static int keyspan_usa19w_calc_baud(struct usb_serial_port *port,
				    u32 baud_rate, u32 baudclk, u8 *rate_hi,
L
Linus Torvalds 已提交
1411 1412 1413 1414
				    u8 *rate_low, u8 *prescaler, int portnum)
{
	u32 	b16,	/* baud rate times 16 (actual rate used internally) */
		clk,	/* clock with 13/8 prescaler */
A
Alan Cox 已提交
1415
		div,	/* divisor using 13/8 prescaler */
L
Linus Torvalds 已提交
1416 1417 1418 1419 1420 1421
		res,	/* resulting baud rate using 13/8 prescaler */
		diff,	/* error using 13/8 prescaler */
		smallest_diff;
	u8	best_prescaler;
	int	i;

1422
	dev_dbg(&port->dev, "%s - %d.\n", __func__, baud_rate);
L
Linus Torvalds 已提交
1423

A
Alan Cox 已提交
1424 1425 1426 1427
	/* prevent divide by zero */
	b16 = baud_rate * 16L;
	if (b16 == 0)
		return KEYSPAN_INVALID_BAUD_RATE;
L
Linus Torvalds 已提交
1428

A
Alan Cox 已提交
1429 1430 1431 1432
	/* Calculate prescaler by trying them all and looking
	   for best fit */

	/* start with largest possible difference */
L
Linus Torvalds 已提交
1433 1434 1435 1436 1437
	smallest_diff = 0xffffffff;

		/* 0 is an invalid prescaler, used as a flag */
	best_prescaler = 0;

A
Alan Cox 已提交
1438
	for (i = 8; i <= 0xff; ++i) {
L
Linus Torvalds 已提交
1439
		clk = (baudclk * 8) / (u32) i;
A
Alan Cox 已提交
1440 1441 1442

		div = clk / b16;
		if (div == 0)
L
Linus Torvalds 已提交
1443 1444 1445
			continue;

		res = clk / div;
A
Alan Cox 已提交
1446
		diff = (res > b16) ? (res-b16) : (b16-res);
L
Linus Torvalds 已提交
1447

A
Alan Cox 已提交
1448
		if (diff < smallest_diff) {
L
Linus Torvalds 已提交
1449 1450 1451 1452 1453
			best_prescaler = i;
			smallest_diff = diff;
		}
	}

A
Alan Cox 已提交
1454 1455
	if (best_prescaler == 0)
		return KEYSPAN_INVALID_BAUD_RATE;
L
Linus Torvalds 已提交
1456 1457 1458 1459

	clk = (baudclk * 8) / (u32) best_prescaler;
	div = clk / b16;

A
Alan Cox 已提交
1460 1461
	/* return the divisor and prescaler if non-null */
	if (rate_low)
L
Linus Torvalds 已提交
1462
		*rate_low = (u8) (div & 0xff);
A
Alan Cox 已提交
1463
	if (rate_hi)
L
Linus Torvalds 已提交
1464 1465 1466
		*rate_hi = (u8) ((div >> 8) & 0xff);
	if (prescaler) {
		*prescaler = best_prescaler;
1467
		/*  dev_dbg(&port->dev, "%s - %d %d\n", __func__, *prescaler, div); */
L
Linus Torvalds 已提交
1468
	}
A
Alan Cox 已提交
1469
	return KEYSPAN_BAUD_RATE_OK;
L
Linus Torvalds 已提交
1470 1471 1472
}

	/* USA-28 supports different maximum baud rates on each port */
1473 1474 1475
static int keyspan_usa28_calc_baud(struct usb_serial_port *port,
				   u32 baud_rate, u32 baudclk, u8 *rate_hi,
				   u8 *rate_low, u8 *prescaler, int portnum)
L
Linus Torvalds 已提交
1476 1477
{
	u32 	b16,	/* baud rate times 16 (actual rate used internally) */
A
Alan Cox 已提交
1478
		div,	/* divisor */
L
Linus Torvalds 已提交
1479 1480
		cnt;	/* inverse of divisor (programmed into 8051) */

1481
	dev_dbg(&port->dev, "%s - %d.\n", __func__, baud_rate);
L
Linus Torvalds 已提交
1482 1483

		/* prevent divide by zero */
A
Alan Cox 已提交
1484 1485 1486 1487 1488 1489 1490 1491 1492
	b16 = baud_rate * 16L;
	if (b16 == 0)
		return KEYSPAN_INVALID_BAUD_RATE;

	/* calculate the divisor and the counter (its inverse) */
	div = KEYSPAN_USA28_BAUDCLK / b16;
	if (div == 0)
		return KEYSPAN_INVALID_BAUD_RATE;
	else
L
Linus Torvalds 已提交
1493 1494
		cnt = 0 - div;

A
Alan Cox 已提交
1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505
	/* check for out of range, based on portnum,
	   and return result */
	if (portnum == 0) {
		if (div > 0xffff)
			return KEYSPAN_INVALID_BAUD_RATE;
	} else {
		if (portnum == 1) {
			if (div > 0xff)
				return KEYSPAN_INVALID_BAUD_RATE;
		} else
			return KEYSPAN_INVALID_BAUD_RATE;
L
Linus Torvalds 已提交
1506 1507 1508 1509
	}

		/* return the counter values if not NULL
		   (port 1 will ignore retHi) */
A
Alan Cox 已提交
1510
	if (rate_low)
L
Linus Torvalds 已提交
1511
		*rate_low = (u8) (cnt & 0xff);
A
Alan Cox 已提交
1512
	if (rate_hi)
L
Linus Torvalds 已提交
1513
		*rate_hi = (u8) ((cnt >> 8) & 0xff);
1514
	dev_dbg(&port->dev, "%s - %d OK.\n", __func__, baud_rate);
A
Alan Cox 已提交
1515
	return KEYSPAN_BAUD_RATE_OK;
L
Linus Torvalds 已提交
1516 1517 1518 1519 1520 1521
}

static int keyspan_usa26_send_setup(struct usb_serial *serial,
				    struct usb_serial_port *port,
				    int reset_port)
{
A
Alan Cox 已提交
1522
	struct keyspan_usa26_portControlMessage	msg;
L
Linus Torvalds 已提交
1523 1524 1525 1526 1527 1528
	struct keyspan_serial_private 		*s_priv;
	struct keyspan_port_private 		*p_priv;
	const struct keyspan_device_details	*d_details;
	struct urb				*this_urb;
	int 					device_port, err;

1529
	dev_dbg(&port->dev, "%s reset=%d\n", __func__, reset_port);
L
Linus Torvalds 已提交
1530 1531 1532 1533

	s_priv = usb_get_serial_data(serial);
	p_priv = usb_get_serial_port_data(port);
	d_details = s_priv->device_details;
1534
	device_port = port->port_number;
L
Linus Torvalds 已提交
1535 1536 1537 1538 1539

	this_urb = p_priv->outcont_urb;

		/* Make sure we have an urb then send the message */
	if (this_urb == NULL) {
1540
		dev_dbg(&port->dev, "%s - oops no urb.\n", __func__);
L
Linus Torvalds 已提交
1541 1542 1543
		return -1;
	}

1544 1545
	dev_dbg(&port->dev, "%s - endpoint %d\n", __func__, usb_pipeendpoint(this_urb->pipe));

L
Linus Torvalds 已提交
1546
	/* Save reset port val for resend.
1547 1548
	   Don't overwrite resend for open/close condition. */
	if ((reset_port + 1) > p_priv->resend_cont)
L
Linus Torvalds 已提交
1549 1550
		p_priv->resend_cont = reset_port + 1;
	if (this_urb->status == -EINPROGRESS) {
1551
		/*  dev_dbg(&port->dev, "%s - already writing\n", __func__); */
L
Linus Torvalds 已提交
1552
		mdelay(5);
A
Alan Cox 已提交
1553
		return -1;
L
Linus Torvalds 已提交
1554 1555
	}

A
Alan Cox 已提交
1556 1557 1558
	memset(&msg, 0, sizeof(struct keyspan_usa26_portControlMessage));

	/* Only set baud rate if it's changed */
L
Linus Torvalds 已提交
1559 1560 1561
	if (p_priv->old_baud != p_priv->baud) {
		p_priv->old_baud = p_priv->baud;
		msg.setClocking = 0xff;
1562 1563 1564 1565 1566
		if (d_details->calculate_baud_rate(port, p_priv->baud, d_details->baudclk,
						   &msg.baudHi, &msg.baudLo, &msg.prescaler,
						   device_port) == KEYSPAN_INVALID_BAUD_RATE) {
			dev_dbg(&port->dev, "%s - Invalid baud rate %d requested, using 9600.\n",
				__func__, p_priv->baud);
L
Linus Torvalds 已提交
1567 1568 1569 1570 1571 1572 1573
			msg.baudLo = 0;
			msg.baudHi = 125;	/* Values for 9600 baud */
			msg.prescaler = 10;
		}
		msg.setPrescaler = 0xff;
	}

1574
	msg.lcr = (p_priv->cflag & CSTOPB) ? STOPBITS_678_2 : STOPBITS_5678_1;
L
Linus Torvalds 已提交
1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590
	switch (p_priv->cflag & CSIZE) {
	case CS5:
		msg.lcr |= USA_DATABITS_5;
		break;
	case CS6:
		msg.lcr |= USA_DATABITS_6;
		break;
	case CS7:
		msg.lcr |= USA_DATABITS_7;
		break;
	case CS8:
		msg.lcr |= USA_DATABITS_8;
		break;
	}
	if (p_priv->cflag & PARENB) {
		/* note USA_PARITY_NONE == 0 */
1591
		msg.lcr |= (p_priv->cflag & PARODD) ?
A
Alan Cox 已提交
1592
			USA_PARITY_ODD : USA_PARITY_EVEN;
L
Linus Torvalds 已提交
1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632
	}
	msg.setLcr = 0xff;

	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
	msg.xonFlowControl = 0;
	msg.setFlowControl = 0xff;
	msg.forwardingLength = 16;
	msg.xonChar = 17;
	msg.xoffChar = 19;

	/* Opening port */
	if (reset_port == 1) {
		msg._txOn = 1;
		msg._txOff = 0;
		msg.txFlush = 0;
		msg.txBreak = 0;
		msg.rxOn = 1;
		msg.rxOff = 0;
		msg.rxFlush = 1;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0xff;
	}

	/* Closing port */
	else if (reset_port == 2) {
		msg._txOn = 0;
		msg._txOff = 1;
		msg.txFlush = 0;
		msg.txBreak = 0;
		msg.rxOn = 0;
		msg.rxOff = 1;
		msg.rxFlush = 1;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0;
	}

	/* Sending intermediate configs */
	else {
A
Alan Cox 已提交
1633
		msg._txOn = (!p_priv->break_on);
L
Linus Torvalds 已提交
1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644
		msg._txOff = 0;
		msg.txFlush = 0;
		msg.txBreak = (p_priv->break_on);
		msg.rxOn = 0;
		msg.rxOff = 0;
		msg.rxFlush = 0;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0x0;
	}

A
Alan Cox 已提交
1645
	/* Do handshaking outputs */
L
Linus Torvalds 已提交
1646 1647 1648 1649 1650
	msg.setTxTriState_setRts = 0xff;
	msg.txTriState_rts = p_priv->rts_state;

	msg.setHskoa_setDtr = 0xff;
	msg.hskoa_dtr = p_priv->dtr_state;
A
Alan Cox 已提交
1651

L
Linus Torvalds 已提交
1652
	p_priv->resend_cont = 0;
A
Alan Cox 已提交
1653 1654
	memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));

L
Linus Torvalds 已提交
1655 1656 1657
	/* send the data out the device on control endpoint */
	this_urb->transfer_buffer_length = sizeof(msg);

A
Alan Cox 已提交
1658 1659
	err = usb_submit_urb(this_urb, GFP_ATOMIC);
	if (err != 0)
1660
		dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err);
1661
	return 0;
L
Linus Torvalds 已提交
1662 1663 1664 1665 1666 1667
}

static int keyspan_usa28_send_setup(struct usb_serial *serial,
				    struct usb_serial_port *port,
				    int reset_port)
{
A
Alan Cox 已提交
1668
	struct keyspan_usa28_portControlMessage	msg;
L
Linus Torvalds 已提交
1669 1670 1671 1672 1673 1674 1675 1676 1677
	struct keyspan_serial_private	 	*s_priv;
	struct keyspan_port_private 		*p_priv;
	const struct keyspan_device_details	*d_details;
	struct urb				*this_urb;
	int 					device_port, err;

	s_priv = usb_get_serial_data(serial);
	p_priv = usb_get_serial_port_data(port);
	d_details = s_priv->device_details;
1678
	device_port = port->port_number;
L
Linus Torvalds 已提交
1679 1680

	/* only do something if we have a bulk out endpoint */
A
Alan Cox 已提交
1681 1682
	this_urb = p_priv->outcont_urb;
	if (this_urb == NULL) {
1683
		dev_dbg(&port->dev, "%s - oops no urb.\n", __func__);
L
Linus Torvalds 已提交
1684 1685 1686 1687
		return -1;
	}

	/* Save reset port val for resend.
1688 1689
	   Don't overwrite resend for open/close condition. */
	if ((reset_port + 1) > p_priv->resend_cont)
L
Linus Torvalds 已提交
1690 1691
		p_priv->resend_cont = reset_port + 1;
	if (this_urb->status == -EINPROGRESS) {
1692
		dev_dbg(&port->dev, "%s already writing\n", __func__);
L
Linus Torvalds 已提交
1693
		mdelay(5);
A
Alan Cox 已提交
1694
		return -1;
L
Linus Torvalds 已提交
1695 1696
	}

A
Alan Cox 已提交
1697
	memset(&msg, 0, sizeof(struct keyspan_usa28_portControlMessage));
L
Linus Torvalds 已提交
1698 1699

	msg.setBaudRate = 1;
1700 1701 1702 1703
	if (d_details->calculate_baud_rate(port, p_priv->baud, d_details->baudclk,
					   &msg.baudHi, &msg.baudLo, NULL,
					   device_port) == KEYSPAN_INVALID_BAUD_RATE) {
		dev_dbg(&port->dev, "%s - Invalid baud rate requested %d.\n",
A
Alan Cox 已提交
1704
						__func__, p_priv->baud);
L
Linus Torvalds 已提交
1705 1706 1707 1708 1709 1710 1711 1712 1713 1714
		msg.baudLo = 0xff;
		msg.baudHi = 0xb2;	/* Values for 9600 baud */
	}

	/* If parity is enabled, we must calculate it ourselves. */
	msg.parity = 0;		/* XXX for now */

	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
	msg.xonFlowControl = 0;

A
Alan Cox 已提交
1715
	/* Do handshaking outputs, DTR is inverted relative to RTS */
L
Linus Torvalds 已提交
1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756
	msg.rts = p_priv->rts_state;
	msg.dtr = p_priv->dtr_state;

	msg.forwardingLength = 16;
	msg.forwardMs = 10;
	msg.breakThreshold = 45;
	msg.xonChar = 17;
	msg.xoffChar = 19;

	/*msg.returnStatus = 1;
	msg.resetDataToggle = 0xff;*/
	/* Opening port */
	if (reset_port == 1) {
		msg._txOn = 1;
		msg._txOff = 0;
		msg.txFlush = 0;
		msg.txForceXoff = 0;
		msg.txBreak = 0;
		msg.rxOn = 1;
		msg.rxOff = 0;
		msg.rxFlush = 1;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0xff;
	}
	/* Closing port */
	else if (reset_port == 2) {
		msg._txOn = 0;
		msg._txOff = 1;
		msg.txFlush = 0;
		msg.txForceXoff = 0;
		msg.txBreak = 0;
		msg.rxOn = 0;
		msg.rxOff = 1;
		msg.rxFlush = 1;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0;
	}
	/* Sending intermediate configs */
	else {
A
Alan Cox 已提交
1757
		msg._txOn = (!p_priv->break_on);
L
Linus Torvalds 已提交
1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770
		msg._txOff = 0;
		msg.txFlush = 0;
		msg.txForceXoff = 0;
		msg.txBreak = (p_priv->break_on);
		msg.rxOn = 0;
		msg.rxOff = 0;
		msg.rxFlush = 0;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0x0;
	}

	p_priv->resend_cont = 0;
A
Alan Cox 已提交
1771
	memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
L
Linus Torvalds 已提交
1772 1773 1774 1775

	/* send the data out the device on control endpoint */
	this_urb->transfer_buffer_length = sizeof(msg);

A
Alan Cox 已提交
1776 1777
	err = usb_submit_urb(this_urb, GFP_ATOMIC);
	if (err != 0)
1778
		dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed\n", __func__);
L
Linus Torvalds 已提交
1779

1780
	return 0;
L
Linus Torvalds 已提交
1781 1782 1783 1784 1785 1786
}

static int keyspan_usa49_send_setup(struct usb_serial *serial,
				    struct usb_serial_port *port,
				    int reset_port)
{
1787 1788
	struct keyspan_usa49_portControlMessage	msg;
	struct usb_ctrlrequest 			*dr = NULL;
L
Linus Torvalds 已提交
1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800
	struct keyspan_serial_private 		*s_priv;
	struct keyspan_port_private 		*p_priv;
	const struct keyspan_device_details	*d_details;
	struct urb				*this_urb;
	int 					err, device_port;

	s_priv = usb_get_serial_data(serial);
	p_priv = usb_get_serial_port_data(port);
	d_details = s_priv->device_details;

	this_urb = s_priv->glocont_urb;

1801
	/* Work out which port within the device is being setup */
1802
	device_port = port->port_number;
L
Linus Torvalds 已提交
1803

1804
	/* Make sure we have an urb then send the message */
L
Linus Torvalds 已提交
1805
	if (this_urb == NULL) {
1806
		dev_dbg(&port->dev, "%s - oops no urb for port.\n", __func__);
L
Linus Torvalds 已提交
1807 1808 1809
		return -1;
	}

1810 1811
	dev_dbg(&port->dev, "%s - endpoint %d (%d)\n",
		__func__, usb_pipeendpoint(this_urb->pipe), device_port);
1812

L
Linus Torvalds 已提交
1813
	/* Save reset port val for resend.
1814 1815
	   Don't overwrite resend for open/close condition. */
	if ((reset_port + 1) > p_priv->resend_cont)
L
Linus Torvalds 已提交
1816
		p_priv->resend_cont = reset_port + 1;
1817

L
Linus Torvalds 已提交
1818
	if (this_urb->status == -EINPROGRESS) {
1819
		/*  dev_dbg(&port->dev, "%s - already writing\n", __func__); */
L
Linus Torvalds 已提交
1820
		mdelay(5);
A
Alan Cox 已提交
1821
		return -1;
L
Linus Torvalds 已提交
1822 1823
	}

A
Alan Cox 已提交
1824
	memset(&msg, 0, sizeof(struct keyspan_usa49_portControlMessage));
L
Linus Torvalds 已提交
1825 1826

	msg.portNumber = device_port;
A
Alan Cox 已提交
1827 1828

	/* Only set baud rate if it's changed */
L
Linus Torvalds 已提交
1829 1830 1831
	if (p_priv->old_baud != p_priv->baud) {
		p_priv->old_baud = p_priv->baud;
		msg.setClocking = 0xff;
1832 1833 1834 1835 1836
		if (d_details->calculate_baud_rate(port, p_priv->baud, d_details->baudclk,
						   &msg.baudHi, &msg.baudLo, &msg.prescaler,
						   device_port) == KEYSPAN_INVALID_BAUD_RATE) {
			dev_dbg(&port->dev, "%s - Invalid baud rate %d requested, using 9600.\n",
				__func__, p_priv->baud);
L
Linus Torvalds 已提交
1837 1838 1839 1840
			msg.baudLo = 0;
			msg.baudHi = 125;	/* Values for 9600 baud */
			msg.prescaler = 10;
		}
A
Alan Cox 已提交
1841
		/* msg.setPrescaler = 0xff; */
L
Linus Torvalds 已提交
1842 1843
	}

1844
	msg.lcr = (p_priv->cflag & CSTOPB) ? STOPBITS_678_2 : STOPBITS_5678_1;
L
Linus Torvalds 已提交
1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860
	switch (p_priv->cflag & CSIZE) {
	case CS5:
		msg.lcr |= USA_DATABITS_5;
		break;
	case CS6:
		msg.lcr |= USA_DATABITS_6;
		break;
	case CS7:
		msg.lcr |= USA_DATABITS_7;
		break;
	case CS8:
		msg.lcr |= USA_DATABITS_8;
		break;
	}
	if (p_priv->cflag & PARENB) {
		/* note USA_PARITY_NONE == 0 */
1861
		msg.lcr |= (p_priv->cflag & PARODD) ?
A
Alan Cox 已提交
1862
			USA_PARITY_ODD : USA_PARITY_EVEN;
L
Linus Torvalds 已提交
1863 1864 1865 1866 1867 1868
	}
	msg.setLcr = 0xff;

	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
	msg.xonFlowControl = 0;
	msg.setFlowControl = 0xff;
A
Alan Cox 已提交
1869

L
Linus Torvalds 已提交
1870 1871 1872 1873
	msg.forwardingLength = 16;
	msg.xonChar = 17;
	msg.xoffChar = 19;

A
Alan Cox 已提交
1874
	/* Opening port */
L
Linus Torvalds 已提交
1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905
	if (reset_port == 1) {
		msg._txOn = 1;
		msg._txOff = 0;
		msg.txFlush = 0;
		msg.txBreak = 0;
		msg.rxOn = 1;
		msg.rxOff = 0;
		msg.rxFlush = 1;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0xff;
		msg.enablePort = 1;
		msg.disablePort = 0;
	}
	/* Closing port */
	else if (reset_port == 2) {
		msg._txOn = 0;
		msg._txOff = 1;
		msg.txFlush = 0;
		msg.txBreak = 0;
		msg.rxOn = 0;
		msg.rxOff = 1;
		msg.rxFlush = 1;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0;
		msg.enablePort = 0;
		msg.disablePort = 1;
	}
	/* Sending intermediate configs */
	else {
A
Alan Cox 已提交
1906
		msg._txOn = (!p_priv->break_on);
L
Linus Torvalds 已提交
1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919
		msg._txOff = 0;
		msg.txFlush = 0;
		msg.txBreak = (p_priv->break_on);
		msg.rxOn = 0;
		msg.rxOff = 0;
		msg.rxFlush = 0;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0x0;
		msg.enablePort = 0;
		msg.disablePort = 0;
	}

A
Alan Cox 已提交
1920
	/* Do handshaking outputs */
L
Linus Torvalds 已提交
1921 1922 1923 1924 1925
	msg.setRts = 0xff;
	msg.rts = p_priv->rts_state;

	msg.setDtr = 0xff;
	msg.dtr = p_priv->dtr_state;
A
Alan Cox 已提交
1926

L
Linus Torvalds 已提交
1927
	p_priv->resend_cont = 0;
1928

A
Alan Cox 已提交
1929 1930
	/* if the device is a 49wg, we send control message on usb
	   control EP 0 */
1931 1932 1933 1934 1935 1936 1937 1938 1939

	if (d_details->product_id == keyspan_usa49wg_product_id) {
		dr = (void *)(s_priv->ctrl_buf);
		dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT;
		dr->bRequest = 0xB0;	/* 49wg control message */;
		dr->wValue = 0;
		dr->wIndex = 0;
		dr->wLength = cpu_to_le16(sizeof(msg));

A
Alan Cox 已提交
1940
		memcpy(s_priv->glocont_buf, &msg, sizeof(msg));
1941

A
Alan Cox 已提交
1942 1943 1944 1945
		usb_fill_control_urb(this_urb, serial->dev,
				usb_sndctrlpipe(serial->dev, 0),
				(unsigned char *)dr, s_priv->glocont_buf,
				sizeof(msg), usa49_glocont_callback, serial);
1946 1947 1948

	} else {
		memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
A
Alan Cox 已提交
1949

1950 1951 1952
		/* send the data out the device on control endpoint */
		this_urb->transfer_buffer_length = sizeof(msg);
	}
A
Alan Cox 已提交
1953 1954
	err = usb_submit_urb(this_urb, GFP_ATOMIC);
	if (err != 0)
1955
		dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err);
L
Linus Torvalds 已提交
1956

1957
	return 0;
L
Linus Torvalds 已提交
1958 1959 1960 1961 1962 1963
}

static int keyspan_usa90_send_setup(struct usb_serial *serial,
				    struct usb_serial_port *port,
				    int reset_port)
{
A
Alan Cox 已提交
1964
	struct keyspan_usa90_portControlMessage	msg;
L
Linus Torvalds 已提交
1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976
	struct keyspan_serial_private 		*s_priv;
	struct keyspan_port_private 		*p_priv;
	const struct keyspan_device_details	*d_details;
	struct urb				*this_urb;
	int 					err;
	u8						prescaler;

	s_priv = usb_get_serial_data(serial);
	p_priv = usb_get_serial_port_data(port);
	d_details = s_priv->device_details;

	/* only do something if we have a bulk out endpoint */
A
Alan Cox 已提交
1977 1978
	this_urb = p_priv->outcont_urb;
	if (this_urb == NULL) {
1979
		dev_dbg(&port->dev, "%s - oops no urb.\n", __func__);
L
Linus Torvalds 已提交
1980 1981 1982 1983 1984 1985 1986 1987
		return -1;
	}

	/* Save reset port val for resend.
	   Don't overwrite resend for open/close condition. */
	if ((reset_port + 1) > p_priv->resend_cont)
		p_priv->resend_cont = reset_port + 1;
	if (this_urb->status == -EINPROGRESS) {
1988
		dev_dbg(&port->dev, "%s already writing\n", __func__);
L
Linus Torvalds 已提交
1989
		mdelay(5);
A
Alan Cox 已提交
1990
		return -1;
L
Linus Torvalds 已提交
1991 1992
	}

A
Alan Cox 已提交
1993
	memset(&msg, 0, sizeof(struct keyspan_usa90_portControlMessage));
L
Linus Torvalds 已提交
1994

A
Alan Cox 已提交
1995
	/* Only set baud rate if it's changed */
L
Linus Torvalds 已提交
1996 1997 1998
	if (p_priv->old_baud != p_priv->baud) {
		p_priv->old_baud = p_priv->baud;
		msg.setClocking = 0x01;
1999 2000 2001 2002
		if (d_details->calculate_baud_rate(port, p_priv->baud, d_details->baudclk,
						   &msg.baudHi, &msg.baudLo, &prescaler, 0) == KEYSPAN_INVALID_BAUD_RATE) {
			dev_dbg(&port->dev, "%s - Invalid baud rate %d requested, using 9600.\n",
				__func__, p_priv->baud);
L
Linus Torvalds 已提交
2003
			p_priv->baud = 9600;
2004
			d_details->calculate_baud_rate(port, p_priv->baud, d_details->baudclk,
L
Linus Torvalds 已提交
2005 2006 2007 2008 2009 2010 2011
				&msg.baudHi, &msg.baudLo, &prescaler, 0);
		}
		msg.setRxMode = 1;
		msg.setTxMode = 1;
	}

	/* modes must always be correctly specified */
A
Alan Cox 已提交
2012
	if (p_priv->baud > 57600) {
L
Linus Torvalds 已提交
2013 2014
		msg.rxMode = RXMODE_DMA;
		msg.txMode = TXMODE_DMA;
A
Alan Cox 已提交
2015
	} else {
L
Linus Torvalds 已提交
2016 2017 2018 2019
		msg.rxMode = RXMODE_BYHAND;
		msg.txMode = TXMODE_BYHAND;
	}

2020
	msg.lcr = (p_priv->cflag & CSTOPB) ? STOPBITS_678_2 : STOPBITS_5678_1;
L
Linus Torvalds 已提交
2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036
	switch (p_priv->cflag & CSIZE) {
	case CS5:
		msg.lcr |= USA_DATABITS_5;
		break;
	case CS6:
		msg.lcr |= USA_DATABITS_6;
		break;
	case CS7:
		msg.lcr |= USA_DATABITS_7;
		break;
	case CS8:
		msg.lcr |= USA_DATABITS_8;
		break;
	}
	if (p_priv->cflag & PARENB) {
		/* note USA_PARITY_NONE == 0 */
2037
		msg.lcr |= (p_priv->cflag & PARODD) ?
A
Alan Cox 已提交
2038
			USA_PARITY_ODD : USA_PARITY_EVEN;
L
Linus Torvalds 已提交
2039 2040 2041 2042 2043 2044 2045 2046 2047 2048
	}
	if (p_priv->old_cflag != p_priv->cflag) {
		p_priv->old_cflag = p_priv->cflag;
		msg.setLcr = 0x01;
	}

	if (p_priv->flow_control == flow_cts)
		msg.txFlowControl = TXFLOW_CTS;
	msg.setTxFlowControl = 0x01;
	msg.setRxFlowControl = 0x01;
A
Alan Cox 已提交
2049

L
Linus Torvalds 已提交
2050
	msg.rxForwardingLength = 16;
A
Alan Cox 已提交
2051
	msg.rxForwardingTimeout = 16;
L
Linus Torvalds 已提交
2052 2053 2054 2055
	msg.txAckSetting = 0;
	msg.xonChar = 17;
	msg.xoffChar = 19;

A
Alan Cox 已提交
2056
	/* Opening port */
L
Linus Torvalds 已提交
2057 2058 2059 2060 2061 2062
	if (reset_port == 1) {
		msg.portEnabled = 1;
		msg.rxFlush = 1;
		msg.txBreak = (p_priv->break_on);
	}
	/* Closing port */
A
Alan Cox 已提交
2063
	else if (reset_port == 2)
L
Linus Torvalds 已提交
2064 2065 2066
		msg.portEnabled = 0;
	/* Sending intermediate configs */
	else {
2067
		msg.portEnabled = 1;
L
Linus Torvalds 已提交
2068 2069 2070
		msg.txBreak = (p_priv->break_on);
	}

A
Alan Cox 已提交
2071
	/* Do handshaking outputs */
L
Linus Torvalds 已提交
2072 2073 2074 2075 2076
	msg.setRts = 0x01;
	msg.rts = p_priv->rts_state;

	msg.setDtr = 0x01;
	msg.dtr = p_priv->dtr_state;
A
Alan Cox 已提交
2077

L
Linus Torvalds 已提交
2078
	p_priv->resend_cont = 0;
A
Alan Cox 已提交
2079 2080
	memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));

L
Linus Torvalds 已提交
2081 2082 2083
	/* send the data out the device on control endpoint */
	this_urb->transfer_buffer_length = sizeof(msg);

A
Alan Cox 已提交
2084 2085
	err = usb_submit_urb(this_urb, GFP_ATOMIC);
	if (err != 0)
2086
		dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err);
2087
	return 0;
L
Linus Torvalds 已提交
2088 2089
}

2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107
static int keyspan_usa67_send_setup(struct usb_serial *serial,
				    struct usb_serial_port *port,
				    int reset_port)
{
	struct keyspan_usa67_portControlMessage	msg;
	struct keyspan_serial_private 		*s_priv;
	struct keyspan_port_private 		*p_priv;
	const struct keyspan_device_details	*d_details;
	struct urb				*this_urb;
	int 					err, device_port;

	s_priv = usb_get_serial_data(serial);
	p_priv = usb_get_serial_port_data(port);
	d_details = s_priv->device_details;

	this_urb = s_priv->glocont_urb;

	/* Work out which port within the device is being setup */
2108
	device_port = port->port_number;
2109 2110 2111

	/* Make sure we have an urb then send the message */
	if (this_urb == NULL) {
2112
		dev_dbg(&port->dev, "%s - oops no urb for port.\n", __func__);
2113 2114 2115 2116 2117 2118 2119 2120
		return -1;
	}

	/* Save reset port val for resend.
	   Don't overwrite resend for open/close condition. */
	if ((reset_port + 1) > p_priv->resend_cont)
		p_priv->resend_cont = reset_port + 1;
	if (this_urb->status == -EINPROGRESS) {
2121
		/*  dev_dbg(&port->dev, "%s - already writing\n", __func__); */
2122
		mdelay(5);
A
Alan Cox 已提交
2123
		return -1;
2124 2125 2126 2127 2128 2129 2130 2131 2132 2133
	}

	memset(&msg, 0, sizeof(struct keyspan_usa67_portControlMessage));

	msg.port = device_port;

	/* Only set baud rate if it's changed */
	if (p_priv->old_baud != p_priv->baud) {
		p_priv->old_baud = p_priv->baud;
		msg.setClocking = 0xff;
2134 2135 2136 2137 2138
		if (d_details->calculate_baud_rate(port, p_priv->baud, d_details->baudclk,
						   &msg.baudHi, &msg.baudLo, &msg.prescaler,
						   device_port) == KEYSPAN_INVALID_BAUD_RATE) {
			dev_dbg(&port->dev, "%s - Invalid baud rate %d requested, using 9600.\n",
				__func__, p_priv->baud);
2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162
			msg.baudLo = 0;
			msg.baudHi = 125;	/* Values for 9600 baud */
			msg.prescaler = 10;
		}
		msg.setPrescaler = 0xff;
	}

	msg.lcr = (p_priv->cflag & CSTOPB) ? STOPBITS_678_2 : STOPBITS_5678_1;
	switch (p_priv->cflag & CSIZE) {
	case CS5:
		msg.lcr |= USA_DATABITS_5;
		break;
	case CS6:
		msg.lcr |= USA_DATABITS_6;
		break;
	case CS7:
		msg.lcr |= USA_DATABITS_7;
		break;
	case CS8:
		msg.lcr |= USA_DATABITS_8;
		break;
	}
	if (p_priv->cflag & PARENB) {
		/* note USA_PARITY_NONE == 0 */
2163
		msg.lcr |= (p_priv->cflag & PARODD) ?
A
Alan Cox 已提交
2164
					USA_PARITY_ODD : USA_PARITY_EVEN;
2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200
	}
	msg.setLcr = 0xff;

	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
	msg.xonFlowControl = 0;
	msg.setFlowControl = 0xff;
	msg.forwardingLength = 16;
	msg.xonChar = 17;
	msg.xoffChar = 19;

	if (reset_port == 1) {
		/* Opening port */
		msg._txOn = 1;
		msg._txOff = 0;
		msg.txFlush = 0;
		msg.txBreak = 0;
		msg.rxOn = 1;
		msg.rxOff = 0;
		msg.rxFlush = 1;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0xff;
	} else if (reset_port == 2) {
		/* Closing port */
		msg._txOn = 0;
		msg._txOff = 1;
		msg.txFlush = 0;
		msg.txBreak = 0;
		msg.rxOn = 0;
		msg.rxOff = 1;
		msg.rxFlush = 1;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0;
	} else {
		/* Sending intermediate configs */
A
Alan Cox 已提交
2201
		msg._txOn = (!p_priv->break_on);
2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228
		msg._txOff = 0;
		msg.txFlush = 0;
		msg.txBreak = (p_priv->break_on);
		msg.rxOn = 0;
		msg.rxOff = 0;
		msg.rxFlush = 0;
		msg.rxForward = 0;
		msg.returnStatus = 0;
		msg.resetDataToggle = 0x0;
	}

	/* Do handshaking outputs */
	msg.setTxTriState_setRts = 0xff;
	msg.txTriState_rts = p_priv->rts_state;

	msg.setHskoa_setDtr = 0xff;
	msg.hskoa_dtr = p_priv->dtr_state;

	p_priv->resend_cont = 0;

	memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));

	/* send the data out the device on control endpoint */
	this_urb->transfer_buffer_length = sizeof(msg);

	err = usb_submit_urb(this_urb, GFP_ATOMIC);
	if (err != 0)
2229
		dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err);
2230
	return 0;
2231 2232
}

L
Linus Torvalds 已提交
2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254
static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
{
	struct usb_serial *serial = port->serial;
	struct keyspan_serial_private *s_priv;
	const struct keyspan_device_details *d_details;

	s_priv = usb_get_serial_data(serial);
	d_details = s_priv->device_details;

	switch (d_details->msg_format) {
	case msg_usa26:
		keyspan_usa26_send_setup(serial, port, reset_port);
		break;
	case msg_usa28:
		keyspan_usa28_send_setup(serial, port, reset_port);
		break;
	case msg_usa49:
		keyspan_usa49_send_setup(serial, port, reset_port);
		break;
	case msg_usa90:
		keyspan_usa90_send_setup(serial, port, reset_port);
		break;
2255 2256 2257
	case msg_usa67:
		keyspan_usa67_send_setup(serial, port, reset_port);
		break;
L
Linus Torvalds 已提交
2258 2259 2260 2261 2262 2263
	}
}


/* Gets called by the "real" driver (ie once firmware is loaded
   and renumeration has taken place. */
A
Alan Cox 已提交
2264
static int keyspan_startup(struct usb_serial *serial)
L
Linus Torvalds 已提交
2265 2266 2267 2268 2269 2270
{
	int				i, err;
	struct keyspan_serial_private 	*s_priv;
	const struct keyspan_device_details	*d_details;

	for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
A
Alan Cox 已提交
2271 2272
		if (d_details->product_id ==
				le16_to_cpu(serial->dev->descriptor.idProduct))
L
Linus Torvalds 已提交
2273 2274
			break;
	if (d_details == NULL) {
A
Alan Cox 已提交
2275 2276
		dev_err(&serial->dev->dev, "%s - unknown product id %x\n",
		    __func__, le16_to_cpu(serial->dev->descriptor.idProduct));
2277
		return -ENODEV;
L
Linus Torvalds 已提交
2278 2279 2280
	}

	/* Setup private data for serial driver */
2281
	s_priv = kzalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL);
2282
	if (!s_priv)
L
Linus Torvalds 已提交
2283 2284
		return -ENOMEM;

2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300
	s_priv->instat_buf = kzalloc(INSTAT_BUFLEN, GFP_KERNEL);
	if (!s_priv->instat_buf)
		goto err_instat_buf;

	s_priv->indat_buf = kzalloc(INDAT49W_BUFLEN, GFP_KERNEL);
	if (!s_priv->indat_buf)
		goto err_indat_buf;

	s_priv->glocont_buf = kzalloc(GLOCONT_BUFLEN, GFP_KERNEL);
	if (!s_priv->glocont_buf)
		goto err_glocont_buf;

	s_priv->ctrl_buf = kzalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
	if (!s_priv->ctrl_buf)
		goto err_ctrl_buf;

L
Linus Torvalds 已提交
2301 2302 2303 2304 2305
	s_priv->device_details = d_details;
	usb_set_serial_data(serial, s_priv);

	keyspan_setup_urbs(serial);

2306 2307 2308
	if (s_priv->instat_urb != NULL) {
		err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL);
		if (err != 0)
2309
			dev_dbg(&serial->dev->dev, "%s - submit instat urb failed %d\n", __func__, err);
2310 2311 2312 2313
	}
	if (s_priv->indat_urb != NULL) {
		err = usb_submit_urb(s_priv->indat_urb, GFP_KERNEL);
		if (err != 0)
2314
			dev_dbg(&serial->dev->dev, "%s - submit indat urb failed %d\n", __func__, err);
L
Linus Torvalds 已提交
2315
	}
A
Alan Cox 已提交
2316

2317
	return 0;
2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328

err_ctrl_buf:
	kfree(s_priv->glocont_buf);
err_glocont_buf:
	kfree(s_priv->indat_buf);
err_indat_buf:
	kfree(s_priv->instat_buf);
err_instat_buf:
	kfree(s_priv);

	return -ENOMEM;
L
Linus Torvalds 已提交
2329 2330
}

2331
static void keyspan_disconnect(struct usb_serial *serial)
L
Linus Torvalds 已提交
2332
{
2333
	struct keyspan_serial_private *s_priv;
L
Linus Torvalds 已提交
2334 2335 2336 2337 2338

	s_priv = usb_get_serial_data(serial);

	stop_urb(s_priv->instat_urb);
	stop_urb(s_priv->glocont_urb);
2339
	stop_urb(s_priv->indat_urb);
2340 2341 2342 2343 2344 2345 2346
}

static void keyspan_release(struct usb_serial *serial)
{
	struct keyspan_serial_private *s_priv;

	s_priv = usb_get_serial_data(serial);
L
Linus Torvalds 已提交
2347

M
Mariusz Kozlowski 已提交
2348
	usb_free_urb(s_priv->instat_urb);
2349
	usb_free_urb(s_priv->indat_urb);
M
Mariusz Kozlowski 已提交
2350
	usb_free_urb(s_priv->glocont_urb);
2351

2352 2353 2354 2355 2356
	kfree(s_priv->ctrl_buf);
	kfree(s_priv->glocont_buf);
	kfree(s_priv->indat_buf);
	kfree(s_priv->instat_buf);

2357
	kfree(s_priv);
2358 2359
}

2360
static int keyspan_port_probe(struct usb_serial_port *port)
2361
{
2362
	struct usb_serial *serial = port->serial;
2363
	struct keyspan_serial_private *s_priv;
2364 2365 2366 2367 2368 2369
	struct keyspan_port_private *p_priv;
	const struct keyspan_device_details *d_details;
	struct callbacks *cback;
	int endp;
	int port_num;
	int i;
2370 2371

	s_priv = usb_get_serial_data(serial);
2372
	d_details = s_priv->device_details;
L
Linus Torvalds 已提交
2373

2374 2375 2376
	p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL);
	if (!p_priv)
		return -ENOMEM;
L
Linus Torvalds 已提交
2377

2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397
	for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i) {
		p_priv->in_buffer[i] = kzalloc(IN_BUFLEN, GFP_KERNEL);
		if (!p_priv->in_buffer[i])
			goto err_in_buffer;
	}

	for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i) {
		p_priv->out_buffer[i] = kzalloc(OUT_BUFLEN, GFP_KERNEL);
		if (!p_priv->out_buffer[i])
			goto err_out_buffer;
	}

	p_priv->inack_buffer = kzalloc(INACK_BUFLEN, GFP_KERNEL);
	if (!p_priv->inack_buffer)
		goto err_inack_buffer;

	p_priv->outcont_buffer = kzalloc(OUTCONT_BUFLEN, GFP_KERNEL);
	if (!p_priv->outcont_buffer)
		goto err_outcont_buffer;

2398 2399 2400 2401 2402
	p_priv->device_details = d_details;

	/* Setup values for the various callback routines */
	cback = &keyspan_callbacks[d_details->msg_format];

2403
	port_num = port->port_number;
2404 2405 2406 2407 2408 2409

	/* Do indat endpoints first, once for each flip */
	endp = d_details->indat_endpoints[port_num];
	for (i = 0; i <= d_details->indat_endp_flip; ++i, ++endp) {
		p_priv->in_urbs[i] = keyspan_setup_urb(serial, endp,
						USB_DIR_IN, port,
2410 2411
						p_priv->in_buffer[i],
						IN_BUFLEN,
2412 2413 2414 2415 2416 2417 2418
						cback->indat_callback);
	}
	/* outdat endpoints also have flip */
	endp = d_details->outdat_endpoints[port_num];
	for (i = 0; i <= d_details->outdat_endp_flip; ++i, ++endp) {
		p_priv->out_urbs[i] = keyspan_setup_urb(serial, endp,
						USB_DIR_OUT, port,
2419 2420
						p_priv->out_buffer[i],
						OUT_BUFLEN,
2421 2422 2423 2424 2425 2426
						cback->outdat_callback);
	}
	/* inack endpoint */
	p_priv->inack_urb = keyspan_setup_urb(serial,
					d_details->inack_endpoints[port_num],
					USB_DIR_IN, port,
2427 2428
					p_priv->inack_buffer,
					INACK_BUFLEN,
2429 2430 2431 2432 2433
					cback->inack_callback);
	/* outcont endpoint */
	p_priv->outcont_urb = keyspan_setup_urb(serial,
					d_details->outcont_endpoints[port_num],
					USB_DIR_OUT, port,
2434 2435
					p_priv->outcont_buffer,
					OUTCONT_BUFLEN,
2436 2437 2438 2439 2440
					 cback->outcont_callback);

	usb_set_serial_port_data(port, p_priv);

	return 0;
2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453

err_outcont_buffer:
	kfree(p_priv->inack_buffer);
err_inack_buffer:
	for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i)
		kfree(p_priv->out_buffer[i]);
err_out_buffer:
	for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i)
		kfree(p_priv->in_buffer[i]);
err_in_buffer:
	kfree(p_priv);

	return -ENOMEM;
2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474
}

static int keyspan_port_remove(struct usb_serial_port *port)
{
	struct keyspan_port_private *p_priv;
	int i;

	p_priv = usb_get_serial_port_data(port);

	stop_urb(p_priv->inack_urb);
	stop_urb(p_priv->outcont_urb);
	for (i = 0; i < 2; i++) {
		stop_urb(p_priv->in_urbs[i]);
		stop_urb(p_priv->out_urbs[i]);
	}

	usb_free_urb(p_priv->inack_urb);
	usb_free_urb(p_priv->outcont_urb);
	for (i = 0; i < 2; i++) {
		usb_free_urb(p_priv->in_urbs[i]);
		usb_free_urb(p_priv->out_urbs[i]);
L
Linus Torvalds 已提交
2475
	}
2476

2477 2478 2479 2480 2481 2482 2483
	kfree(p_priv->outcont_buffer);
	kfree(p_priv->inack_buffer);
	for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i)
		kfree(p_priv->out_buffer[i]);
	for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i)
		kfree(p_priv->in_buffer[i]);

2484 2485 2486
	kfree(p_priv);

	return 0;
L
Linus Torvalds 已提交
2487 2488
}

A
Alan Cox 已提交
2489 2490
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
L
Linus Torvalds 已提交
2491 2492
MODULE_LICENSE("GPL");

2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504
MODULE_FIRMWARE("keyspan/usa28.fw");
MODULE_FIRMWARE("keyspan/usa28x.fw");
MODULE_FIRMWARE("keyspan/usa28xa.fw");
MODULE_FIRMWARE("keyspan/usa28xb.fw");
MODULE_FIRMWARE("keyspan/usa19.fw");
MODULE_FIRMWARE("keyspan/usa19qi.fw");
MODULE_FIRMWARE("keyspan/mpr.fw");
MODULE_FIRMWARE("keyspan/usa19qw.fw");
MODULE_FIRMWARE("keyspan/usa18x.fw");
MODULE_FIRMWARE("keyspan/usa19w.fw");
MODULE_FIRMWARE("keyspan/usa49w.fw");
MODULE_FIRMWARE("keyspan/usa49wlc.fw");