io_ti.c 75.7 KB
Newer Older
L
Linus Torvalds 已提交
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 28
/*
 * Edgeport USB Serial Converter driver
 *
 * Copyright (C) 2000-2002 Inside Out Networks, All rights reserved.
 * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
 *
 *	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.
 *
 * Supports the following devices:
 *	EP/1 EP/2 EP/4 EP/21 EP/22 EP/221 EP/42 EP/421 WATCHPORT
 *
 * For questions or problems with this driver, contact Inside Out
 * Networks technical support, or Peter Berger <pberger@brimson.com>,
 * or Al Borchers <alborchers@steinerpoint.com>.
 */

#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>
29
#include <linux/mutex.h>
L
Linus Torvalds 已提交
30
#include <linux/serial.h>
31
#include <linux/swab.h>
32
#include <linux/kfifo.h>
L
Linus Torvalds 已提交
33
#include <linux/ioctl.h>
34
#include <linux/firmware.h>
35
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
36
#include <linux/usb.h>
37
#include <linux/usb/serial.h>
L
Linus Torvalds 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

#include "io_16654.h"
#include "io_usbvend.h"
#include "io_ti.h"

#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli"
#define DRIVER_DESC "Edgeport USB Serial Driver"

#define EPROM_PAGE_SIZE		64


/* different hardware types */
#define HARDWARE_TYPE_930	0
#define HARDWARE_TYPE_TIUMP	1

53 54 55 56 57 58
/* IOCTL_PRIVATE_TI_GET_MODE Definitions */
#define	TI_MODE_CONFIGURING	0   /* Device has not entered start device */
#define	TI_MODE_BOOT		1   /* Staying in boot mode		   */
#define TI_MODE_DOWNLOAD	2   /* Made it to download mode		   */
#define TI_MODE_TRANSITIONING	3   /* Currently in boot mode but
				       transitioning to download mode	   */
L
Linus Torvalds 已提交
59 60 61 62 63 64 65 66 67 68

/* read urb state */
#define EDGE_READ_URB_RUNNING	0
#define EDGE_READ_URB_STOPPING	1
#define EDGE_READ_URB_STOPPED	2

#define EDGE_CLOSING_WAIT	4000	/* in .01 sec */


/* Product information read from the Edgeport */
69 70 71
struct product_info {
	int	TiMode;			/* Current TI Mode  */
	__u8	hardware_type;		/* Type of hardware */
L
Linus Torvalds 已提交
72 73
} __attribute__((packed));

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
/*
 * Edgeport firmware header
 *
 * "build_number" has been set to 0 in all three of the images I have
 * seen, and Digi Tech Support suggests that it is safe to ignore it.
 *
 * "length" is the number of bytes of actual data following the header.
 *
 * "checksum" is the low order byte resulting from adding the values of
 * all the data bytes.
 */
struct edgeport_fw_hdr {
	u8 major_version;
	u8 minor_version;
	__le16 build_number;
	__le16 length;
	u8 checksum;
} __packed;

L
Linus Torvalds 已提交
93 94 95 96 97 98 99
struct edgeport_port {
	__u16 uart_base;
	__u16 dma_address;
	__u8 shadow_msr;
	__u8 shadow_mcr;
	__u8 shadow_lsr;
	__u8 lsr_mask;
100
	__u32 ump_read_timeout;		/* Number of milliseconds the UMP will
L
Linus Torvalds 已提交
101 102 103 104 105
					   wait without data before completing
					   a read short */
	int baud_rate;
	int close_pending;
	int lsr_event;
106

L
Linus Torvalds 已提交
107 108
	struct edgeport_serial	*edge_serial;
	struct usb_serial_port	*port;
109
	__u8 bUartMode;		/* Port type, 0: RS232, etc. */
L
Linus Torvalds 已提交
110 111 112 113 114 115 116
	spinlock_t ep_lock;
	int ep_read_urb_state;
	int ep_write_urb_in_use;
};

struct edgeport_serial {
	struct product_info product_info;
117 118 119
	u8 TI_I2C_Type;			/* Type of I2C in UMP */
	u8 TiReadI2C;			/* Set to TRUE if we have read the
					   I2c in Boot Mode */
120
	struct mutex es_lock;
L
Linus Torvalds 已提交
121 122
	int num_ports_open;
	struct usb_serial *serial;
123
	struct delayed_work heartbeat_work;
124
	int fw_version;
125
	bool use_heartbeat;
L
Linus Torvalds 已提交
126 127 128 129
};


/* Devices that this driver supports */
130
static const struct usb_device_id edgeport_1port_id_table[] = {
L
Linus Torvalds 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_PROXIMITY) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_MOTION) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_MOISTURE) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_TEMPERATURE) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_HUMIDITY) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_POWER) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_LIGHT) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_RADIATION) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_DISTANCE) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_ACCELERATION) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_PROX_DIST) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_PLUS_PWR_HP4CD) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_PLUS_PWR_PCI) },
	{ }
};

150
static const struct usb_device_id edgeport_2port_id_table[] = {
L
Linus Torvalds 已提交
151 152 153 154 155 156 157 158 159 160 161 162
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2C) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_42) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4I) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22I) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_221C) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22C) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21C) },
163
	/* The 4, 8 and 16 port devices show up as multiple 2 port devices */
L
Linus Torvalds 已提交
164
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) },
165 166 167 168
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) },
L
Linus Torvalds 已提交
169 170 171 172
	{ }
};

/* Devices that this driver supports */
173
static const struct usb_device_id id_table_combined[] = {
L
Linus Torvalds 已提交
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_PROXIMITY) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_MOTION) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_MOISTURE) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_TEMPERATURE) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_HUMIDITY) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_POWER) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_LIGHT) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_RADIATION) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_DISTANCE) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_ACCELERATION) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_PROX_DIST) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_PLUS_PWR_HP4CD) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_PLUS_PWR_PCI) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2C) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_42) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4I) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22I) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_221C) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22C) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21C) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) },
203 204 205 206
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) },
L
Linus Torvalds 已提交
207 208 209
	{ }
};

210
MODULE_DEVICE_TABLE(usb, id_table_combined);
L
Linus Torvalds 已提交
211 212

static int closing_wait = EDGE_CLOSING_WAIT;
213
static bool ignore_cpu_rev;
214
static int default_uart_mode;		/* RS232 */
L
Linus Torvalds 已提交
215

J
Jiri Slaby 已提交
216 217
static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data,
		int length);
L
Linus Torvalds 已提交
218 219 220 221

static void stop_read(struct edgeport_port *edge_port);
static int restart_read(struct edgeport_port *edge_port);

A
Alan Cox 已提交
222 223
static void edge_set_termios(struct tty_struct *tty,
		struct usb_serial_port *port, struct ktermios *old_termios);
224
static void edge_send(struct usb_serial_port *port, struct tty_struct *tty);
L
Linus Torvalds 已提交
225

226 227 228 229
/* sysfs attributes */
static int edge_create_sysfs_attrs(struct usb_serial_port *port);
static int edge_remove_sysfs_attrs(struct usb_serial_port *port);

230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
/*
 * Some release of Edgeport firmware "down3.bin" after version 4.80
 * introduced code to automatically disconnect idle devices on some
 * Edgeport models after periods of inactivity, typically ~60 seconds.
 * This occurs without regard to whether ports on the device are open
 * or not.  Digi International Tech Support suggested:
 *
 * 1.  Adding driver "heartbeat" code to reset the firmware timer by
 *     requesting a descriptor record every 15 seconds, which should be
 *     effective with newer firmware versions that require it, and benign
 *     with older versions that do not. In practice 40 seconds seems often
 *     enough.
 * 2.  The heartbeat code is currently required only on Edgeport/416 models.
 */
#define FW_HEARTBEAT_VERSION_CUTOFF ((4 << 8) + 80)
#define FW_HEARTBEAT_SECS 40
L
Linus Torvalds 已提交
246

247 248 249 250
/* Timeouts in msecs: firmware downloads take longer */
#define TI_VSEND_TIMEOUT_DEFAULT 1000
#define TI_VSEND_TIMEOUT_FW_DOWNLOAD 10000

251 252
static int ti_vread_sync(struct usb_device *dev, __u8 request,
				__u16 value, __u16 index, u8 *data, int size)
L
Linus Torvalds 已提交
253 254 255
{
	int status;

256 257 258
	status = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,
			(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN),
			value, index, data, size, 1000);
L
Linus Torvalds 已提交
259 260 261
	if (status < 0)
		return status;
	if (status != size) {
262 263
		dev_dbg(&dev->dev, "%s - wanted to write %d, but only wrote %d\n",
			__func__, size, status);
L
Linus Torvalds 已提交
264 265 266 267 268
		return -ECOMM;
	}
	return 0;
}

269 270
static int ti_vsend_sync(struct usb_device *dev, u8 request, u16 value,
		u16 index, u8 *data, int size, int timeout)
L
Linus Torvalds 已提交
271 272 273
{
	int status;

274 275
	status = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request,
			(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT),
276
			value, index, data, size, timeout);
L
Linus Torvalds 已提交
277 278 279
	if (status < 0)
		return status;
	if (status != size) {
280 281
		dev_dbg(&dev->dev, "%s - wanted to write %d, but only wrote %d\n",
			__func__, size, status);
L
Linus Torvalds 已提交
282 283 284 285 286
		return -ECOMM;
	}
	return 0;
}

287
static int send_cmd(struct usb_device *dev, __u8 command,
L
Linus Torvalds 已提交
288 289 290
				__u8 moduleid, __u16 value, u8 *data,
				int size)
{
291 292
	return ti_vsend_sync(dev, command, value, moduleid, data, size,
			TI_VSEND_TIMEOUT_DEFAULT);
L
Linus Torvalds 已提交
293 294 295
}

/* clear tx/rx buffers and fifo in TI UMP */
296
static int purge_port(struct usb_serial_port *port, __u16 mask)
L
Linus Torvalds 已提交
297
{
298
	int port_number = port->port_number;
L
Linus Torvalds 已提交
299

300
	dev_dbg(&port->dev, "%s - port %d, mask %x\n", __func__, port_number, mask);
L
Linus Torvalds 已提交
301

302
	return send_cmd(port->serial->dev,
L
Linus Torvalds 已提交
303 304 305 306 307 308 309 310
					UMPC_PURGE_PORT,
					(__u8)(UMPM_UART1_PORT + port_number),
					mask,
					NULL,
					0);
}

/**
311
 * read_download_mem - Read edgeport memory from TI chip
L
Linus Torvalds 已提交
312 313 314 315 316 317
 * @dev: usb device pointer
 * @start_address: Device CPU address at which to read
 * @length: Length of above data
 * @address_type: Can read both XDATA and I2C
 * @buffer: pointer to input data buffer
 */
318
static int read_download_mem(struct usb_device *dev, int start_address,
L
Linus Torvalds 已提交
319 320 321 322
				int length, __u8 address_type, __u8 *buffer)
{
	int status = 0;
	__u8 read_length;
323
	u16 be_start_address;
324

325
	dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, length);
L
Linus Torvalds 已提交
326 327 328 329 330 331

	/* Read in blocks of 64 bytes
	 * (TI firmware can't handle more than 64 byte reads)
	 */
	while (length) {
		if (length > 64)
332
			read_length = 64;
L
Linus Torvalds 已提交
333 334 335 336
		else
			read_length = (__u8)length;

		if (read_length > 1) {
337
			dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, read_length);
L
Linus Torvalds 已提交
338
		}
339 340 341 342 343
		/*
		 * NOTE: Must use swab as wIndex is sent in little-endian
		 *       byte order regardless of host byte order.
		 */
		be_start_address = swab16((u16)start_address);
344 345
		status = ti_vread_sync(dev, UMPC_MEMORY_READ,
					(__u16)address_type,
346
					be_start_address,
347
					buffer, read_length);
L
Linus Torvalds 已提交
348 349

		if (status) {
350
			dev_dbg(&dev->dev, "%s - ERROR %x\n", __func__, status);
L
Linus Torvalds 已提交
351 352 353
			return status;
		}

354
		if (read_length > 1)
355
			usb_serial_debug_data(&dev->dev, __func__, read_length, buffer);
L
Linus Torvalds 已提交
356 357 358 359 360 361

		/* Update pointers/length */
		start_address += read_length;
		buffer += read_length;
		length -= read_length;
	}
362

L
Linus Torvalds 已提交
363 364 365
	return status;
}

366 367
static int read_ram(struct usb_device *dev, int start_address,
						int length, __u8 *buffer)
L
Linus Torvalds 已提交
368
{
369 370
	return read_download_mem(dev, start_address, length,
					DTK_ADDR_SPACE_XDATA, buffer);
L
Linus Torvalds 已提交
371 372 373
}

/* Read edgeport memory to a given block */
374 375
static int read_boot_mem(struct edgeport_serial *serial,
				int start_address, int length, __u8 *buffer)
L
Linus Torvalds 已提交
376 377 378 379
{
	int status = 0;
	int i;

380 381 382 383
	for (i = 0; i < length; i++) {
		status = ti_vread_sync(serial->serial->dev,
				UMPC_MEMORY_READ, serial->TI_I2C_Type,
				(__u16)(start_address+i), &buffer[i], 0x01);
L
Linus Torvalds 已提交
384
		if (status) {
385
			dev_dbg(&serial->serial->dev->dev, "%s - ERROR %x\n", __func__, status);
L
Linus Torvalds 已提交
386 387 388 389
			return status;
		}
	}

390 391
	dev_dbg(&serial->serial->dev->dev, "%s - start_address = %x, length = %d\n",
		__func__, start_address, length);
392
	usb_serial_debug_data(&serial->serial->dev->dev, __func__, length, buffer);
L
Linus Torvalds 已提交
393 394 395 396 397 398 399

	serial->TiReadI2C = 1;

	return status;
}

/* Write given block to TI EPROM memory */
400 401
static int write_boot_mem(struct edgeport_serial *serial,
				int start_address, int length, __u8 *buffer)
L
Linus Torvalds 已提交
402 403 404
{
	int status = 0;
	int i;
405
	u8 *temp;
L
Linus Torvalds 已提交
406 407 408

	/* Must do a read before write */
	if (!serial->TiReadI2C) {
409
		temp = kmalloc(1, GFP_KERNEL);
410
		if (!temp)
411
			return -ENOMEM;
412

413 414
		status = read_boot_mem(serial, 0, 1, temp);
		kfree(temp);
L
Linus Torvalds 已提交
415 416 417 418
		if (status)
			return status;
	}

419
	for (i = 0; i < length; ++i) {
420 421 422
		status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE,
				buffer[i], (u16)(i + start_address), NULL,
				0, TI_VSEND_TIMEOUT_DEFAULT);
L
Linus Torvalds 已提交
423 424 425 426
		if (status)
			return status;
	}

427
	dev_dbg(&serial->serial->dev->dev, "%s - start_sddr = %x, length = %d\n", __func__, start_address, length);
428
	usb_serial_debug_data(&serial->serial->dev->dev, __func__, length, buffer);
L
Linus Torvalds 已提交
429 430 431 432 433 434

	return status;
}


/* Write edgeport I2C memory to TI chip	*/
435 436
static int write_i2c_mem(struct edgeport_serial *serial,
		int start_address, int length, __u8 address_type, __u8 *buffer)
L
Linus Torvalds 已提交
437
{
438
	struct device *dev = &serial->serial->dev->dev;
L
Linus Torvalds 已提交
439 440
	int status = 0;
	int write_length;
441
	u16 be_start_address;
L
Linus Torvalds 已提交
442 443

	/* We can only send a maximum of 1 aligned byte page at a time */
444

L
Lucas De Marchi 已提交
445
	/* calculate the number of bytes left in the first page */
446 447
	write_length = EPROM_PAGE_SIZE -
				(start_address & (EPROM_PAGE_SIZE - 1));
L
Linus Torvalds 已提交
448 449 450 451

	if (write_length > length)
		write_length = length;

452 453
	dev_dbg(dev, "%s - BytesInFirstPage Addr = %x, length = %d\n",
		__func__, start_address, write_length);
454
	usb_serial_debug_data(dev, __func__, write_length, buffer);
L
Linus Torvalds 已提交
455

456 457 458 459 460 461 462
	/*
	 * Write first page.
	 *
	 * NOTE: Must use swab as wIndex is sent in little-endian byte order
	 *       regardless of host byte order.
	 */
	be_start_address = swab16((u16)start_address);
463 464 465
	status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE,
				(u16)address_type, be_start_address,
				buffer,	write_length, TI_VSEND_TIMEOUT_DEFAULT);
L
Linus Torvalds 已提交
466
	if (status) {
467
		dev_dbg(dev, "%s - ERROR %d\n", __func__, status);
L
Linus Torvalds 已提交
468 469 470 471 472 473 474
		return status;
	}

	length		-= write_length;
	start_address	+= write_length;
	buffer		+= write_length;

475 476
	/* We should be aligned now -- can write
	   max page size bytes at a time */
L
Linus Torvalds 已提交
477 478 479 480 481 482
	while (length) {
		if (length > EPROM_PAGE_SIZE)
			write_length = EPROM_PAGE_SIZE;
		else
			write_length = length;

483 484
		dev_dbg(dev, "%s - Page Write Addr = %x, length = %d\n",
			__func__, start_address, write_length);
485
		usb_serial_debug_data(dev, __func__, write_length, buffer);
L
Linus Torvalds 已提交
486

487 488 489 490 491 492 493
		/*
		 * Write next page.
		 *
		 * NOTE: Must use swab as wIndex is sent in little-endian byte
		 *       order regardless of host byte order.
		 */
		be_start_address = swab16((u16)start_address);
494
		status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE,
495 496
				(u16)address_type, be_start_address, buffer,
				write_length, TI_VSEND_TIMEOUT_DEFAULT);
L
Linus Torvalds 已提交
497
		if (status) {
498
			dev_err(dev, "%s - ERROR %d\n", __func__, status);
L
Linus Torvalds 已提交
499 500
			return status;
		}
501

L
Linus Torvalds 已提交
502 503 504 505 506 507 508 509
		length		-= write_length;
		start_address	+= write_length;
		buffer		+= write_length;
	}
	return status;
}

/* Examine the UMP DMA registers and LSR
510
 *
L
Linus Torvalds 已提交
511 512 513 514
 * Check the MSBit of the X and Y DMA byte count registers.
 * A zero in this bit indicates that the TX DMA buffers are empty
 * then check the TX Empty bit in the UART.
 */
515
static int tx_active(struct edgeport_port *port)
L
Linus Torvalds 已提交
516 517 518 519 520 521
{
	int status;
	struct out_endpoint_desc_block *oedb;
	__u8 *lsr;
	int bytes_left = 0;

522
	oedb = kmalloc(sizeof(*oedb), GFP_KERNEL);
523
	if (!oedb)
L
Linus Torvalds 已提交
524 525
		return -ENOMEM;

526
	lsr = kmalloc(1, GFP_KERNEL);	/* Sigh, that's right, just one byte,
L
Linus Torvalds 已提交
527 528 529 530 531 532 533
					   as not all platforms can do DMA
					   from stack */
	if (!lsr) {
		kfree(oedb);
		return -ENOMEM;
	}
	/* Read the DMA Count Registers */
534 535
	status = read_ram(port->port->serial->dev, port->dma_address,
						sizeof(*oedb), (void *)oedb);
L
Linus Torvalds 已提交
536 537 538
	if (status)
		goto exit_is_tx_active;

539
	dev_dbg(&port->port->dev, "%s - XByteCount    0x%X\n", __func__, oedb->XByteCount);
L
Linus Torvalds 已提交
540 541

	/* and the LSR */
542 543
	status = read_ram(port->port->serial->dev,
			port->uart_base + UMPMEM_OFFS_UART_LSR, 1, lsr);
L
Linus Torvalds 已提交
544 545 546

	if (status)
		goto exit_is_tx_active;
547
	dev_dbg(&port->port->dev, "%s - LSR = 0x%X\n", __func__, *lsr);
548

L
Linus Torvalds 已提交
549
	/* If either buffer has data or we are transmitting then return TRUE */
550
	if ((oedb->XByteCount & 0x80) != 0)
L
Linus Torvalds 已提交
551 552
		bytes_left += 64;

553
	if ((*lsr & UMP_UART_LSR_TX_MASK) == 0)
L
Linus Torvalds 已提交
554 555 556 557
		bytes_left += 1;

	/* We return Not Active if we get any kind of error */
exit_is_tx_active:
558
	dev_dbg(&port->port->dev, "%s - return %d\n", __func__, bytes_left);
L
Linus Torvalds 已提交
559 560 561 562 563 564

	kfree(lsr);
	kfree(oedb);
	return bytes_left;
}

565
static int choose_config(struct usb_device *dev)
L
Linus Torvalds 已提交
566
{
567 568 569 570 571 572
	/*
	 * There may be multiple configurations on this device, in which case
	 * we would need to read and parse all of them to find out which one
	 * we want. However, we just support one config at this point,
	 * configuration # 1, which is Config Descriptor 0.
	 */
L
Linus Torvalds 已提交
573

574 575 576 577
	dev_dbg(&dev->dev, "%s - Number of Interfaces = %d\n",
		__func__, dev->config->desc.bNumInterfaces);
	dev_dbg(&dev->dev, "%s - MAX Power            = %d\n",
		__func__, dev->config->desc.bMaxPower * 2);
L
Linus Torvalds 已提交
578 579

	if (dev->config->desc.bNumInterfaces != 1) {
580
		dev_err(&dev->dev, "%s - bNumInterfaces is not 1, ERROR!\n", __func__);
L
Linus Torvalds 已提交
581 582 583 584 585 586
		return -ENODEV;
	}

	return 0;
}

587 588
static int read_rom(struct edgeport_serial *serial,
				int start_address, int length, __u8 *buffer)
L
Linus Torvalds 已提交
589 590 591 592
{
	int status;

	if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) {
593
		status = read_download_mem(serial->serial->dev,
L
Linus Torvalds 已提交
594 595 596 597 598
					       start_address,
					       length,
					       serial->TI_I2C_Type,
					       buffer);
	} else {
599 600
		status = read_boot_mem(serial, start_address, length,
								buffer);
L
Linus Torvalds 已提交
601 602 603 604
	}
	return status;
}

605 606
static int write_rom(struct edgeport_serial *serial, int start_address,
						int length, __u8 *buffer)
L
Linus Torvalds 已提交
607 608
{
	if (serial->product_info.TiMode == TI_MODE_BOOT)
609 610
		return write_boot_mem(serial, start_address, length,
								buffer);
L
Linus Torvalds 已提交
611 612

	if (serial->product_info.TiMode == TI_MODE_DOWNLOAD)
613 614
		return write_i2c_mem(serial, start_address, length,
						serial->TI_I2C_Type, buffer);
L
Linus Torvalds 已提交
615 616 617 618 619 620
	return -EINVAL;
}



/* Read a descriptor header from I2C based on type */
621 622
static int get_descriptor_addr(struct edgeport_serial *serial,
				int desc_type, struct ti_i2c_desc *rom_desc)
L
Linus Torvalds 已提交
623 624 625 626 627 628 629
{
	int start_address;
	int status;

	/* Search for requested descriptor in I2C */
	start_address = 2;
	do {
630
		status = read_rom(serial,
L
Linus Torvalds 已提交
631 632
				   start_address,
				   sizeof(struct ti_i2c_desc),
633
				   (__u8 *)rom_desc);
L
Linus Torvalds 已提交
634 635 636 637 638 639
		if (status)
			return 0;

		if (rom_desc->Type == desc_type)
			return start_address;

640 641
		start_address = start_address + sizeof(struct ti_i2c_desc) +
						le16_to_cpu(rom_desc->Size);
L
Linus Torvalds 已提交
642 643

	} while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type);
644

L
Linus Torvalds 已提交
645 646 647 648
	return 0;
}

/* Validate descriptor checksum */
649
static int valid_csum(struct ti_i2c_desc *rom_desc, __u8 *buffer)
L
Linus Torvalds 已提交
650 651 652 653
{
	__u16 i;
	__u8 cs = 0;

654
	for (i = 0; i < le16_to_cpu(rom_desc->Size); i++)
L
Linus Torvalds 已提交
655
		cs = (__u8)(cs + buffer[i]);
656

L
Linus Torvalds 已提交
657
	if (cs != rom_desc->CheckSum) {
658
		pr_debug("%s - Mismatch %x - %x", __func__, rom_desc->CheckSum, cs);
L
Linus Torvalds 已提交
659 660 661 662 663 664
		return -EINVAL;
	}
	return 0;
}

/* Make sure that the I2C image is good */
665
static int check_i2c_image(struct edgeport_serial *serial)
L
Linus Torvalds 已提交
666 667 668 669 670 671 672 673
{
	struct device *dev = &serial->serial->dev->dev;
	int status = 0;
	struct ti_i2c_desc *rom_desc;
	int start_address = 2;
	__u8 *buffer;
	__u16 ttype;

674
	rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);
675
	if (!rom_desc)
L
Linus Torvalds 已提交
676
		return -ENOMEM;
677

678
	buffer = kmalloc(TI_MAX_I2C_SIZE, GFP_KERNEL);
L
Linus Torvalds 已提交
679
	if (!buffer) {
680
		kfree(rom_desc);
L
Linus Torvalds 已提交
681 682 683
		return -ENOMEM;
	}

684 685
	/* Read the first byte (Signature0) must be 0x52 or 0x10 */
	status = read_rom(serial, 0, 1, buffer);
L
Linus Torvalds 已提交
686
	if (status)
687
		goto out;
L
Linus Torvalds 已提交
688 689

	if (*buffer != UMP5152 && *buffer != UMP3410) {
690
		dev_err(dev, "%s - invalid buffer signature\n", __func__);
L
Linus Torvalds 已提交
691
		status = -ENODEV;
692
		goto out;
L
Linus Torvalds 已提交
693 694 695
	}

	do {
696 697
		/* Validate the I2C */
		status = read_rom(serial,
L
Linus Torvalds 已提交
698 699 700 701 702 703
				start_address,
				sizeof(struct ti_i2c_desc),
				(__u8 *)rom_desc);
		if (status)
			break;

704
		if ((start_address + sizeof(struct ti_i2c_desc) +
705
			le16_to_cpu(rom_desc->Size)) > TI_MAX_I2C_SIZE) {
L
Linus Torvalds 已提交
706
			status = -ENODEV;
707
			dev_dbg(dev, "%s - structure too big, erroring out.\n", __func__);
L
Linus Torvalds 已提交
708 709 710
			break;
		}

711
		dev_dbg(dev, "%s Type = 0x%x\n", __func__, rom_desc->Type);
L
Linus Torvalds 已提交
712

713
		/* Skip type 2 record */
L
Linus Torvalds 已提交
714
		ttype = rom_desc->Type & 0x0f;
715 716 717 718 719
		if (ttype != I2C_DESC_TYPE_FIRMWARE_BASIC
			&& ttype != I2C_DESC_TYPE_FIRMWARE_AUTO) {
			/* Read the descriptor data */
			status = read_rom(serial, start_address +
						sizeof(struct ti_i2c_desc),
720 721
						le16_to_cpu(rom_desc->Size),
						buffer);
L
Linus Torvalds 已提交
722 723 724
			if (status)
				break;

725
			status = valid_csum(rom_desc, buffer);
L
Linus Torvalds 已提交
726 727 728
			if (status)
				break;
		}
729
		start_address = start_address + sizeof(struct ti_i2c_desc) +
730
						le16_to_cpu(rom_desc->Size);
L
Linus Torvalds 已提交
731

732 733
	} while ((rom_desc->Type != I2C_DESC_TYPE_ION) &&
				(start_address < TI_MAX_I2C_SIZE));
L
Linus Torvalds 已提交
734

735 736
	if ((rom_desc->Type != I2C_DESC_TYPE_ION) ||
				(start_address > TI_MAX_I2C_SIZE))
L
Linus Torvalds 已提交
737 738
		status = -ENODEV;

739 740 741
out:
	kfree(buffer);
	kfree(rom_desc);
L
Linus Torvalds 已提交
742 743 744
	return status;
}

745
static int get_manuf_info(struct edgeport_serial *serial, __u8 *buffer)
L
Linus Torvalds 已提交
746 747 748 749 750
{
	int status;
	int start_address;
	struct ti_i2c_desc *rom_desc;
	struct edge_ti_manuf_descriptor *desc;
751
	struct device *dev = &serial->serial->dev->dev;
L
Linus Torvalds 已提交
752

753
	rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);
754
	if (!rom_desc)
L
Linus Torvalds 已提交
755
		return -ENOMEM;
756

757 758
	start_address = get_descriptor_addr(serial, I2C_DESC_TYPE_ION,
								rom_desc);
