⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io_ti.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * 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>. * * Version history: * *	July 11, 2002 	Removed 4 port device structure since all TI UMP  *			chips have only 2 ports  *			David Iacovelli (davidi@ionetworks.com) * */#include <linux/config.h>#include <linux/kernel.h>#include <linux/jiffies.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/tty.h>#include <linux/tty_driver.h>#include <linux/tty_flip.h>#include <linux/module.h>#include <linux/spinlock.h>#include <linux/serial.h>#include <linux/ioctl.h>#include <asm/uaccess.h>#include <asm/semaphore.h>#include <linux/usb.h>#include "usb-serial.h"#include "io_16654.h"#include "io_usbvend.h"#include "io_ti.h"/* * Version Information */#define DRIVER_VERSION "v0.7"#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli"#define DRIVER_DESC "Edgeport USB Serial Driver"/* firmware image code */#define IMAGE_VERSION_NAME	PagableOperationalCodeImageVersion#define IMAGE_ARRAY_NAME	PagableOperationalCodeImage#define IMAGE_SIZE		PagableOperationalCodeSize#include "io_fw_down3.h"	/* Define array OperationalCodeImage[] */#define EPROM_PAGE_SIZE		64struct edgeport_uart_buf_desc {	__u32 count;		// Number of bytes currently in buffer};/* different hardware types */#define HARDWARE_TYPE_930	0#define HARDWARE_TYPE_TIUMP	1// 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/* read urb state */#define EDGE_READ_URB_RUNNING	0#define EDGE_READ_URB_STOPPING	1#define EDGE_READ_URB_STOPPED	2#define EDGE_LOW_LATENCY	1#define EDGE_CLOSING_WAIT	4000	/* in .01 sec */#define EDGE_OUT_BUF_SIZE	1024/* Product information read from the Edgeport */struct product_info{	int	TiMode;			// Current TI Mode	__u8	hardware_type;		// Type of hardware} __attribute__((packed));/* circular buffer */struct edge_buf {	unsigned int	buf_size;	char		*buf_buf;	char		*buf_get;	char		*buf_put;};struct edgeport_port {	__u16 uart_base;	__u16 dma_address;	__u8 shadow_msr;	__u8 shadow_mcr;	__u8 shadow_lsr;	__u8 lsr_mask;	__u32 ump_read_timeout;		/* Number of miliseconds the UMP will					   wait without data before completing					   a read short */	int baud_rate;	int close_pending;	int lsr_event;	struct edgeport_uart_buf_desc tx;	struct async_icount	icount;	wait_queue_head_t	delta_msr_wait;	/* for handling sleeping while						   waiting for msr change to						   happen */	struct edgeport_serial	*edge_serial;	struct usb_serial_port	*port;	__u8 bUartMode;		/* Port type, 0: RS232, etc. */ 	spinlock_t ep_lock;	int ep_read_urb_state;	int ep_write_urb_in_use;	struct edge_buf *ep_out_buf;};struct edgeport_serial {	struct product_info product_info;	u8 TI_I2C_Type;			// Type of I2C in UMP	u8 TiReadI2C;			// Set to TRUE if we have read the I2c in Boot Mode	struct semaphore es_sem;	int num_ports_open;	struct usb_serial *serial;};/* Devices that this driver supports */static struct usb_device_id edgeport_1port_id_table [] = {	{ 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) },	{ }};static struct usb_device_id edgeport_2port_id_table [] = {	{ 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) },// The 4-port shows up as two 2-port devices	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) },	{ }};/* Devices that this driver supports */static struct usb_device_id id_table_combined [] = {	{ 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) },	{ }};MODULE_DEVICE_TABLE (usb, id_table_combined);static struct usb_driver io_driver = {	.owner =	THIS_MODULE,	.name =		"io_ti",	.probe =	usb_serial_probe,	.disconnect =	usb_serial_disconnect,	.id_table =	id_table_combined,};static struct EDGE_FIRMWARE_VERSION_INFO OperationalCodeImageVersion;static int debug;static int TIStayInBootMode = 0;static int low_latency = EDGE_LOW_LATENCY;static int closing_wait = EDGE_CLOSING_WAIT;static int ignore_cpu_rev = 0;static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length);static void stop_read(struct edgeport_port *edge_port);static int restart_read(struct edgeport_port *edge_port);static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios);static void edge_send(struct usb_serial_port *port);/* circular buffer */static struct edge_buf *edge_buf_alloc(unsigned int size);static void edge_buf_free(struct edge_buf *eb);static void edge_buf_clear(struct edge_buf *eb);static unsigned int edge_buf_data_avail(struct edge_buf *eb);static unsigned int edge_buf_space_avail(struct edge_buf *eb);static unsigned int edge_buf_put(struct edge_buf *eb, const char *buf,	unsigned int count);static unsigned int edge_buf_get(struct edge_buf *eb, char *buf,	unsigned int count);static int TIReadVendorRequestSync (struct usb_device *dev,				__u8		request,				__u16		value,				__u16		index,				u8 		*data,				int		size){	int status;	status = usb_control_msg (dev,				usb_rcvctrlpipe(dev, 0),				request,				(USB_TYPE_VENDOR | 				 USB_RECIP_DEVICE | 				 USB_DIR_IN),				value,				index,				data,				size,				1000);	if (status < 0)		return status;	if (status != size) {		dbg ("%s - wanted to write %d, but only wrote %d",		     __FUNCTION__, size, status);		return -ECOMM;	}	return 0;}static int TISendVendorRequestSync (struct usb_device *dev,				__u8		request,				__u16		value,				__u16		index,				u8 		*data,				int		size){	int status;	status = usb_control_msg (dev,				usb_sndctrlpipe(dev, 0),				request,				(USB_TYPE_VENDOR | 				 USB_RECIP_DEVICE | 				 USB_DIR_OUT),				value,				index,				data,				size,				1000);	if (status < 0)		return status;	if (status != size) {		dbg ("%s - wanted to write %d, but only wrote %d",		     __FUNCTION__, size, status);		return -ECOMM;	}	return 0;}static int TIWriteCommandSync (struct usb_device *dev, __u8 command,				__u8 moduleid, __u16 value, u8 *data,				int size){	return TISendVendorRequestSync (dev,					  command,	  		// Request					  value,			// wValue 					  moduleid,			// wIndex					  data,				// TransferBuffer					  size);			// TransferBufferLength}/* clear tx/rx buffers and fifo in TI UMP */static int TIPurgeDataSync (struct usb_serial_port *port, __u16 mask){	int port_number = port->number - port->serial->minor;	dbg ("%s - port %d, mask %x", __FUNCTION__, port_number, mask);	return TIWriteCommandSync (port->serial->dev,					UMPC_PURGE_PORT,					(__u8)(UMPM_UART1_PORT + port_number),					mask,					NULL,					0);}/** * TIReadDownloadMemory - Read edgeport memory from TI chip * @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 */static int TIReadDownloadMemory(struct usb_device *dev, int start_address,				int length, __u8 address_type, __u8 *buffer){	int status = 0;	__u8 read_length;	__be16 be_start_address;		dbg ("%s - @ %x for %d", __FUNCTION__, start_address, length);	/* Read in blocks of 64 bytes	 * (TI firmware can't handle more than 64 byte reads)	 */	while (length) {		if (length > 64)			read_length= 64;		else			read_length = (__u8)length;		if (read_length > 1) {			dbg ("%s - @ %x for %d", __FUNCTION__, 			     start_address, read_length);		}		be_start_address = cpu_to_be16 (start_address);		status = TIReadVendorRequestSync (dev,						  UMPC_MEMORY_READ,	// Request						  (__u16)address_type,	// wValue (Address type)						  (__force __u16)be_start_address,	// wIndex (Address to read)						  buffer,		// TransferBuffer						  read_length);	// TransferBufferLength		if (status) {			dbg ("%s - ERROR %x", __FUNCTION__, status);			return status;		}		if (read_length > 1) {			usb_serial_debug_data(debug, &dev->dev, __FUNCTION__,					      read_length, buffer);		}		/* Update pointers/length */		start_address += read_length;		buffer += read_length;		length -= read_length;	}		return status;}static int TIReadRam (struct usb_device *dev, int start_address, int length, __u8 *buffer){	return TIReadDownloadMemory (dev,				     start_address,				     length,				     DTK_ADDR_SPACE_XDATA,				     buffer);}/* Read edgeport memory to a given block */static int TIReadBootMemory (struct edgeport_serial *serial, int start_address, int length, __u8 * buffer){	int status = 0;	int i;	for (i=0; i< length; i++) {		status = TIReadVendorRequestSync (serial->serial->dev,					UMPC_MEMORY_READ,		// Request					serial->TI_I2C_Type,		// wValue (Address type)					(__u16)(start_address+i),	// wIndex					&buffer[i],			// TransferBuffer					0x01);				// TransferBufferLength		if (status) {			dbg ("%s - ERROR %x", __FUNCTION__, status);			return status;		}	}	dbg ("%s - start_address = %x, length = %d", __FUNCTION__, start_address, length);	usb_serial_debug_data(debug, &serial->serial->dev->dev, __FUNCTION__, length, buffer);	serial->TiReadI2C = 1;	return status;}/* Write given block to TI EPROM memory */static int TIWriteBootMemory (struct edgeport_serial *serial, int start_address, int length, __u8 *buffer){	int status = 0;	int i;	__u8 temp;	/* Must do a read before write */	if (!serial->TiReadI2C) {		status = TIReadBootMemory(serial, 0, 1, &temp);		if (status)			return status;	}	for (i=0; i < length; ++i) {		status = TISendVendorRequestSync (serial->serial->dev,						UMPC_MEMORY_WRITE,		// Request						buffer[i],			// wValue						(__u16)(i+start_address),	// wIndex						NULL,				// TransferBuffer						0);				// TransferBufferLength		if (status)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -