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

📄 io_edgeport.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Edgeport USB Serial Converter driver * * Copyright (C) 2000 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: *	Edgeport/4 *	Edgeport/4t *	Edgeport/2 *	Edgeport/4i *	Edgeport/2i *	Edgeport/421 *	Edgeport/21 *	Rapidport/4 *	Edgeport/8 *	Edgeport/2D8 *	Edgeport/4D8 *	Edgeport/8i * * 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/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 <linux/wait.h>#include <asm/uaccess.h>#include <linux/usb.h>#include "usb-serial.h"#include "io_edgeport.h"#include "io_ionsp.h"		/* info for the iosp messages */#include "io_16654.h"		/* 16654 UART defines *//* * Version Information */#define DRIVER_VERSION "v2.7"#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli"#define DRIVER_DESC "Edgeport USB Serial Driver"/* First, the latest boot code - for first generation edgeports */#define IMAGE_ARRAY_NAME	BootCodeImage_GEN1#define IMAGE_VERSION_NAME	BootCodeImageVersion_GEN1#include "io_fw_boot.h"		/* the bootloader firmware to download to a device, if it needs it *//* for second generation edgeports */#define IMAGE_ARRAY_NAME	BootCodeImage_GEN2#define IMAGE_VERSION_NAME	BootCodeImageVersion_GEN2#include "io_fw_boot2.h"	/* the bootloader firmware to download to a device, if it needs it *//* Then finally the main run-time operational code - for first generation edgeports */#define IMAGE_ARRAY_NAME	OperationalCodeImage_GEN1#define IMAGE_VERSION_NAME	OperationalCodeImageVersion_GEN1#include "io_fw_down.h"		/* Define array OperationalCodeImage[] *//* for second generation edgeports */#define IMAGE_ARRAY_NAME	OperationalCodeImage_GEN2#define IMAGE_VERSION_NAME	OperationalCodeImageVersion_GEN2#include "io_fw_down2.h"	/* Define array OperationalCodeImage[] */#define MAX_NAME_LEN		64#define CHASE_TIMEOUT		(5*HZ)		/* 5 seconds */#define OPEN_TIMEOUT		(5*HZ)		/* 5 seconds */#define COMMAND_TIMEOUT		(5*HZ)		/* 5 seconds *//* receive port state */enum RXSTATE {	EXPECT_HDR1 = 0,	/* Expect header byte 1 */	EXPECT_HDR2 = 1,	/* Expect header byte 2 */	EXPECT_DATA = 2,	/* Expect 'RxBytesRemaining' data */	EXPECT_HDR3 = 3,	/* Expect header byte 3 (for status hdrs only) */};/* Transmit Fifo  * This Transmit queue is an extension of the edgeport Rx buffer.  * The maximum amount of data buffered in both the edgeport  * Rx buffer (maxTxCredits) and this buffer will never exceed maxTxCredits. */struct TxFifo {	unsigned int	head;	/* index to head pointer (write) */	unsigned int	tail;	/* index to tail pointer (read)  */	unsigned int	count;	/* Bytes in queue */	unsigned int	size;	/* Max size of queue (equal to Max number of TxCredits) */	unsigned char	*fifo;	/* allocated Buffer */};/* This structure holds all of the local port information */struct edgeport_port {	__u16			txCredits;		/* our current credits for this port */	__u16			maxTxCredits;		/* the max size of the port */	struct TxFifo		txfifo;			/* transmit fifo -- size will be maxTxCredits */	struct urb		*write_urb;		/* write URB for this port */	char			write_in_progress;	/* TRUE while a write URB is outstanding */	spinlock_t		ep_lock;	__u8			shadowLCR;		/* last LCR value received */	__u8			shadowMCR;		/* last MCR value received */	__u8			shadowMSR;		/* last MSR value received */	__u8			shadowLSR;		/* last LSR value received */	__u8			shadowXonChar;		/* last value set as XON char in Edgeport */	__u8			shadowXoffChar;		/* last value set as XOFF char in Edgeport */	__u8			validDataMask;	__u32			baudRate;	char			open;	char			openPending;	char			commandPending;	char			closePending;	char			chaseResponsePending;	wait_queue_head_t	wait_chase;		/* for handling sleeping while waiting for chase to finish */	wait_queue_head_t	wait_open;		/* for handling sleeping while waiting for open to finish */	wait_queue_head_t	wait_command;		/* for handling sleeping while waiting for command to finish */	wait_queue_head_t	delta_msr_wait;		/* for handling sleeping while waiting for msr change to happen */	struct async_icount	icount;	struct usb_serial_port	*port;			/* loop back to the owner of this object */};/* This structure holds all of the individual device information */struct edgeport_serial {	char			name[MAX_NAME_LEN+1];		/* string name of this device */	struct edge_manuf_descriptor	manuf_descriptor;	/* the manufacturer descriptor */	struct edge_boot_descriptor	boot_descriptor;	/* the boot firmware descriptor */	struct edgeport_product_info	product_info;		/* Product Info */	__u8			interrupt_in_endpoint;		/* the interrupt endpoint handle */	unsigned char *		interrupt_in_buffer;		/* the buffer we use for the interrupt endpoint */	struct urb *		interrupt_read_urb;		/* our interrupt urb */	__u8			bulk_in_endpoint;		/* the bulk in endpoint handle */	unsigned char *		bulk_in_buffer;			/* the buffer we use for the bulk in endpoint */	struct urb *		read_urb;			/* our bulk read urb */	int			read_in_progress;	spinlock_t		es_lock;	__u8			bulk_out_endpoint;		/* the bulk out endpoint handle */	__s16			rxBytesAvail;			/* the number of bytes that we need to read from this device */	enum RXSTATE		rxState;			/* the current state of the bulk receive processor */	__u8			rxHeader1;			/* receive header byte 1 */	__u8			rxHeader2;			/* receive header byte 2 */	__u8			rxHeader3;			/* receive header byte 3 */	__u8			rxPort;				/* the port that we are currently receiving data for */	__u8			rxStatusCode;			/* the receive status code */	__u8			rxStatusParam;			/* the receive status paramater */	__s16			rxBytesRemaining;		/* the number of port bytes left to read */	struct usb_serial	*serial;			/* loop back to the owner of this object */};/* baud rate information */struct divisor_table_entry {	__u32   BaudRate;	__u16  Divisor;};//// Define table of divisors for Rev A EdgePort/4 hardware// These assume a 3.6864MHz crystal, the standard /16, and// MCR.7 = 0.//static struct divisor_table_entry divisor_table[] = {	{   50,		4608},  	{   75,		3072},  	{   110,	2095},		/* 2094.545455 => 230450   => .0217 % over */	{   134,	1713},		/* 1713.011152 => 230398.5 => .00065% under */	{   150,	1536},	{   300,	768},	{   600,	384},	{   1200,	192},	{   1800,	128},	{   2400,	96},	{   4800,	48},	{   7200,	32},	{   9600,	24},	{   14400,	16},	{   19200,	12},	{   38400,	6},	{   57600,	4},	{   115200,	2},	{   230400,	1},};/* local variables */static int debug;static int low_latency = 1;	/* tty low latency flag, on by default */static int CmdUrbs = 0;		/* Number of outstanding Command Write Urbs *//* local function prototypes *//* function prototypes for all URB callbacks */static void edge_interrupt_callback	(struct urb *urb, struct pt_regs *regs);static void edge_bulk_in_callback	(struct urb *urb, struct pt_regs *regs);static void edge_bulk_out_data_callback	(struct urb *urb, struct pt_regs *regs);static void edge_bulk_out_cmd_callback	(struct urb *urb, struct pt_regs *regs);/* function prototypes for the usbserial callbacks */static int  edge_open			(struct usb_serial_port *port, struct file *filp);static void edge_close			(struct usb_serial_port *port, struct file *filp);static int  edge_write			(struct usb_serial_port *port, const unsigned char *buf, int count);static int  edge_write_room		(struct usb_serial_port *port);static int  edge_chars_in_buffer	(struct usb_serial_port *port);static void edge_throttle		(struct usb_serial_port *port);static void edge_unthrottle		(struct usb_serial_port *port);static void edge_set_termios		(struct usb_serial_port *port, struct termios *old_termios);static int  edge_ioctl			(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);static void edge_break			(struct usb_serial_port *port, int break_state);static int  edge_tiocmget		(struct usb_serial_port *port, struct file *file);static int  edge_tiocmset		(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);static int  edge_startup		(struct usb_serial *serial);static void edge_shutdown		(struct usb_serial *serial);#include "io_tables.h"	/* all of the devices that this driver supports */static struct usb_driver io_driver = {	.owner =	THIS_MODULE,	.name =		"io_edgeport",	.probe =	usb_serial_probe,	.disconnect =	usb_serial_disconnect,	.id_table =	id_table_combined,};/* function prototypes for all of our local functions */static void  process_rcvd_data		(struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength);static void process_rcvd_status		(struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3);static void edge_tty_recv			(struct device *dev, struct tty_struct *tty, unsigned char *data, int length);static void handle_new_msr		(struct edgeport_port *edge_port, __u8 newMsr);static void handle_new_lsr		(struct edgeport_port *edge_port, __u8 lsrData, __u8 lsr, __u8 data);static int  send_iosp_ext_cmd		(struct edgeport_port *edge_port, __u8 command, __u8 param);static int  calc_baud_rate_divisor	(int baud_rate, int *divisor);static int  send_cmd_write_baud_rate	(struct edgeport_port *edge_port, int baudRate);static void change_port_settings	(struct edgeport_port *edge_port, struct termios *old_termios);static int  send_cmd_write_uart_register	(struct edgeport_port *edge_port, __u8 regNum, __u8 regValue);static int  write_cmd_usb		(struct edgeport_port *edge_port, unsigned char *buffer, int writeLength);static void send_more_port_data		(struct edgeport_serial *edge_serial, struct edgeport_port *edge_port);static int  sram_write			(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data);static int  rom_read			(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data);static int  rom_write			(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data);static void get_manufacturing_desc	(struct edgeport_serial *edge_serial);static void get_boot_desc		(struct edgeport_serial *edge_serial);static void load_application_firmware	(struct edgeport_serial *edge_serial);static void unicode_to_ascii		(char *string, __le16 *unicode, int unicode_size);// ************************************************************************// ************************************************************************// ************************************************************************// ************************************************************************/************************************************************************ *									* * update_edgeport_E2PROM()	Compare current versions of		* *				Boot ROM and Manufacture 		* *				Descriptors with versions		* *				embedded in this driver			* *									* ************************************************************************/static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial){	__u32 BootCurVer;	__u32 BootNewVer;	__u8 BootMajorVersion;                  	__u8 BootMinorVersion;                  	__le16 BootBuildNumber;	__u8 *BootImage;      	__u32 BootSize;	struct edge_firmware_image_record *record;	unsigned char *firmware;	int response;	switch (edge_serial->product_info.iDownloadFile) {		case EDGE_DOWNLOAD_FILE_I930:			BootMajorVersion	= BootCodeImageVersion_GEN1.MajorVersion;			BootMinorVersion	= BootCodeImageVersion_GEN1.MinorVersion;			BootBuildNumber		= cpu_to_le16(BootCodeImageVersion_GEN1.BuildNumber);			BootImage		= &BootCodeImage_GEN1[0];			BootSize		= sizeof( BootCodeImage_GEN1 );			break;		case EDGE_DOWNLOAD_FILE_80251:			BootMajorVersion	= BootCodeImageVersion_GEN2.MajorVersion;			BootMinorVersion	= BootCodeImageVersion_GEN2.MinorVersion;			BootBuildNumber		= cpu_to_le16(BootCodeImageVersion_GEN2.BuildNumber);			BootImage		= &BootCodeImage_GEN2[0];			BootSize		= sizeof( BootCodeImage_GEN2 );			break;		default:			return;	}	// Check Boot Image Version	BootCurVer = (edge_serial->boot_descriptor.MajorVersion << 24) +		     (edge_serial->boot_descriptor.MinorVersion << 16) +		      le16_to_cpu(edge_serial->boot_descriptor.BuildNumber);	BootNewVer = (BootMajorVersion << 24) +		     (BootMinorVersion << 16) +		      le16_to_cpu(BootBuildNumber);	dbg("Current Boot Image version %d.%d.%d",	    edge_serial->boot_descriptor.MajorVersion,	    edge_serial->boot_descriptor.MinorVersion,	    le16_to_cpu(edge_serial->boot_descriptor.BuildNumber));	if (BootNewVer > BootCurVer) {		dbg("**Update Boot Image from %d.%d.%d to %d.%d.%d",		    edge_serial->boot_descriptor.MajorVersion,		    edge_serial->boot_descriptor.MinorVersion,		    le16_to_cpu(edge_serial->boot_descriptor.BuildNumber),		    BootMajorVersion,		    BootMinorVersion,		    le16_to_cpu(BootBuildNumber));		dbg("Downloading new Boot Image");		firmware = BootImage;		for (;;) {			record = (struct edge_firmware_image_record *)firmware;			response = rom_write (edge_serial->serial, le16_to_cpu(record->ExtAddr), le16_to_cpu(record->Addr), le16_to_cpu(record->Len), &record->Data[0]);			if (response < 0) {				dev_err(&edge_serial->serial->dev->dev, "rom_write failed (%x, %x, %d)\n", le16_to_cpu(record->ExtAddr), le16_to_cpu(record->Addr), le16_to_cpu(record->Len));				break;			}			firmware += sizeof (struct edge_firmware_image_record) + le16_to_cpu(record->Len);			if (firmware >= &BootImage[BootSize]) {				break;			}		}	} else {		dbg("Boot Image -- already up to date");	}}/************************************************************************ *									* *  Get string descriptor from device					* *									* ************************************************************************/static int get_string (struct usb_device *dev, int Id, char *string){	struct usb_string_descriptor StringDesc;	struct usb_string_descriptor *pStringDesc;	dbg("%s - USB String ID = %d", __FUNCTION__, Id );	if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, sizeof(StringDesc))) {		return 0;	}	pStringDesc = kmalloc (StringDesc.bLength, GFP_KERNEL);	if (!pStringDesc) {		return 0;	}	if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc, StringDesc.bLength )) {		kfree(pStringDesc);		return 0;

⌨️ 快捷键说明

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