L
Linus Torvalds 已提交
759 760

	if (!start_address) {
761
		dev_dbg(dev, "%s - Edge Descriptor not found in I2C\n", __func__);
L
Linus Torvalds 已提交
762 763 764 765
		status = -ENODEV;
		goto exit;
	}

766 767
	/* Read the descriptor data */
	status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc),
768
					le16_to_cpu(rom_desc->Size), buffer);
L
Linus Torvalds 已提交
769 770
	if (status)
		goto exit;
771 772 773

	status = valid_csum(rom_desc, buffer);

L
Linus Torvalds 已提交
774
	desc = (struct edge_ti_manuf_descriptor *)buffer;
775 776 777 778 779 780
	dev_dbg(dev, "%s - IonConfig      0x%x\n", __func__, desc->IonConfig);
	dev_dbg(dev, "%s - Version          %d\n", __func__, desc->Version);
	dev_dbg(dev, "%s - Cpu/Board      0x%x\n", __func__, desc->CpuRev_BoardRev);
	dev_dbg(dev, "%s - NumPorts         %d\n", __func__, desc->NumPorts);
	dev_dbg(dev, "%s - NumVirtualPorts  %d\n", __func__, desc->NumVirtualPorts);
	dev_dbg(dev, "%s - TotalPorts       %d\n", __func__, desc->TotalPorts);
L
Linus Torvalds 已提交
781 782

exit:
783
	kfree(rom_desc);
L
Linus Torvalds 已提交
784 785 786 787
	return status;
}

/* Build firmware header used for firmware update */
788 789
static int build_i2c_fw_hdr(u8 *header, struct device *dev,
		const struct firmware *fw)
L
Linus Torvalds 已提交
790 791 792 793 794 795 796 797
{
	__u8 *buffer;
	int buffer_size;
	int i;
	__u8 cs = 0;
	struct ti_i2c_desc *i2c_header;
	struct ti_i2c_image_header *img_header;
	struct ti_i2c_firmware_rec *firmware_rec;
798
	struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;
L
Linus Torvalds 已提交
799

800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
	/* In order to update the I2C firmware we must change the type 2 record
	 * to type 0xF2.  This will force the UMP to come up in Boot Mode.
	 * Then while in boot mode, the driver will download the latest
	 * firmware (padded to 15.5k) into the UMP ram.  And finally when the
	 * device comes back up in download mode the driver will cause the new
	 * firmware to be copied from the UMP Ram to I2C and the firmware will
	 * update the record type from 0xf2 to 0x02.
	 */

	/* Allocate a 15.5k buffer + 2 bytes for version number
	 * (Firmware Record) */
	buffer_size = (((1024 * 16) - 512 ) +
			sizeof(struct ti_i2c_firmware_rec));

	buffer = kmalloc(buffer_size, GFP_KERNEL);
815
	if (!buffer)
L
Linus Torvalds 已提交
816
		return -ENOMEM;
817

L
Linus Torvalds 已提交
818
	// Set entire image of 0xffs
819
	memset(buffer, 0xff, buffer_size);
L
Linus Torvalds 已提交
820

821
	/* Copy version number into firmware record */
L
Linus Torvalds 已提交
822 823
	firmware_rec = (struct ti_i2c_firmware_rec *)buffer;

824 825
	firmware_rec->Ver_Major	= fw_hdr->major_version;
	firmware_rec->Ver_Minor	= fw_hdr->minor_version;
L
Linus Torvalds 已提交
826

827
	/* Pointer to fw_down memory image */
828
	img_header = (struct ti_i2c_image_header *)&fw->data[4];
L
Linus Torvalds 已提交
829

830
	memcpy(buffer + sizeof(struct ti_i2c_firmware_rec),
831
		&fw->data[4 + sizeof(struct ti_i2c_image_header)],
L
Linus Torvalds 已提交
832 833 834 835 836 837
		le16_to_cpu(img_header->Length));

	for (i=0; i < buffer_size; i++) {
		cs = (__u8)(cs + buffer[i]);
	}

838
	kfree(buffer);
L
Linus Torvalds 已提交
839

840
	/* Build new header */
L
Linus Torvalds 已提交
841 842
	i2c_header =  (struct ti_i2c_desc *)header;
	firmware_rec =  (struct ti_i2c_firmware_rec*)i2c_header->Data;
843

L
Linus Torvalds 已提交
844
	i2c_header->Type	= I2C_DESC_TYPE_FIRMWARE_BLANK;
845
	i2c_header->Size	= cpu_to_le16(buffer_size);
L
Linus Torvalds 已提交
846
	i2c_header->CheckSum	= cs;
847 848
	firmware_rec->Ver_Major	= fw_hdr->major_version;
	firmware_rec->Ver_Minor	= fw_hdr->minor_version;
L
Linus Torvalds 已提交
849 850 851 852 853

	return 0;
}

/* Try to figure out what type of I2c we have */
854
static int i2c_type_bootmode(struct edgeport_serial *serial)
L
Linus Torvalds 已提交
855
{
856
	struct device *dev = &serial->serial->dev->dev;
L
Linus Torvalds 已提交
857
	int status;
858 859 860
	u8 *data;

	data = kmalloc(1, GFP_KERNEL);
861
	if (!data)
862
		return -ENOMEM;
863 864 865

	/* Try to read type 2 */
	status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ,
866
				DTK_ADDR_SPACE_I2C_TYPE_II, 0, data, 0x01);
L
Linus Torvalds 已提交
867
	if (status)
868
		dev_dbg(dev, "%s - read 2 status error = %d\n", __func__, status);
L
Linus Torvalds 已提交
869
	else
870
		dev_dbg(dev, "%s - read 2 data = 0x%x\n", __func__, *data);
871
	if ((!status) && (*data == UMP5152 || *data == UMP3410)) {
872
		dev_dbg(dev, "%s - ROM_TYPE_II\n", __func__);
L
Linus Torvalds 已提交
873
		serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
874
		goto out;
L
Linus Torvalds 已提交
875 876
	}

877 878
	/* Try to read type 3 */
	status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ,
879
				DTK_ADDR_SPACE_I2C_TYPE_III, 0,	data, 0x01);
L
Linus Torvalds 已提交
880
	if (status)
881
		dev_dbg(dev, "%s - read 3 status error = %d\n", __func__, status);
L
Linus Torvalds 已提交
882
	else
883
		dev_dbg(dev, "%s - read 2 data = 0x%x\n", __func__, *data);
884
	if ((!status) && (*data == UMP5152 || *data == UMP3410)) {
885
		dev_dbg(dev, "%s - ROM_TYPE_III\n", __func__);
L
Linus Torvalds 已提交
886
		serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_III;
887
		goto out;
L
Linus Torvalds 已提交
888 889
	}

890
	dev_dbg(dev, "%s - Unknown\n", __func__);
L
Linus Torvalds 已提交
891
	serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
892 893 894 895
	status = -ENODEV;
out:
	kfree(data);
	return status;
L
Linus Torvalds 已提交
896 897
}

898 899
static int bulk_xfer(struct usb_serial *serial, void *buffer,
						int length, int *num_sent)
L
Linus Torvalds 已提交
900 901 902
{
	int status;

903 904 905 906
	status = usb_bulk_msg(serial->dev,
			usb_sndbulkpipe(serial->dev,
				serial->port[0]->bulk_out_endpointAddress),
			buffer, length, num_sent, 1000);
L
Linus Torvalds 已提交
907 908 909 910
	return status;
}

/* Download given firmware image to the device (IN BOOT MODE) */
911 912
static int download_code(struct edgeport_serial *serial, __u8 *image,
							int image_length)
L
Linus Torvalds 已提交
913 914 915 916 917 918
{
	int status = 0;
	int pos;
	int transfer;
	int done;

919
	/* Transfer firmware image */
L
Linus Torvalds 已提交
920
	for (pos = 0; pos < image_length; ) {
921
		/* Read the next buffer from file */
L
Linus Torvalds 已提交
922 923 924 925
		transfer = image_length - pos;
		if (transfer > EDGE_FW_BULK_MAX_PACKET_SIZE)
			transfer = EDGE_FW_BULK_MAX_PACKET_SIZE;

926 927 928
		/* Transfer data */
		status = bulk_xfer(serial->serial, &image[pos],
							transfer, &done);
L
Linus Torvalds 已提交
929 930
		if (status)
			break;
931
		/* Advance buffer pointer */
L
Linus Torvalds 已提交
932 933 934 935 936 937
		pos += done;
	}

	return status;
}

938 939
/* FIXME!!! */
static int config_boot_dev(struct usb_device *dev)
L
Linus Torvalds 已提交
940 941 942 943
{
	return 0;
}

944 945 946 947 948
static int ti_cpu_rev(struct edge_ti_manuf_descriptor *desc)
{
	return TI_GET_CPU_REVISION(desc->CpuRev_BoardRev);
}

949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983
static int check_fw_sanity(struct edgeport_serial *serial,
		const struct firmware *fw)
{
	u16 length_total;
	u8 checksum = 0;
	int pos;
	struct device *dev = &serial->serial->interface->dev;
	struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;

	if (fw->size < sizeof(struct edgeport_fw_hdr)) {
		dev_err(dev, "incomplete fw header\n");
		return -EINVAL;
	}

	length_total = le16_to_cpu(fw_hdr->length) +
			sizeof(struct edgeport_fw_hdr);

	if (fw->size != length_total) {
		dev_err(dev, "bad fw size (expected: %u, got: %zu)\n",
				length_total, fw->size);
		return -EINVAL;
	}

	for (pos = sizeof(struct edgeport_fw_hdr); pos < fw->size; ++pos)
		checksum += fw->data[pos];

	if (checksum != fw_hdr->checksum) {
		dev_err(dev, "bad fw checksum (expected: 0x%x, got: 0x%x)\n",
				fw_hdr->checksum, checksum);
		return -EINVAL;
	}

	return 0;
}

L
Linus Torvalds 已提交
984 985
/**
 * DownloadTIFirmware - Download run-time operating firmware to the TI5052
986
 *
L
Linus Torvalds 已提交
987 988 989
 * This routine downloads the main operating code into the TI5052, using the
 * boot code already burned into E2PROM or ROM.
 */
990 991
static int download_fw(struct edgeport_serial *serial,
		const struct firmware *fw)
L
Linus Torvalds 已提交
992 993 994 995 996 997 998 999
{
	struct device *dev = &serial->serial->dev->dev;
	int status = 0;
	int start_address;
	struct edge_ti_manuf_descriptor *ti_manuf_desc;
	struct usb_interface_descriptor *interface;
	int download_cur_ver;
	int download_new_ver;
1000 1001
	struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;

1002
	if (check_fw_sanity(serial, fw))
1003 1004 1005 1006 1007
		return -EINVAL;

	/* If on-board version is newer, "fw_version" will be updated below. */
	serial->fw_version = (fw_hdr->major_version << 8) +
			fw_hdr->minor_version;
L
Linus Torvalds 已提交
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017

	/* This routine is entered by both the BOOT mode and the Download mode
	 * We can determine which code is running by the reading the config
	 * descriptor and if we have only one bulk pipe it is in boot mode
	 */
	serial->product_info.hardware_type = HARDWARE_TYPE_TIUMP;

	/* Default to type 2 i2c */
	serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;

1018
	status = choose_config(serial->serial->dev);
L
Linus Torvalds 已提交
1019 1020 1021 1022 1023
	if (status)
		return status;

	interface = &serial->serial->interface->cur_altsetting->desc;
	if (!interface) {
1024
		dev_err(dev, "%s - no interface set, error!\n", __func__);
L
Linus Torvalds 已提交
1025 1026 1027
		return -ENODEV;
	}

1028 1029 1030 1031 1032
	/*
	 * Setup initial mode -- the default mode 0 is TI_MODE_CONFIGURING
	 * if we have more than one endpoint we are definitely in download
	 * mode
	 */
L
Linus Torvalds 已提交
1033 1034 1035
	if (interface->bNumEndpoints > 1)
		serial->product_info.TiMode = TI_MODE_DOWNLOAD;
	else
1036
		/* Otherwise we will remain in configuring mode */
L
Linus Torvalds 已提交
1037 1038 1039 1040 1041 1042 1043 1044
		serial->product_info.TiMode = TI_MODE_CONFIGURING;

	/********************************************************************/
	/* Download Mode */
	/********************************************************************/
	if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) {
		struct ti_i2c_desc *rom_desc;

1045
		dev_dbg(dev, "%s - RUNNING IN DOWNLOAD MODE\n", __func__);
L
Linus Torvalds 已提交
1046

1047
		status = check_i2c_image(serial);
L
Linus Torvalds 已提交
1048
		if (status) {
1049
			dev_dbg(dev, "%s - DOWNLOAD MODE -- BAD I2C\n", __func__);
L
Linus Torvalds 已提交
1050 1051
			return status;
		}
1052

L
Linus Torvalds 已提交
1053 1054 1055
		/* Validate Hardware version number
		 * Read Manufacturing Descriptor from TI Based Edgeport
		 */
1056
		ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL);
1057
		if (!ti_manuf_desc)
L
Linus Torvalds 已提交
1058
			return -ENOMEM;
1059

1060
		status = get_manuf_info(serial, (__u8 *)ti_manuf_desc);
L
Linus Torvalds 已提交
1061
		if (status) {
1062
			kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1063 1064 1065
			return status;
		}

1066 1067
		/* Check version number of ION descriptor */
		if (!ignore_cpu_rev && ti_cpu_rev(ti_manuf_desc) < 2) {
1068
			dev_dbg(dev, "%s - Wrong CPU Rev %d (Must be 2)\n",
1069 1070 1071 1072
				__func__, ti_cpu_rev(ti_manuf_desc));
			kfree(ti_manuf_desc);
			return -EINVAL;
  		}
L
Linus Torvalds 已提交
1073

1074
		rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);
L
Linus Torvalds 已提交
1075
		if (!rom_desc) {
1076
			kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1077 1078 1079
			return -ENOMEM;
		}

1080 1081 1082 1083
		/* Search for type 2 record (firmware record) */
		start_address = get_descriptor_addr(serial,
				I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc);
		if (start_address != 0) {
L
Linus Torvalds 已提交
1084
			struct ti_i2c_firmware_rec *firmware_version;
1085
			u8 *record;
L
Linus Torvalds 已提交
1086

1087
			dev_dbg(dev, "%s - Found Type FIRMWARE (Type 2) record\n", __func__);
L
Linus Torvalds 已提交
1088

1089 1090
			firmware_version = kmalloc(sizeof(*firmware_version),
								GFP_KERNEL);
L
Linus Torvalds 已提交
1091
			if (!firmware_version) {
1092 1093
				kfree(rom_desc);
				kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1094 1095 1096
				return -ENOMEM;
			}

1097 1098 1099 1100 1101
			/* Validate version number
			 * Read the descriptor data
			 */
			status = read_rom(serial, start_address +
					sizeof(struct ti_i2c_desc),
L
Linus Torvalds 已提交
1102 1103 1104
					sizeof(struct ti_i2c_firmware_rec),
					(__u8 *)firmware_version);
			if (status) {
1105 1106 1107
				kfree(firmware_version);
				kfree(rom_desc);
				kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1108 1109 1110
				return status;
			}

1111 1112 1113
			/* Check version number of download with current
			   version in I2c */
			download_cur_ver = (firmware_version->Ver_Major << 8) +
L
Linus Torvalds 已提交
1114
					   (firmware_version->Ver_Minor);
1115 1116
			download_new_ver = (fw_hdr->major_version << 8) +
					   (fw_hdr->minor_version);
L
Linus Torvalds 已提交
1117

1118 1119 1120
			dev_dbg(dev, "%s - >> FW Versions Device %d.%d  Driver %d.%d\n",
				__func__, firmware_version->Ver_Major,
				firmware_version->Ver_Minor,
1121
				fw_hdr->major_version, fw_hdr->minor_version);
L
Linus Torvalds 已提交
1122

1123 1124
			/* Check if we have an old version in the I2C and
			   update if necessary */
1125
			if (download_cur_ver < download_new_ver) {
1126 1127 1128 1129
				dev_dbg(dev, "%s - Update I2C dld from %d.%d to %d.%d\n",
					__func__,
					firmware_version->Ver_Major,
					firmware_version->Ver_Minor,
1130 1131
					fw_hdr->major_version,
					fw_hdr->minor_version);
1132

1133 1134 1135 1136 1137 1138 1139
				record = kmalloc(1, GFP_KERNEL);
				if (!record) {
					kfree(firmware_version);
					kfree(rom_desc);
					kfree(ti_manuf_desc);
					return -ENOMEM;
				}
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
				/* In order to update the I2C firmware we must
				 * change the type 2 record to type 0xF2. This
				 * will force the UMP to come up in Boot Mode.
				 * Then while in boot mode, the driver will
				 * download the latest firmware (padded to
				 * 15.5k) into the UMP ram. Finally when the
				 * device comes back up in download mode the
				 * driver will cause the new firmware to be
				 * copied from the UMP Ram to I2C and the
				 * firmware will update the record type from
				 * 0xf2 to 0x02.
				 */
1152
				*record = I2C_DESC_TYPE_FIRMWARE_BLANK;
L
Linus Torvalds 已提交
1153

1154 1155 1156
				/* Change the I2C Firmware record type to
				   0xf2 to trigger an update */
				status = write_rom(serial, start_address,
1157
						sizeof(*record), record);
L
Linus Torvalds 已提交
1158
				if (status) {
1159
					kfree(record);
1160 1161 1162
					kfree(firmware_version);
					kfree(rom_desc);
					kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1163 1164 1165
					return status;
				}

1166 1167 1168 1169 1170
				/* verify the write -- must do this in order
				 * for write to complete before we do the
				 * hardware reset
				 */
				status = read_rom(serial,
L
Linus Torvalds 已提交
1171
							start_address,
1172 1173
							sizeof(*record),
							record);
L
Linus Torvalds 已提交
1174
				if (status) {
1175
					kfree(record);
1176 1177 1178
					kfree(firmware_version);
					kfree(rom_desc);
					kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1179 1180 1181
					return status;
				}

1182
				if (*record != I2C_DESC_TYPE_FIRMWARE_BLANK) {
1183
					dev_err(dev, "%s - error resetting device\n", __func__);
1184
					kfree(record);
1185 1186 1187
					kfree(firmware_version);
					kfree(rom_desc);
					kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1188 1189 1190
					return -ENODEV;
				}

1191
				dev_dbg(dev, "%s - HARDWARE RESET\n", __func__);
L
Linus Torvalds 已提交
1192

1193 1194 1195
				/* Reset UMP -- Back to BOOT MODE */
				status = ti_vsend_sync(serial->serial->dev,
						UMPC_HARDWARE_RESET,
1196 1197
						0, 0, NULL, 0,
						TI_VSEND_TIMEOUT_DEFAULT);
L
Linus Torvalds 已提交
1198

1199
				dev_dbg(dev, "%s - HARDWARE RESET return %d\n", __func__, status);
L
Linus Torvalds 已提交
1200 1201

				/* return an error on purpose. */
1202
				kfree(record);
1203 1204 1205
				kfree(firmware_version);
				kfree(rom_desc);
				kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1206
				return -ENODEV;
1207 1208 1209
			} else {
				/* Same or newer fw version is already loaded */
				serial->fw_version = download_cur_ver;
L
Linus Torvalds 已提交
1210
			}
1211
			kfree(firmware_version);
L
Linus Torvalds 已提交
1212
		}
1213 1214 1215 1216
		/* Search for type 0xF2 record (firmware blank record) */
		else if ((start_address = get_descriptor_addr(serial, I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc)) != 0) {
#define HEADER_SIZE	(sizeof(struct ti_i2c_desc) + \
					sizeof(struct ti_i2c_firmware_rec))
L
Linus Torvalds 已提交
1217 1218 1219
			__u8 *header;
			__u8 *vheader;

1220
			header = kmalloc(HEADER_SIZE, GFP_KERNEL);
L
Linus Torvalds 已提交
1221
			if (!header) {
1222 1223
				kfree(rom_desc);
				kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1224 1225
				return -ENOMEM;
			}
1226 1227

			vheader = kmalloc(HEADER_SIZE, GFP_KERNEL);
L
Linus Torvalds 已提交
1228
			if (!vheader) {
1229 1230 1231
				kfree(header);
				kfree(rom_desc);
				kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1232 1233
				return -ENOMEM;
			}
1234

1235
			dev_dbg(dev, "%s - Found Type BLANK FIRMWARE (Type F2) record\n", __func__);
1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247

			/*
			 * In order to update the I2C firmware we must change
			 * the type 2 record to type 0xF2. This will force the
			 * UMP to come up in Boot Mode.  Then while in boot
			 * mode, the driver will download the latest firmware
			 * (padded to 15.5k) into the UMP ram. Finally when the
			 * device comes back up in download mode the driver
			 * will cause the new firmware to be copied from the
			 * UMP Ram to I2C and the firmware will update the
			 * record type from 0xf2 to 0x02.
			 */
1248
			status = build_i2c_fw_hdr(header, dev, fw);
L
Linus Torvalds 已提交
1249
			if (status) {
1250 1251 1252 1253
				kfree(vheader);
				kfree(header);
				kfree(rom_desc);
				kfree(ti_manuf_desc);
1254
				return -EINVAL;
L
Linus Torvalds 已提交
1255 1256
			}

1257 1258 1259
			/* Update I2C with type 0xf2 record with correct
			   size and checksum */
			status = write_rom(serial,
L
Linus Torvalds 已提交
1260 1261 1262 1263
						start_address,
						HEADER_SIZE,
						header);
			if (status) {
1264 1265 1266 1267
				kfree(vheader);
				kfree(header);
				kfree(rom_desc);
				kfree(ti_manuf_desc);
1268
				return -EINVAL;
L
Linus Torvalds 已提交
1269 1270
			}

1271 1272 1273 1274
			/* verify the write -- must do this in order for
			   write to complete before we do the hardware reset */
			status = read_rom(serial, start_address,
							HEADER_SIZE, vheader);
L
Linus Torvalds 已提交
1275 1276

			if (status) {
1277
				dev_dbg(dev, "%s - can't read header back\n", __func__);
1278 1279 1280 1281
				kfree(vheader);
				kfree(header);
				kfree(rom_desc);
				kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1282 1283 1284
				return status;
			}
			if (memcmp(vheader, header, HEADER_SIZE)) {
1285
				dev_dbg(dev, "%s - write download record failed\n", __func__);
1286 1287 1288 1289
				kfree(vheader);
				kfree(header);
				kfree(rom_desc);
				kfree(ti_manuf_desc);
1290
				return -EINVAL;
L
Linus Torvalds 已提交
1291 1292
			}

1293 1294
			kfree(vheader);
			kfree(header);
L
Linus Torvalds 已提交
1295

1296
			dev_dbg(dev, "%s - Start firmware update\n", __func__);
L
Linus Torvalds 已提交
1297

1298 1299
			/* Tell firmware to copy download image into I2C */
			status = ti_vsend_sync(serial->serial->dev,
1300 1301 1302
					UMPC_COPY_DNLD_TO_I2C,
					0, 0, NULL, 0,
					TI_VSEND_TIMEOUT_FW_DOWNLOAD);
L
Linus Torvalds 已提交
1303

1304
		  	dev_dbg(dev, "%s - Update complete 0x%x\n", __func__, status);
L
Linus Torvalds 已提交
1305
			if (status) {
1306 1307 1308 1309 1310
				dev_err(dev,
					"%s - UMPC_COPY_DNLD_TO_I2C failed\n",
								__func__);
				kfree(rom_desc);
				kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1311 1312 1313 1314 1315
				return status;
			}
		}

		// The device is running the download code
1316 1317
		kfree(rom_desc);
		kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1318 1319 1320 1321 1322 1323
		return 0;
	}

	/********************************************************************/
	/* Boot Mode */
	/********************************************************************/
1324
	dev_dbg(dev, "%s - RUNNING IN BOOT MODE\n", __func__);
L
Linus Torvalds 已提交
1325

1326 1327
	/* Configure the TI device so we can use the BULK pipes for download */
	status = config_boot_dev(serial->serial->dev);
L
Linus Torvalds 已提交
1328 1329 1330
	if (status)
		return status;

1331 1332
	if (le16_to_cpu(serial->serial->dev->descriptor.idVendor)
							!= USB_VENDOR_ID_ION) {
1333 1334
		dev_dbg(dev, "%s - VID = 0x%x\n", __func__,
			le16_to_cpu(serial->serial->dev->descriptor.idVendor));
L
Linus Torvalds 已提交
1335
		serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
1336
		goto stayinbootmode;
L
Linus Torvalds 已提交
1337 1338
	}

1339 1340 1341 1342
	/* We have an ION device (I2c Must be programmed)
	   Determine I2C image type */
	if (i2c_type_bootmode(serial))
		goto stayinbootmode;
L
Linus Torvalds 已提交
1343

1344 1345
	/* Check for ION Vendor ID and that the I2C is valid */
	if (!check_i2c_image(serial)) {
L
Linus Torvalds 已提交
1346 1347 1348 1349 1350 1351 1352 1353 1354
		struct ti_i2c_image_header *header;
		int i;
		__u8 cs = 0;
		__u8 *buffer;
		int buffer_size;

		/* Validate Hardware version number
		 * Read Manufacturing Descriptor from TI Based Edgeport
		 */
1355
		ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL);
1356
		if (!ti_manuf_desc)
L
Linus Torvalds 已提交
1357
			return -ENOMEM;
1358

1359
		status = get_manuf_info(serial, (__u8 *)ti_manuf_desc);
L
Linus Torvalds 已提交
1360
		if (status) {
1361 1362
			kfree(ti_manuf_desc);
			goto stayinbootmode;
L
Linus Torvalds 已提交
1363 1364
		}

1365 1366
		/* Check for version 2 */
		if (!ignore_cpu_rev && ti_cpu_rev(ti_manuf_desc) < 2) {
1367 1368
			dev_dbg(dev, "%s - Wrong CPU Rev %d (Must be 2)\n",
				__func__, ti_cpu_rev(ti_manuf_desc));
1369 1370
			kfree(ti_manuf_desc);
			goto stayinbootmode;
L
Linus Torvalds 已提交
1371 1372
		}

1373
		kfree(ti_manuf_desc);
L
Linus Torvalds 已提交
1374 1375

		/*
1376 1377 1378 1379 1380 1381 1382 1383 1384
		 * In order to update the I2C firmware we must change the type
		 * 2 record to type 0xF2. This will force the UMP to come up
		 * in Boot Mode.  Then while in boot mode, the driver will
		 * download the latest firmware (padded to 15.5k) into the
		 * UMP ram. Finally when the device comes back up in download
		 * mode the driver will cause the new firmware to be copied
		 * from the UMP Ram to I2C and the firmware will update the
		 * record type from 0xf2 to 0x02.
		 *
L
Linus Torvalds 已提交
1385 1386 1387 1388
		 * Do we really have to copy the whole firmware image,
		 * or could we do this in place!
		 */

1389 1390 1391 1392
		/* Allocate a 15.5k buffer + 3 byte header */
		buffer_size = (((1024 * 16) - 512) +
					sizeof(struct ti_i2c_image_header));
		buffer = kmalloc(buffer_size, GFP_KERNEL);
1393
		if (!buffer)
L
Linus Torvalds 已提交
1394
			return -ENOMEM;
1395 1396 1397

		/* Initialize the buffer to 0xff (pad the buffer) */
		memset(buffer, 0xff, buffer_size);
1398
		memcpy(buffer, &fw->data[4], fw->size - 4);
L
Linus Torvalds 已提交
1399

1400 1401
		for (i = sizeof(struct ti_i2c_image_header);
				i < buffer_size; i++) {
L
Linus Torvalds 已提交
1402 1403
			cs = (__u8)(cs + buffer[i]);
		}
1404

L
Linus Torvalds 已提交
1405
		header = (struct ti_i2c_image_header *)buffer;
1406 1407 1408 1409

		/* update length and checksum after padding */
		header->Length 	 = cpu_to_le16((__u16)(buffer_size -
					sizeof(struct ti_i2c_image_header)));
L
Linus Torvalds 已提交
1410 1411
		header->CheckSum = cs;

1412
		/* Download the operational code  */
1413 1414 1415
		dev_dbg(dev, "%s - Downloading operational code image version %d.%d (TI UMP)\n",
				__func__,
				fw_hdr->major_version, fw_hdr->minor_version);
1416
		status = download_code(serial, buffer, buffer_size);
L
Linus Torvalds 已提交
1417

1418
		kfree(buffer);
L
Linus Torvalds 已提交
1419 1420

		if (status) {
1421
			dev_dbg(dev, "%s - Error downloading operational code image\n", __func__);
L
Linus Torvalds 已提交
1422 1423 1424
			return status;
		}

1425
		/* Device will reboot */
L
Linus Torvalds 已提交
1426 1427
		serial->product_info.TiMode = TI_MODE_TRANSITIONING;

1428
		dev_dbg(dev, "%s - Download successful -- Device rebooting...\n", __func__);
L
Linus Torvalds 已提交
1429 1430 1431 1432 1433

		/* return an error on purpose */
		return -ENODEV;
	}

1434 1435
stayinbootmode:
	/* Eprom is invalid or blank stay in boot mode */
1436
	dev_dbg(dev, "%s - STAYING IN BOOT MODE\n", __func__);
L
Linus Torvalds 已提交
1437 1438 1439 1440 1441 1442
	serial->product_info.TiMode = TI_MODE_BOOT;

	return 0;
}


1443
static int ti_do_config(struct edgeport_port *port, int feature, int on)
L
Linus Torvalds 已提交
1444
{
1445 1446
	int port_number = port->port->port_number;

1447 1448 1449 1450
	on = !!on;	/* 1 or 0 not bitmask */
	return send_cmd(port->port->serial->dev,
			feature, (__u8)(UMPM_UART1_PORT + port_number),
			on, NULL, 0);
L
Linus Torvalds 已提交
1451 1452 1453
}


1454
static int restore_mcr(struct edgeport_port *port, __u8 mcr)
L
Linus Torvalds 已提交
1455 1456 1457
{
	int status = 0;

1458
	dev_dbg(&port->port->dev, "%s - %x\n", __func__, mcr);
L
Linus Torvalds 已提交
1459

1460
	status = ti_do_config(port, UMPC_SET_CLR_DTR, mcr & MCR_DTR);
L
Linus Torvalds 已提交
1461 1462
	if (status)
		return status;
1463
	status = ti_do_config(port, UMPC_SET_CLR_RTS, mcr & MCR_RTS);
L
Linus Torvalds 已提交
1464 1465
	if (status)
		return status;
1466
	return ti_do_config(port, UMPC_SET_CLR_LOOPBACK, mcr & MCR_LOOPBACK);
L
Linus Torvalds 已提交
1467 1468 1469
}

/* Convert TI LSR to standard UART flags */
1470
static __u8 map_line_status(__u8 ti_lsr)
L
Linus Torvalds 已提交
1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481
{
	__u8 lsr = 0;

#define MAP_FLAG(flagUmp, flagUart)    \
	if (ti_lsr & flagUmp) \
		lsr |= flagUart;

	MAP_FLAG(UMP_UART_LSR_OV_MASK, LSR_OVER_ERR)	/* overrun */
	MAP_FLAG(UMP_UART_LSR_PE_MASK, LSR_PAR_ERR)	/* parity error */
	MAP_FLAG(UMP_UART_LSR_FE_MASK, LSR_FRM_ERR)	/* framing error */
	MAP_FLAG(UMP_UART_LSR_BR_MASK, LSR_BREAK)	/* break detected */
1482 1483
	MAP_FLAG(UMP_UART_LSR_RX_MASK, LSR_RX_AVAIL)	/* rx data available */
	MAP_FLAG(UMP_UART_LSR_TX_MASK, LSR_TX_EMPTY)	/* tx hold reg empty */
L
Linus Torvalds 已提交
1484 1485 1486 1487 1488 1489

#undef MAP_FLAG

	return lsr;
}

1490
static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
L
Linus Torvalds 已提交
1491 1492 1493 1494
{
	struct async_icount *icount;
	struct tty_struct *tty;

1495
	dev_dbg(&edge_port->port->dev, "%s - %02x\n", __func__, msr);
L
Linus Torvalds 已提交
1496

1497 1498
	if (msr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR |
			EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) {
1499
		icount = &edge_port->port->icount;
L
Linus Torvalds 已提交
1500 1501 1502 1503 1504 1505 1506 1507 1508 1509

		/* update input line counters */
		if (msr & EDGEPORT_MSR_DELTA_CTS)
			icount->cts++;
		if (msr & EDGEPORT_MSR_DELTA_DSR)
			icount->dsr++;
		if (msr & EDGEPORT_MSR_DELTA_CD)
			icount->dcd++;
		if (msr & EDGEPORT_MSR_DELTA_RI)
			icount->rng++;
1510
		wake_up_interruptible(&edge_port->port->port.delta_msr_wait);
L
Linus Torvalds 已提交
1511 1512 1513 1514 1515
	}

	/* Save the new modem status */
	edge_port->shadow_msr = msr & 0xf0;

A
Alan Cox 已提交
1516
	tty = tty_port_tty_get(&edge_port->port->port);
L
Linus Torvalds 已提交
1517 1518
	/* handle CTS flow control */
	if (tty && C_CRTSCTS(tty)) {
1519
		if (msr & EDGEPORT_MSR_CTS)
L
Linus Torvalds 已提交
1520 1521
			tty_wakeup(tty);
	}
A
Alan Cox 已提交
1522
	tty_kref_put(tty);
L
Linus Torvalds 已提交
1523 1524
}

1525 1526
static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data,
							__u8 lsr, __u8 data)
L
Linus Torvalds 已提交
1527 1528
{
	struct async_icount *icount;
1529 1530
	__u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR |
						LSR_FRM_ERR | LSR_BREAK));
L
Linus Torvalds 已提交
1531

1532
	dev_dbg(&edge_port->port->dev, "%s - %02x\n", __func__, new_lsr);
L
Linus Torvalds 已提交
1533 1534 1535

	edge_port->shadow_lsr = lsr;

1536
	if (new_lsr & LSR_BREAK)
L
Linus Torvalds 已提交
1537 1538 1539 1540 1541 1542 1543
		/*
		 * Parity and Framing errors only count if they
		 * occur exclusive of a break being received.
		 */
		new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK);

	/* Place LSR data byte into Rx buffer */
J
Jiri Slaby 已提交
1544 1545
	if (lsr_data)
		edge_tty_recv(edge_port->port, &data, 1);
L
Linus Torvalds 已提交
1546 1547

	/* update input line counters */
1548
	icount = &edge_port->port->icount;
L
Linus Torvalds 已提交
1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559
	if (new_lsr & LSR_BREAK)
		icount->brk++;
	if (new_lsr & LSR_OVER_ERR)
		icount->overrun++;
	if (new_lsr & LSR_PAR_ERR)
		icount->parity++;
	if (new_lsr & LSR_FRM_ERR)
		icount->frame++;
}


1560
static void edge_interrupt_callback(struct urb *urb)
L
Linus Torvalds 已提交
1561
{
1562
	struct edgeport_serial *edge_serial = urb->context;
L
Linus Torvalds 已提交
1563 1564
	struct usb_serial_port *port;
	struct edgeport_port *edge_port;
1565
	struct device *dev;
L
Linus Torvalds 已提交
1566 1567 1568 1569
	unsigned char *data = urb->transfer_buffer;
	int length = urb->actual_length;
	int port_number;
	int function;
1570
	int retval;
L
Linus Torvalds 已提交
1571 1572
	__u8 lsr;
	__u8 msr;
1573
	int status = urb->status;
L
Linus Torvalds 已提交
1574

1575
	switch (status) {
L
Linus Torvalds 已提交
1576 1577 1578 1579 1580 1581 1582
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
1583
		dev_dbg(&urb->dev->dev, "%s - urb shutting down with status: %d\n",
1584
		    __func__, status);
L
Linus Torvalds 已提交
1585 1586
		return;
	default:
1587
		dev_err(&urb->dev->dev, "%s - nonzero urb status received: "
1588
			"%d\n", __func__, status);
L
Linus Torvalds 已提交
1589 1590 1591 1592
		goto exit;
	}

	if (!length) {
1593
		dev_dbg(&urb->dev->dev, "%s - no data in urb\n", __func__);
L
Linus Torvalds 已提交
1594 1595
		goto exit;
	}
1596

1597
	dev = &edge_serial->serial->dev->dev;
1598
	usb_serial_debug_data(dev, __func__, length, data);
1599

L
Linus Torvalds 已提交
1600
	if (length != 2) {
1601
		dev_dbg(dev, "%s - expecting packet of size 2, got %d\n", __func__, length);
L
Linus Torvalds 已提交
1602 1603 1604
		goto exit;
	}

1605 1606
	port_number = TIUMP_GET_PORT_FROM_CODE(data[0]);
	function    = TIUMP_GET_FUNC_FROM_CODE(data[0]);
1607 1608
	dev_dbg(dev, "%s - port_number %d, function %d, info 0x%x\n", __func__,
		port_number, function, data[1]);
L
Linus Torvalds 已提交
1609 1610 1611
	port = edge_serial->serial->port[port_number];
	edge_port = usb_get_serial_port_data(port);
	if (!edge_port) {
1612
		dev_dbg(dev, "%s - edge_port not found\n", __func__);
L
Linus Torvalds 已提交
1613 1614 1615 1616
		return;
	}
	switch (function) {
	case TIUMP_INTERRUPT_CODE_LSR:
1617
		lsr = map_line_status(data[1]);
L
Linus Torvalds 已提交
1618
		if (lsr & UMP_UART_LSR_DATA_MASK) {
1619 1620
			/* Save the LSR event for bulk read
			   completion routine */
1621 1622
			dev_dbg(dev, "%s - LSR Event Port %u LSR Status = %02x\n",
				__func__, port_number, lsr);
L
Linus Torvalds 已提交
1623 1624 1625
			edge_port->lsr_event = 1;
			edge_port->lsr_mask = lsr;
		} else {
1626 1627
			dev_dbg(dev, "%s - ===== Port %d LSR Status = %02x ======\n",
				__func__, port_number, lsr);
1628
			handle_new_lsr(edge_port, 0, lsr, 0);
L
Linus Torvalds 已提交
1629 1630 1631
		}
		break;

1632
	case TIUMP_INTERRUPT_CODE_MSR:	/* MSR */
L
Linus Torvalds 已提交
1633 1634
		/* Copy MSR from UMP */
		msr = data[1];
1635 1636
		dev_dbg(dev, "%s - ===== Port %u MSR Status = %02x ======\n",
			__func__, port_number, msr);
1637
		handle_new_msr(edge_port, msr);
L
Linus Torvalds 已提交
1638 1639 1640
		break;

	default:
1641 1642 1643
		dev_err(&urb->dev->dev,
			"%s - Unknown Interrupt code from UMP %x\n",
			__func__, data[1]);
L
Linus Torvalds 已提交
1644
		break;
1645

L
Linus Torvalds 已提交
1646 1647 1648
	}

exit:
1649
	retval = usb_submit_urb(urb, GFP_ATOMIC);
1650
	if (retval)
1651 1652
		dev_err(&urb->dev->dev,
			"%s - usb_submit_urb failed with result %d\n",
1653
			 __func__, retval);
L
Linus Torvalds 已提交
1654 1655
}

1656
static void edge_bulk_in_callback(struct urb *urb)
L
Linus Torvalds 已提交
1657
{
1658
	struct edgeport_port *edge_port = urb->context;
1659
	struct device *dev = &edge_port->port->dev;
L
Linus Torvalds 已提交
1660
	unsigned char *data = urb->transfer_buffer;
1661
	int retval = 0;
L
Linus Torvalds 已提交
1662
	int port_number;
1663
	int status = urb->status;
L
Linus Torvalds 已提交
1664

1665
	switch (status) {
L
Linus Torvalds 已提交
1666 1667 1668 1669 1670 1671 1672
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
1673
		dev_dbg(&urb->dev->dev, "%s - urb shutting down with status: %d\n", __func__, status);
L
Linus Torvalds 已提交
1674 1675
		return;
	default:
1676
		dev_err(&urb->dev->dev, "%s - nonzero read bulk status received: %d\n", __func__, status);
L
Linus Torvalds 已提交
1677 1678
	}

1679
	if (status == -EPIPE)
L
Linus Torvalds 已提交
1680 1681
		goto exit;

1682
	if (status) {
1683
		dev_err(&urb->dev->dev, "%s - stopping read!\n", __func__);
L
Linus Torvalds 已提交
1684 1685 1686
		return;
	}

1687
	port_number = edge_port->port->port_number;
L
Linus Torvalds 已提交
1688 1689 1690

	if (edge_port->lsr_event) {
		edge_port->lsr_event = 0;
1691 1692
		dev_dbg(dev, "%s ===== Port %u LSR Status = %02x, Data = %02x ======\n",
			__func__, port_number, edge_port->lsr_mask, *data);
1693
		handle_new_lsr(edge_port, 1, edge_port->lsr_mask, *data);
L
Linus Torvalds 已提交
1694 1695 1696 1697 1698
		/* Adjust buffer length/pointer */
		--urb->actual_length;
		++data;
	}

J
Jiri Slaby 已提交
1699
	if (urb->actual_length) {
1700
		usb_serial_debug_data(dev, __func__, urb->actual_length, data);
1701
		if (edge_port->close_pending)
1702
			dev_dbg(dev, "%s - close pending, dropping data on the floor\n",
1703 1704
								__func__);
		else
J
Jiri Slaby 已提交
1705
			edge_tty_recv(edge_port->port, data,
J
Jiri Slaby 已提交
1706
					urb->actual_length);
1707
		edge_port->port->icount.rx += urb->actual_length;
L
Linus Torvalds 已提交
1708 1709 1710 1711 1712
	}

exit:
	/* continue read unless stopped */
	spin_lock(&edge_port->ep_lock);
1713
	if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING)
1714
		retval = usb_submit_urb(urb, GFP_ATOMIC);
1715
	else if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPING)
L
Linus Torvalds 已提交
1716
		edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPED;
1717

L
Linus Torvalds 已提交
1718
	spin_unlock(&edge_port->ep_lock);
1719
	if (retval)
1720
		dev_err(dev, "%s - usb_submit_urb failed with result %d\n", __func__, retval);
L
Linus Torvalds 已提交
1721 1722
}

J
Jiri Slaby 已提交
1723 1724
static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data,
		int length)
L
Linus Torvalds 已提交
1725
{
1726
	int queued;
L
Linus Torvalds 已提交
1727

J
Jiri Slaby 已提交
1728
	queued = tty_insert_flip_string(&port->port, data, length);
1729
	if (queued < length)
J
Jiri Slaby 已提交
1730
		dev_err(&port->dev, "%s - dropping data, %d bytes lost\n",
1731
			__func__, length - queued);
J
Jiri Slaby 已提交
1732
	tty_flip_buffer_push(&port->port);
L
Linus Torvalds 已提交
1733 1734
}

1735
static void edge_bulk_out_callback(struct urb *urb)
L
Linus Torvalds 已提交
1736
{
1737
	struct usb_serial_port *port = urb->context;
L
Linus Torvalds 已提交
1738
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
1739
	int status = urb->status;
A
Alan Cox 已提交
1740
	struct tty_struct *tty;
L
Linus Torvalds 已提交
1741 1742 1743

	edge_port->ep_write_urb_in_use = 0;

1744
	switch (status) {
L
Linus Torvalds 已提交
1745 1746 1747 1748 1749 1750 1751
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
1752
		dev_dbg(&urb->dev->dev, "%s - urb shutting down with status: %d\n",
1753
		    __func__, status);
L
Linus Torvalds 已提交
1754 1755
		return;
	default:
1756
		dev_err_console(port, "%s - nonzero write bulk status "
1757
			"received: %d\n", __func__, status);
L
Linus Torvalds 已提交
1758 1759 1760
	}

	/* send any buffered data */
A
Alan Cox 已提交
1761
	tty = tty_port_tty_get(&port->port);
1762
	edge_send(port, tty);
A
Alan Cox 已提交
1763
	tty_kref_put(tty);
L
Linus Torvalds 已提交
1764 1765
}

1766
static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
L
Linus Torvalds 已提交
1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779
{
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	struct edgeport_serial *edge_serial;
	struct usb_device *dev;
	struct urb *urb;
	int port_number;
	int status;
	u16 open_settings;
	u8 transaction_timeout;

	if (edge_port == NULL)
		return -ENODEV;

1780
	port_number = port->port_number;
L
Linus Torvalds 已提交
1781 1782 1783 1784

	dev = port->serial->dev;

	/* turn off loopback */
1785
	status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0);
L
Linus Torvalds 已提交
1786
	if (status) {
1787 1788
		dev_err(&port->dev,
				"%s - cannot send clear loopback command, %d\n",
1789
			__func__, status);
L
Linus Torvalds 已提交
1790 1791
		return status;
	}
1792

L
Linus Torvalds 已提交
1793
	/* set up the port settings */
A
Alan Cox 已提交
1794
	if (tty)
1795
		edge_set_termios(tty, port, &tty->termios);
L
Linus Torvalds 已提交
1796 1797 1798 1799 1800 1801

	/* open up the port */

	/* milliseconds to timeout for DMA transfer */
	transaction_timeout = 2;

1802 1803
	edge_port->ump_read_timeout =
				max(20, ((transaction_timeout * 3) / 2));
L
Linus Torvalds 已提交
1804

1805 1806 1807
	/* milliseconds to timeout for DMA transfer */
	open_settings = (u8)(UMP_DMA_MODE_CONTINOUS |
			     UMP_PIPE_TRANS_TIMEOUT_ENA |
L
Linus Torvalds 已提交
1808 1809
			     (transaction_timeout << 2));

1810
	dev_dbg(&port->dev, "%s - Sending UMPC_OPEN_PORT\n", __func__);
L
Linus Torvalds 已提交
1811 1812

	/* Tell TI to open and start the port */
1813 1814
	status = send_cmd(dev, UMPC_OPEN_PORT,
		(u8)(UMPM_UART1_PORT + port_number), open_settings, NULL, 0);
L
Linus Torvalds 已提交
1815
	if (status) {
1816 1817
		dev_err(&port->dev, "%s - cannot send open command, %d\n",
							__func__, status);
L
Linus Torvalds 已提交
1818 1819 1820 1821
		return status;
	}

	/* Start the DMA? */
1822 1823
	status = send_cmd(dev, UMPC_START_PORT,
		(u8)(UMPM_UART1_PORT + port_number), 0, NULL, 0);
L
Linus Torvalds 已提交
1824
	if (status) {
1825 1826
		dev_err(&port->dev, "%s - cannot send start DMA command, %d\n",
							__func__, status);
L
Linus Torvalds 已提交
1827 1828 1829 1830
		return status;
	}

	/* Clear TX and RX buffers in UMP */
1831
	status = purge_port(port, UMP_PORT_DIR_OUT | UMP_PORT_DIR_IN);
L
Linus Torvalds 已提交
1832
	if (status) {
1833 1834 1835
		dev_err(&port->dev,
			"%s - cannot send clear buffers command, %d\n",
			__func__, status);
L
Linus Torvalds 已提交
1836 1837 1838 1839
		return status;
	}

	/* Read Initial MSR */
1840 1841 1842
	status = ti_vread_sync(dev, UMPC_READ_MSR, 0,
				(__u16)(UMPM_UART1_PORT + port_number),
				&edge_port->shadow_msr, 1);
L
Linus Torvalds 已提交
1843
	if (status) {
1844 1845
		dev_err(&port->dev, "%s - cannot send read MSR command, %d\n",
							__func__, status);
L
Linus Torvalds 已提交
1846 1847 1848
		return status;
	}

1849
	dev_dbg(&port->dev, "ShadowMSR 0x%X\n", edge_port->shadow_msr);
1850

L
Linus Torvalds 已提交
1851 1852
	/* Set Initial MCR */
	edge_port->shadow_mcr = MCR_RTS | MCR_DTR;
1853
	dev_dbg(&port->dev, "ShadowMCR 0x%X\n", edge_port->shadow_mcr);
L
Linus Torvalds 已提交
1854 1855

	edge_serial = edge_port->edge_serial;
1856
	if (mutex_lock_interruptible(&edge_serial->es_lock))
L
Linus Torvalds 已提交
1857 1858
		return -ERESTARTSYS;
	if (edge_serial->num_ports_open == 0) {
1859
		/* we are the first port to open, post the interrupt urb */
L
Linus Torvalds 已提交
1860 1861
		urb = edge_serial->serial->port[0]->interrupt_in_urb;
		if (!urb) {
1862 1863 1864
			dev_err(&port->dev,
				"%s - no interrupt urb present, exiting\n",
				__func__);
L
Linus Torvalds 已提交
1865
			status = -EINVAL;
1866
			goto release_es_lock;
L
Linus Torvalds 已提交
1867 1868
		}
		urb->context = edge_serial;
1869
		status = usb_submit_urb(urb, GFP_KERNEL);
L
Linus Torvalds 已提交
1870
		if (status) {
1871 1872 1873
			dev_err(&port->dev,
				"%s - usb_submit_urb failed with value %d\n",
					__func__, status);
1874
			goto release_es_lock;
L
Linus Torvalds 已提交
1875 1876 1877 1878 1879 1880 1881
		}
	}

	/*
	 * reset the data toggle on the bulk endpoints to work around bug in
	 * host controllers where things get out of sync some times
	 */
1882 1883
	usb_clear_halt(dev, port->write_urb->pipe);
	usb_clear_halt(dev, port->read_urb->pipe);
L
Linus Torvalds 已提交
1884 1885 1886 1887

	/* start up our bulk read urb */
	urb = port->read_urb;
	if (!urb) {
1888 1889
		dev_err(&port->dev, "%s - no read urb present, exiting\n",
								__func__);
L
Linus Torvalds 已提交
1890 1891 1892 1893 1894
		status = -EINVAL;
		goto unlink_int_urb;
	}
	edge_port->ep_read_urb_state = EDGE_READ_URB_RUNNING;
	urb->context = edge_port;
1895
	status = usb_submit_urb(urb, GFP_KERNEL);
L
Linus Torvalds 已提交
1896
	if (status) {
1897 1898 1899
		dev_err(&port->dev,
			"%s - read bulk usb_submit_urb failed with value %d\n",
				__func__, status);
L
Linus Torvalds 已提交
1900 1901 1902 1903 1904
		goto unlink_int_urb;
	}

	++edge_serial->num_ports_open;

1905
	goto release_es_lock;
L
Linus Torvalds 已提交
1906 1907 1908 1909

unlink_int_urb:
	if (edge_port->edge_serial->num_ports_open == 0)
		usb_kill_urb(port->serial->port[0]->interrupt_in_urb);
1910 1911
release_es_lock:
	mutex_unlock(&edge_serial->es_lock);
L
Linus Torvalds 已提交
1912 1913 1914
	return status;
}

1915
static void edge_close(struct usb_serial_port *port)
L
Linus Torvalds 已提交
1916 1917 1918
{
	struct edgeport_serial *edge_serial;
	struct edgeport_port *edge_port;
1919
	struct usb_serial *serial = port->serial;
1920
	unsigned long flags;
L
Linus Torvalds 已提交
1921 1922 1923 1924
	int port_number;

	edge_serial = usb_get_serial_data(port->serial);
	edge_port = usb_get_serial_port_data(port);
1925
	if (edge_serial == NULL || edge_port == NULL)
L
Linus Torvalds 已提交
1926
		return;
1927 1928

	/* The bulkreadcompletion routine will check
L
Linus Torvalds 已提交
1929 1930 1931 1932 1933 1934
	 * this flag and dump add read data */
	edge_port->close_pending = 1;

	usb_kill_urb(port->read_urb);
	usb_kill_urb(port->write_urb);
	edge_port->ep_write_urb_in_use = 0;
1935
	spin_lock_irqsave(&edge_port->ep_lock, flags);
J
Johan Hovold 已提交
1936
	kfifo_reset_out(&port->write_fifo);
1937
	spin_unlock_irqrestore(&edge_port->ep_lock, flags);
L
Linus Torvalds 已提交
1938

1939
	dev_dbg(&port->dev, "%s - send umpc_close_port\n", __func__);
1940
	port_number = port->port_number;
1941 1942
	send_cmd(serial->dev, UMPC_CLOSE_PORT,
		     (__u8)(UMPM_UART1_PORT + port_number), 0, NULL, 0);
1943

1944
	mutex_lock(&edge_serial->es_lock);
L
Linus Torvalds 已提交
1945 1946 1947 1948 1949 1950
	--edge_port->edge_serial->num_ports_open;
	if (edge_port->edge_serial->num_ports_open <= 0) {
		/* last port is now closed, let's shut down our interrupt urb */
		usb_kill_urb(port->serial->port[0]->interrupt_in_urb);
		edge_port->edge_serial->num_ports_open = 0;
	}
1951
	mutex_unlock(&edge_serial->es_lock);
L
Linus Torvalds 已提交
1952 1953 1954
	edge_port->close_pending = 0;
}

A
Alan Cox 已提交
1955 1956
static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
				const unsigned char *data, int count)
L
Linus Torvalds 已提交
1957 1958 1959 1960
{
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);

	if (count == 0) {
1961
		dev_dbg(&port->dev, "%s - write request of 0 bytes\n", __func__);
L
Linus Torvalds 已提交
1962 1963 1964 1965 1966 1967 1968 1969
		return 0;
	}

	if (edge_port == NULL)
		return -ENODEV;
	if (edge_port->close_pending == 1)
		return -ENODEV;

J
Johan Hovold 已提交
1970
	count = kfifo_in_locked(&port->write_fifo, data, count,
1971
							&edge_port->ep_lock);
1972
	edge_send(port, tty);
L
Linus Torvalds 已提交
1973 1974 1975 1976

	return count;
}

1977
static void edge_send(struct usb_serial_port *port, struct tty_struct *tty)
L
Linus Torvalds 已提交
1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989
{
	int count, result;
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	unsigned long flags;

	spin_lock_irqsave(&edge_port->ep_lock, flags);

	if (edge_port->ep_write_urb_in_use) {
		spin_unlock_irqrestore(&edge_port->ep_lock, flags);
		return;
	}

J
Johan Hovold 已提交
1990
	count = kfifo_out(&port->write_fifo,
L
Linus Torvalds 已提交
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002
				port->write_urb->transfer_buffer,
				port->bulk_out_size);

	if (count == 0) {
		spin_unlock_irqrestore(&edge_port->ep_lock, flags);
		return;
	}

	edge_port->ep_write_urb_in_use = 1;

	spin_unlock_irqrestore(&edge_port->ep_lock, flags);

2003
	usb_serial_debug_data(&port->dev, __func__, count, port->write_urb->transfer_buffer);
L
Linus Torvalds 已提交
2004 2005

	/* set up our urb */
2006
	port->write_urb->transfer_buffer_length = count;
L
Linus Torvalds 已提交
2007 2008 2009 2010

	/* send the data out the bulk port */
	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
	if (result) {
2011
		dev_err_console(port,
2012 2013
			"%s - failed submitting write urb, error %d\n",
				__func__, result);
L
Linus Torvalds 已提交
2014
		edge_port->ep_write_urb_in_use = 0;
2015 2016
		/* TODO: reschedule edge_send */
	} else
2017
		edge_port->port->icount.tx += count;
L
Linus Torvalds 已提交
2018 2019 2020

	/* wakeup any process waiting for writes to complete */
	/* there is now more room in the buffer for new writes */
2021
	if (tty)
L
Linus Torvalds 已提交
2022 2023 2024
		tty_wakeup(tty);
}

A
Alan Cox 已提交
2025
static int edge_write_room(struct tty_struct *tty)
L
Linus Torvalds 已提交
2026
{
A
Alan Cox 已提交
2027
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
2028 2029 2030 2031 2032
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	int room = 0;
	unsigned long flags;

	if (edge_port == NULL)
2033
		return 0;
L
Linus Torvalds 已提交
2034
	if (edge_port->close_pending == 1)
2035
		return 0;
L
Linus Torvalds 已提交
2036 2037

	spin_lock_irqsave(&edge_port->ep_lock, flags);
J
Johan Hovold 已提交
2038
	room = kfifo_avail(&port->write_fifo);
L
Linus Torvalds 已提交
2039 2040
	spin_unlock_irqrestore(&edge_port->ep_lock, flags);

2041
	dev_dbg(&port->dev, "%s - returns %d\n", __func__, room);
L
Linus Torvalds 已提交
2042 2043 2044
	return room;
}

A
Alan Cox 已提交
2045
static int edge_chars_in_buffer(struct tty_struct *tty)
L
Linus Torvalds 已提交
2046
{
A
Alan Cox 已提交
2047
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
2048 2049 2050 2051
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	int chars = 0;
	unsigned long flags;
	if (edge_port == NULL)
2052
		return 0;
L
Linus Torvalds 已提交
2053 2054

	spin_lock_irqsave(&edge_port->ep_lock, flags);
J
Johan Hovold 已提交
2055
	chars = kfifo_len(&port->write_fifo);
L
Linus Torvalds 已提交
2056 2057
	spin_unlock_irqrestore(&edge_port->ep_lock, flags);

2058
	dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
L
Linus Torvalds 已提交
2059 2060 2061
	return chars;
}

2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073
static bool edge_tx_empty(struct usb_serial_port *port)
{
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	int ret;

	ret = tx_active(edge_port);
	if (ret > 0)
		return false;

	return true;
}

A
Alan Cox 已提交
2074
static void edge_throttle(struct tty_struct *tty)
L
Linus Torvalds 已提交
2075
{
A
Alan Cox 已提交
2076
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
2077 2078 2079 2080 2081 2082 2083 2084 2085
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	int status;

	if (edge_port == NULL)
		return;

	/* if we are implementing XON/XOFF, send the stop character */
	if (I_IXOFF(tty)) {
		unsigned char stop_char = STOP_CHAR(tty);
A
Alan Cox 已提交
2086 2087 2088 2089
		status = edge_write(tty, port, &stop_char, 1);
		if (status <= 0) {
			dev_err(&port->dev, "%s - failed to write stop character, %d\n", __func__, status);
		}
L
Linus Torvalds 已提交
2090 2091 2092 2093 2094 2095 2096 2097 2098
	}

	/* if we are implementing RTS/CTS, stop reads */
	/* and the Edgeport will clear the RTS line */
	if (C_CRTSCTS(tty))
		stop_read(edge_port);

}

A
Alan Cox 已提交
2099
static void edge_unthrottle(struct tty_struct *tty)
L
Linus Torvalds 已提交
2100
{
A
Alan Cox 已提交
2101
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
2102 2103 2104 2105 2106 2107 2108 2109 2110
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	int status;

	if (edge_port == NULL)
		return;

	/* if we are implementing XON/XOFF, send the start character */
	if (I_IXOFF(tty)) {
		unsigned char start_char = START_CHAR(tty);
A
Alan Cox 已提交
2111 2112 2113 2114
		status = edge_write(tty, port, &start_char, 1);
		if (status <= 0) {
			dev_err(&port->dev, "%s - failed to write start character, %d\n", __func__, status);
		}
L
Linus Torvalds 已提交
2115 2116 2117 2118 2119 2120
	}
	/* if we are implementing RTS/CTS, restart reads */
	/* are the Edgeport will assert the RTS line */
	if (C_CRTSCTS(tty)) {
		status = restart_read(edge_port);
		if (status)
2121 2122 2123
			dev_err(&port->dev,
				"%s - read bulk usb_submit_urb failed: %d\n",
							__func__, status);
L
Linus Torvalds 已提交
2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150
	}

}

static void stop_read(struct edgeport_port *edge_port)
{
	unsigned long flags;

	spin_lock_irqsave(&edge_port->ep_lock, flags);

	if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING)
		edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPING;
	edge_port->shadow_mcr &= ~MCR_RTS;

	spin_unlock_irqrestore(&edge_port->ep_lock, flags);
}

static int restart_read(struct edgeport_port *edge_port)
{
	struct urb *urb;
	int status = 0;
	unsigned long flags;

	spin_lock_irqsave(&edge_port->ep_lock, flags);

	if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPED) {
		urb = edge_port->port->read_urb;
2151
		status = usb_submit_urb(urb, GFP_ATOMIC);
L
Linus Torvalds 已提交
2152 2153 2154 2155 2156 2157 2158 2159 2160
	}
	edge_port->ep_read_urb_state = EDGE_READ_URB_RUNNING;
	edge_port->shadow_mcr |= MCR_RTS;

	spin_unlock_irqrestore(&edge_port->ep_lock, flags);

	return status;
}

A
Alan Cox 已提交
2161 2162
static void change_port_settings(struct tty_struct *tty,
		struct edgeport_port *edge_port, struct ktermios *old_termios)
L
Linus Torvalds 已提交
2163
{
2164
	struct device *dev = &edge_port->port->dev;
L
Linus Torvalds 已提交
2165 2166 2167 2168
	struct ump_uart_config *config;
	int baud;
	unsigned cflag;
	int status;
2169
	int port_number = edge_port->port->port_number;
L
Linus Torvalds 已提交
2170

A
Alan Cox 已提交
2171
	config = kmalloc (sizeof (*config), GFP_KERNEL);
L
Linus Torvalds 已提交
2172
	if (!config) {
2173
		tty->termios = *old_termios;
L
Linus Torvalds 已提交
2174 2175 2176
		return;
	}

2177
	cflag = tty->termios.c_cflag;
L
Linus Torvalds 已提交
2178 2179 2180 2181 2182 2183 2184 2185 2186

	config->wFlags = 0;

	/* These flags must be set */
	config->wFlags |= UMP_MASK_UART_FLAGS_RECEIVE_MS_INT;
	config->wFlags |= UMP_MASK_UART_FLAGS_AUTO_START_ON_ERR;
	config->bUartMode = (__u8)(edge_port->bUartMode);

	switch (cflag & CSIZE) {
2187 2188
	case CS5:
		    config->bDataBits = UMP_UART_CHAR5BITS;
2189
		    dev_dbg(dev, "%s - data bits = 5\n", __func__);
2190 2191 2192
		    break;
	case CS6:
		    config->bDataBits = UMP_UART_CHAR6BITS;
2193
		    dev_dbg(dev, "%s - data bits = 6\n", __func__);
2194 2195 2196
		    break;
	case CS7:
		    config->bDataBits = UMP_UART_CHAR7BITS;
2197
		    dev_dbg(dev, "%s - data bits = 7\n", __func__);
2198 2199 2200 2201
		    break;
	default:
	case CS8:
		    config->bDataBits = UMP_UART_CHAR8BITS;
2202
		    dev_dbg(dev, "%s - data bits = 8\n", __func__);
L
Linus Torvalds 已提交
2203 2204 2205 2206 2207 2208 2209
			    break;
	}

	if (cflag & PARENB) {
		if (cflag & PARODD) {
			config->wFlags |= UMP_MASK_UART_FLAGS_PARITY;
			config->bParity = UMP_UART_ODDPARITY;
2210
			dev_dbg(dev, "%s - parity = odd\n", __func__);
L
Linus Torvalds 已提交
2211 2212 2213
		} else {
			config->wFlags |= UMP_MASK_UART_FLAGS_PARITY;
			config->bParity = UMP_UART_EVENPARITY;
2214
			dev_dbg(dev, "%s - parity = even\n", __func__);
L
Linus Torvalds 已提交
2215 2216
		}
	} else {
2217
		config->bParity = UMP_UART_NOPARITY;
2218
		dev_dbg(dev, "%s - parity = none\n", __func__);
L
Linus Torvalds 已提交
2219 2220 2221 2222
	}

	if (cflag & CSTOPB) {
		config->bStopBits = UMP_UART_STOPBIT2;
2223
		dev_dbg(dev, "%s - stop bits = 2\n", __func__);
L
Linus Torvalds 已提交
2224 2225
	} else {
		config->bStopBits = UMP_UART_STOPBIT1;
2226
		dev_dbg(dev, "%s - stop bits = 1\n", __func__);
L
Linus Torvalds 已提交
2227 2228 2229 2230 2231 2232
	}

	/* figure out the flow control settings */
	if (cflag & CRTSCTS) {
		config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X_CTS_FLOW;
		config->wFlags |= UMP_MASK_UART_FLAGS_RTS_FLOW;
2233
		dev_dbg(dev, "%s - RTS/CTS is enabled\n", __func__);
L
Linus Torvalds 已提交
2234
	} else {
2235
		dev_dbg(dev, "%s - RTS/CTS is disabled\n", __func__);
L
Linus Torvalds 已提交
2236 2237 2238
		restart_read(edge_port);
	}

2239 2240 2241 2242
	/* if we are implementing XON/XOFF, set the start and stop
	   character in the device */
	config->cXon  = START_CHAR(tty);
	config->cXoff = STOP_CHAR(tty);
L
Linus Torvalds 已提交
2243

2244 2245 2246
	/* if we are implementing INBOUND XON/XOFF */
	if (I_IXOFF(tty)) {
		config->wFlags |= UMP_MASK_UART_FLAGS_IN_X;
2247 2248
		dev_dbg(dev, "%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x\n",
			__func__, config->cXon, config->cXoff);
2249
	} else
2250
		dev_dbg(dev, "%s - INBOUND XON/XOFF is disabled\n", __func__);
L
Linus Torvalds 已提交
2251

2252 2253 2254
	/* if we are implementing OUTBOUND XON/XOFF */
	if (I_IXON(tty)) {
		config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X;
2255 2256
		dev_dbg(dev, "%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x\n",
			__func__, config->cXon, config->cXoff);
2257
	} else
2258
		dev_dbg(dev, "%s - OUTBOUND XON/XOFF is disabled\n", __func__);
L
Linus Torvalds 已提交
2259

2260
	tty->termios.c_cflag &= ~CMSPAR;
A
Alan Cox 已提交
2261

L
Linus Torvalds 已提交
2262 2263 2264 2265 2266
	/* Round the baud rate */
	baud = tty_get_baud_rate(tty);
	if (!baud) {
		/* pick a default, any default... */
		baud = 9600;
A
Alan Cox 已提交
2267 2268 2269
	} else
		tty_encode_baud_rate(tty, baud, baud);

L
Linus Torvalds 已提交
2270 2271 2272
	edge_port->baud_rate = baud;
	config->wBaudRate = (__u16)((461550L + baud/2) / baud);

A
Alan Cox 已提交
2273 2274
	/* FIXME: Recompute actual baud from divisor here */

2275
	dev_dbg(dev, "%s - baud rate = %d, wBaudRate = %d\n", __func__, baud, config->wBaudRate);
L
Linus Torvalds 已提交
2276

2277 2278 2279 2280 2281 2282 2283 2284
	dev_dbg(dev, "wBaudRate:   %d\n", (int)(461550L / config->wBaudRate));
	dev_dbg(dev, "wFlags:    0x%x\n", config->wFlags);
	dev_dbg(dev, "bDataBits:   %d\n", config->bDataBits);
	dev_dbg(dev, "bParity:     %d\n", config->bParity);
	dev_dbg(dev, "bStopBits:   %d\n", config->bStopBits);
	dev_dbg(dev, "cXon:        %d\n", config->cXon);
	dev_dbg(dev, "cXoff:       %d\n", config->cXoff);
	dev_dbg(dev, "bUartMode:   %d\n", config->bUartMode);
L
Linus Torvalds 已提交
2285 2286

	/* move the word values into big endian mode */
2287 2288
	cpu_to_be16s(&config->wFlags);
	cpu_to_be16s(&config->wBaudRate);
L
Linus Torvalds 已提交
2289

2290
	status = send_cmd(edge_port->port->serial->dev, UMPC_SET_CONFIG,
L
Linus Torvalds 已提交
2291
				(__u8)(UMPM_UART1_PORT + port_number),
2292 2293
				0, (__u8 *)config, sizeof(*config));
	if (status)
2294 2295
		dev_dbg(dev, "%s - error %d when trying to write config to device\n",
			__func__, status);
2296
	kfree(config);
L
Linus Torvalds 已提交
2297 2298
}

A
Alan Cox 已提交
2299
static void edge_set_termios(struct tty_struct *tty,
A
Alan Cox 已提交
2300
		struct usb_serial_port *port, struct ktermios *old_termios)
L
Linus Torvalds 已提交
2301 2302
{
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
A
Alan Cox 已提交
2303 2304
	unsigned int cflag;

2305
	cflag = tty->termios.c_cflag;
L
Linus Torvalds 已提交
2306

2307
	dev_dbg(&port->dev, "%s - clfag %08x iflag %08x\n", __func__,
2308
		tty->termios.c_cflag, tty->termios.c_iflag);
2309 2310
	dev_dbg(&port->dev, "%s - old clfag %08x old iflag %08x\n", __func__,
		old_termios->c_cflag, old_termios->c_iflag);
L
Linus Torvalds 已提交
2311 2312 2313 2314

	if (edge_port == NULL)
		return;
	/* change the port settings to the new ones specified */
A
Alan Cox 已提交
2315
	change_port_settings(tty, edge_port, old_termios);
L
Linus Torvalds 已提交
2316 2317
}

2318
static int edge_tiocmset(struct tty_struct *tty,
2319
					unsigned int set, unsigned int clear)
L
Linus Torvalds 已提交
2320
{
A
Alan Cox 已提交
2321
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
2322 2323
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	unsigned int mcr;
2324
	unsigned long flags;
L
Linus Torvalds 已提交
2325

2326
	spin_lock_irqsave(&edge_port->ep_lock, flags);
L
Linus Torvalds 已提交
2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342
	mcr = edge_port->shadow_mcr;
	if (set & TIOCM_RTS)
		mcr |= MCR_RTS;
	if (set & TIOCM_DTR)
		mcr |= MCR_DTR;
	if (set & TIOCM_LOOP)
		mcr |= MCR_LOOPBACK;

	if (clear & TIOCM_RTS)
		mcr &= ~MCR_RTS;
	if (clear & TIOCM_DTR)
		mcr &= ~MCR_DTR;
	if (clear & TIOCM_LOOP)
		mcr &= ~MCR_LOOPBACK;

	edge_port->shadow_mcr = mcr;
2343
	spin_unlock_irqrestore(&edge_port->ep_lock, flags);
L
Linus Torvalds 已提交
2344

2345
	restore_mcr(edge_port, mcr);
L
Linus Torvalds 已提交
2346 2347 2348
	return 0;
}

2349
static int edge_tiocmget(struct tty_struct *tty)
L
Linus Torvalds 已提交
2350
{
A
Alan Cox 已提交
2351
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
2352 2353 2354 2355
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	unsigned int result = 0;
	unsigned int msr;
	unsigned int mcr;
2356
	unsigned long flags;
L
Linus Torvalds 已提交
2357

2358 2359
	spin_lock_irqsave(&edge_port->ep_lock, flags);

L
Linus Torvalds 已提交
2360 2361 2362 2363 2364 2365 2366 2367 2368 2369
	msr = edge_port->shadow_msr;
	mcr = edge_port->shadow_mcr;
	result = ((mcr & MCR_DTR)	? TIOCM_DTR: 0)	  /* 0x002 */
		  | ((mcr & MCR_RTS)	? TIOCM_RTS: 0)   /* 0x004 */
		  | ((msr & EDGEPORT_MSR_CTS)	? TIOCM_CTS: 0)   /* 0x020 */
		  | ((msr & EDGEPORT_MSR_CD)	? TIOCM_CAR: 0)   /* 0x040 */
		  | ((msr & EDGEPORT_MSR_RI)	? TIOCM_RI:  0)   /* 0x080 */
		  | ((msr & EDGEPORT_MSR_DSR)	? TIOCM_DSR: 0);  /* 0x100 */


2370
	dev_dbg(&port->dev, "%s -- %x\n", __func__, result);
2371
	spin_unlock_irqrestore(&edge_port->ep_lock, flags);
L
Linus Torvalds 已提交
2372 2373 2374 2375

	return result;
}

2376 2377
static int get_serial_info(struct edgeport_port *edge_port,
				struct serial_struct __user *retinfo)
L
Linus Torvalds 已提交
2378 2379
{
	struct serial_struct tmp;
2380
	unsigned cwait;
L
Linus Torvalds 已提交
2381 2382 2383 2384

	if (!retinfo)
		return -EFAULT;

2385 2386
	cwait = edge_port->port->port.closing_wait;
	if (cwait != ASYNC_CLOSING_WAIT_NONE)
J
Johan Hovold 已提交
2387
		cwait = jiffies_to_msecs(cwait) / 10;
2388

L
Linus Torvalds 已提交
2389 2390 2391
	memset(&tmp, 0, sizeof(tmp));

	tmp.type		= PORT_16550A;
2392
	tmp.line		= edge_port->port->minor;
2393
	tmp.port		= edge_port->port->port_number;
L
Linus Torvalds 已提交
2394 2395 2396 2397 2398
	tmp.irq			= 0;
	tmp.flags		= ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
	tmp.xmit_fifo_size	= edge_port->port->bulk_out_size;
	tmp.baud_base		= 9600;
	tmp.close_delay		= 5*HZ;
2399
	tmp.closing_wait	= cwait;
L
Linus Torvalds 已提交
2400 2401 2402 2403 2404 2405

	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
		return -EFAULT;
	return 0;
}

2406
static int edge_ioctl(struct tty_struct *tty,
2407
					unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
2408
{
A
Alan Cox 已提交
2409
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
2410 2411 2412
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);

	switch (cmd) {
2413
	case TIOCGSERIAL:
2414
		dev_dbg(&port->dev, "%s - TIOCGSERIAL\n", __func__);
2415 2416
		return get_serial_info(edge_port,
				(struct serial_struct __user *) arg);
L
Linus Torvalds 已提交
2417 2418 2419 2420
	}
	return -ENOIOCTLCMD;
}

A
Alan Cox 已提交
2421
static void edge_break(struct tty_struct *tty, int break_state)
L
Linus Torvalds 已提交
2422
{
A
Alan Cox 已提交
2423
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
2424 2425
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	int status;
2426
	int bv = 0;	/* Off */
L
Linus Torvalds 已提交
2427

A
Alan Cox 已提交
2428
	if (break_state == -1)
2429 2430 2431
		bv = 1;	/* On */
	status = ti_do_config(edge_port, UMPC_SET_CLR_BREAK, bv);
	if (status)
2432 2433
		dev_dbg(&port->dev, "%s - error %d sending break set/clear command.\n",
			__func__, status);
L
Linus Torvalds 已提交
2434 2435
}

2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465
static void edge_heartbeat_schedule(struct edgeport_serial *edge_serial)
{
	if (!edge_serial->use_heartbeat)
		return;

	schedule_delayed_work(&edge_serial->heartbeat_work,
			FW_HEARTBEAT_SECS * HZ);
}

static void edge_heartbeat_work(struct work_struct *work)
{
	struct edgeport_serial *serial;
	struct ti_i2c_desc *rom_desc;

	serial = container_of(work, struct edgeport_serial,
			heartbeat_work.work);

	rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);

	/* Descriptor address request is enough to reset the firmware timer */
	if (!rom_desc || !get_descriptor_addr(serial, I2C_DESC_TYPE_ION,
			rom_desc)) {
		dev_err(&serial->serial->interface->dev,
				"%s - Incomplete heartbeat\n", __func__);
	}
	kfree(rom_desc);

	edge_heartbeat_schedule(serial);
}

2466
static int edge_startup(struct usb_serial *serial)
L
Linus Torvalds 已提交
2467 2468 2469
{
	struct edgeport_serial *edge_serial;
	int status;
2470 2471 2472
	const struct firmware *fw;
	const char *fw_name = "edgeport/down3.bin";
	struct device *dev = &serial->interface->dev;
2473
	u16 product_id;
L
Linus Torvalds 已提交
2474 2475

	/* create our private serial structure */
2476
	edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL);
2477
	if (!edge_serial)
L
Linus Torvalds 已提交
2478
		return -ENOMEM;
2479

2480
	mutex_init(&edge_serial->es_lock);
L
Linus Torvalds 已提交
2481 2482 2483
	edge_serial->serial = serial;
	usb_set_serial_data(serial, edge_serial);

2484 2485 2486 2487 2488 2489 2490 2491 2492 2493
	status = request_firmware(&fw, fw_name, dev);
	if (status) {
		dev_err(dev, "Failed to load image \"%s\" err %d\n",
				fw_name, status);
		kfree(edge_serial);
		return status;
	}

	status = download_fw(edge_serial, fw);
	release_firmware(fw);
L
Linus Torvalds 已提交
2494
	if (status) {
2495
		kfree(edge_serial);
L
Linus Torvalds 已提交
2496 2497 2498
		return status;
	}

2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512
	product_id = le16_to_cpu(
			edge_serial->serial->dev->descriptor.idProduct);

	/* Currently only the EP/416 models require heartbeat support */
	if (edge_serial->fw_version > FW_HEARTBEAT_VERSION_CUTOFF) {
		if (product_id == ION_DEVICE_ID_TI_EDGEPORT_416 ||
			product_id == ION_DEVICE_ID_TI_EDGEPORT_416B) {
			edge_serial->use_heartbeat = true;
		}
	}

	INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work);
	edge_heartbeat_schedule(edge_serial);

L
Linus Torvalds 已提交
2513 2514 2515
	return 0;
}

2516
static void edge_disconnect(struct usb_serial *serial)
L
Linus Torvalds 已提交
2517
{
2518 2519 2520 2521
}

static void edge_release(struct usb_serial *serial)
{
2522 2523 2524 2525
	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);

	cancel_delayed_work_sync(&edge_serial->heartbeat_work);
	kfree(edge_serial);
2526 2527 2528 2529
}

static int edge_port_probe(struct usb_serial_port *port)
{
2530
	struct edgeport_port *edge_port;
2531
	int ret;
2532

2533 2534 2535 2536 2537 2538 2539 2540 2541
	edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL);
	if (!edge_port)
		return -ENOMEM;

	spin_lock_init(&edge_port->ep_lock);
	edge_port->port = port;
	edge_port->edge_serial = usb_get_serial_data(port->serial);
	edge_port->bUartMode = default_uart_mode;

2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561
	switch (port->port_number) {
	case 0:
		edge_port->uart_base = UMPMEM_BASE_UART1;
		edge_port->dma_address = UMPD_OEDB1_ADDRESS;
		break;
	case 1:
		edge_port->uart_base = UMPMEM_BASE_UART2;
		edge_port->dma_address = UMPD_OEDB2_ADDRESS;
		break;
	default:
		dev_err(&port->dev, "unknown port number\n");
		ret = -ENODEV;
		goto err;
	}

	dev_dbg(&port->dev,
		"%s - port_number = %d, uart_base = %04x, dma_address = %04x\n",
		__func__, port->port_number, edge_port->uart_base,
		edge_port->dma_address);

2562 2563
	usb_set_serial_port_data(port, edge_port);

2564
	ret = edge_create_sysfs_attrs(port);
2565 2566
	if (ret)
		goto err;
2567

2568
	port->port.closing_wait = msecs_to_jiffies(closing_wait * 10);
2569
	port->port.drain_delay = 1;
2570

2571
	return 0;
2572 2573 2574 2575
err:
	kfree(edge_port);

	return ret;
L
Linus Torvalds 已提交
2576 2577
}

2578 2579 2580 2581 2582 2583 2584 2585 2586 2587
static int edge_port_remove(struct usb_serial_port *port)
{
	struct edgeport_port *edge_port;

	edge_port = usb_get_serial_port_data(port);
	edge_remove_sysfs_attrs(port);
	kfree(edge_port);

	return 0;
}
L
Linus Torvalds 已提交
2588

2589 2590
/* Sysfs Attributes */

2591
static ssize_t uart_mode_show(struct device *dev,
2592 2593 2594 2595 2596 2597 2598 2599
	struct device_attribute *attr, char *buf)
{
	struct usb_serial_port *port = to_usb_serial_port(dev);
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);

	return sprintf(buf, "%d\n", edge_port->bUartMode);
}

2600
static ssize_t uart_mode_store(struct device *dev,
2601 2602 2603 2604 2605 2606
	struct device_attribute *attr, const char *valbuf, size_t count)
{
	struct usb_serial_port *port = to_usb_serial_port(dev);
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	unsigned int v = simple_strtoul(valbuf, NULL, 0);

2607
	dev_dbg(dev, "%s: setting uart_mode = %d\n", __func__, v);
2608 2609 2610 2611

	if (v < 256)
		edge_port->bUartMode = v;
	else
2612
		dev_err(dev, "%s - uart_mode %d is invalid\n", __func__, v);
2613 2614 2615

	return count;
}
2616
static DEVICE_ATTR_RW(uart_mode);
2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628

static int edge_create_sysfs_attrs(struct usb_serial_port *port)
{
	return device_create_file(&port->dev, &dev_attr_uart_mode);
}

static int edge_remove_sysfs_attrs(struct usb_serial_port *port)
{
	device_remove_file(&port->dev, &dev_attr_uart_mode);
	return 0;
}

2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647
#ifdef CONFIG_PM
static int edge_suspend(struct usb_serial *serial, pm_message_t message)
{
	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);

	cancel_delayed_work_sync(&edge_serial->heartbeat_work);

	return 0;
}

static int edge_resume(struct usb_serial *serial)
{
	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);

	edge_heartbeat_schedule(edge_serial);

	return 0;
}
#endif
2648

2649
static struct usb_serial_driver edgeport_1port_device = {
2650
	.driver = {
2651 2652
		.owner		= THIS_MODULE,
		.name		= "edgeport_ti_1",
2653
	},
2654
	.description		= "Edgeport TI 1 port adapter",
L
Linus Torvalds 已提交
2655 2656 2657 2658 2659 2660 2661
	.id_table		= edgeport_1port_id_table,
	.num_ports		= 1,
	.open			= edge_open,
	.close			= edge_close,
	.throttle		= edge_throttle,
	.unthrottle		= edge_unthrottle,
	.attach			= edge_startup,
2662 2663
	.disconnect		= edge_disconnect,
	.release		= edge_release,
2664 2665
	.port_probe		= edge_port_probe,
	.port_remove		= edge_port_remove,
L
Linus Torvalds 已提交
2666 2667 2668 2669
	.ioctl			= edge_ioctl,
	.set_termios		= edge_set_termios,
	.tiocmget		= edge_tiocmget,
	.tiocmset		= edge_tiocmset,
2670
	.tiocmiwait		= usb_serial_generic_tiocmiwait,
2671
	.get_icount		= usb_serial_generic_get_icount,
L
Linus Torvalds 已提交
2672 2673 2674
	.write			= edge_write,
	.write_room		= edge_write_room,
	.chars_in_buffer	= edge_chars_in_buffer,
2675
	.tx_empty		= edge_tx_empty,
L
Linus Torvalds 已提交
2676 2677 2678 2679
	.break_ctl		= edge_break,
	.read_int_callback	= edge_interrupt_callback,
	.read_bulk_callback	= edge_bulk_in_callback,
	.write_bulk_callback	= edge_bulk_out_callback,
2680 2681 2682 2683
#ifdef CONFIG_PM
	.suspend		= edge_suspend,
	.resume			= edge_resume,
#endif
L
Linus Torvalds 已提交
2684 2685
};

2686
static struct usb_serial_driver edgeport_2port_device = {
2687
	.driver = {
2688 2689
		.owner		= THIS_MODULE,
		.name		= "edgeport_ti_2",
2690
	},
2691
	.description		= "Edgeport TI 2 port adapter",
L
Linus Torvalds 已提交
2692 2693 2694 2695 2696 2697 2698
	.id_table		= edgeport_2port_id_table,
	.num_ports		= 2,
	.open			= edge_open,
	.close			= edge_close,
	.throttle		= edge_throttle,
	.unthrottle		= edge_unthrottle,
	.attach			= edge_startup,
2699 2700
	.disconnect		= edge_disconnect,
	.release		= edge_release,
2701 2702
	.port_probe		= edge_port_probe,
	.port_remove		= edge_port_remove,
L
Linus Torvalds 已提交
2703 2704 2705 2706
	.ioctl			= edge_ioctl,
	.set_termios		= edge_set_termios,
	.tiocmget		= edge_tiocmget,
	.tiocmset		= edge_tiocmset,
2707
	.tiocmiwait		= usb_serial_generic_tiocmiwait,
2708
	.get_icount		= usb_serial_generic_get_icount,
L
Linus Torvalds 已提交
2709 2710 2711
	.write			= edge_write,
	.write_room		= edge_write_room,
	.chars_in_buffer	= edge_chars_in_buffer,
2712
	.tx_empty		= edge_tx_empty,
L
Linus Torvalds 已提交
2713 2714 2715 2716
	.break_ctl		= edge_break,
	.read_int_callback	= edge_interrupt_callback,
	.read_bulk_callback	= edge_bulk_in_callback,
	.write_bulk_callback	= edge_bulk_out_callback,
2717 2718 2719 2720
#ifdef CONFIG_PM
	.suspend		= edge_suspend,
	.resume			= edge_resume,
#endif
L
Linus Torvalds 已提交
2721 2722
};

2723 2724 2725 2726
static struct usb_serial_driver * const serial_drivers[] = {
	&edgeport_1port_device, &edgeport_2port_device, NULL
};

2727
module_usb_serial_driver(serial_drivers, id_table_combined);
L
Linus Torvalds 已提交
2728 2729 2730 2731

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
2732
MODULE_FIRMWARE("edgeport/down3.bin");
L
Linus Torvalds 已提交
2733 2734 2735 2736 2737

module_param(closing_wait, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain, in .01 secs");

module_param(ignore_cpu_rev, bool, S_IRUGO | S_IWUSR);
2738 2739
MODULE_PARM_DESC(ignore_cpu_rev,
			"Ignore the cpu revision when connecting to a device");
L
Linus Torvalds 已提交
2740

2741 2742
module_param(default_uart_mode, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(default_uart_mode, "Default uart_mode, 0=RS232, ...");