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

📄 io_edgeport.c

📁 基于S3CEB2410平台LINUX操作系统下 USB驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
//static DIVISOR_TABLE_ENTRY  DivisorTable[] = {	{   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	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);static void edge_bulk_in_callback	(struct urb *urb);static void edge_bulk_out_data_callback	(struct urb *urb);static void edge_bulk_out_cmd_callback	(struct urb *urb);/* 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, int from_user, 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_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 *//* function prototypes for all of our local functions */static int  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 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, short *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;                  	__u16 BootBuildNumber;	__u8 *BootImage;      	__u32 BootSize;	PEDGE_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		= 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		= 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) +		      edge_serial->boot_descriptor.BuildNumber;	BootNewVer = (BootMajorVersion << 24) +		     (BootMinorVersion << 16) +		      BootBuildNumber;	dbg("Current Boot Image version %d.%d.%d",	    edge_serial->boot_descriptor.MajorVersion,	    edge_serial->boot_descriptor.MinorVersion,	    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,		    edge_serial->boot_descriptor.BuildNumber,		    BootMajorVersion,		    BootMinorVersion,		    BootBuildNumber);		dbg("Downloading new Boot Image");		firmware = BootImage;		for (;;) {			record = (PEDGE_FIRMWARE_IMAGE_RECORD)firmware;			response = rom_write (edge_serial->serial, record->ExtAddr, record->Addr, record->Len, &record->Data[0]);			if (response < 0) {				err("sram_write failed (%x, %x, %d)", record->ExtAddr, record->Addr, record->Len);				break;			}			firmware += sizeof (EDGE_FIRMWARE_IMAGE_RECORD) + 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(__FUNCTION__ " - USB String ID = %d", 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;	}	unicode_to_ascii(string,  pStringDesc->wData,     pStringDesc->bLength/2-1);	kfree(pStringDesc);	return strlen(string);}#if 0/************************************************************************ * *  Get string descriptor from device * ************************************************************************/static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_descriptor **pRetDesc){	struct usb_string_descriptor StringDesc;	struct usb_string_descriptor *pStringDesc;	dbg(__FUNCTION__ " - USB String ID = %d", Id );	if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, sizeof(StringDesc))) {		return 0;	}	pStringDesc = kmalloc (StringDesc.bLength, GFP_KERNEL);	if (!pStringDesc) {		return -1;	}	if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc, StringDesc.bLength )) {		kfree(pStringDesc);		return -1;	}	*pRetDesc = pStringDesc;	return 0;}#endifstatic void get_product_info(struct edgeport_serial *edge_serial){	struct edgeport_product_info *product_info = &edge_serial->product_info;	memset (product_info, 0, sizeof(struct edgeport_product_info));	product_info->ProductId		= (__u16)(edge_serial->serial->dev->descriptor.idProduct & ~ION_DEVICE_ID_GENERATION_2);	product_info->NumPorts		= edge_serial->manuf_descriptor.NumPorts;	product_info->ProdInfoVer	= 0;	product_info->RomSize		= edge_serial->manuf_descriptor.RomSize;	product_info->RamSize		= edge_serial->manuf_descriptor.RamSize;	product_info->CpuRev		= edge_serial->manuf_descriptor.CpuRev;	product_info->BoardRev		= edge_serial->manuf_descriptor.BoardRev;	product_info->BootMajorVersion	= edge_serial->boot_descriptor.MajorVersion;	product_info->BootMinorVersion	= edge_serial->boot_descriptor.MinorVersion;	product_info->BootBuildNumber	= edge_serial->boot_descriptor.BuildNumber;	memcpy(product_info->ManufactureDescDate, edge_serial->manuf_descriptor.DescDate, sizeof(edge_serial->manuf_descriptor.DescDate));	// check if this is 2nd generation hardware	if (edge_serial->serial->dev->descriptor.idProduct & ION_DEVICE_ID_GENERATION_2) {		product_info->FirmwareMajorVersion	= OperationalCodeImageVersion_GEN2.MajorVersion;		product_info->FirmwareMinorVersion	= OperationalCodeImageVersion_GEN2.MinorVersion;		product_info->FirmwareBuildNumber	= OperationalCodeImageVersion_GEN2.BuildNumber;		product_info->iDownloadFile		= EDGE_DOWNLOAD_FILE_80251;	} else {		product_info->FirmwareMajorVersion	= OperationalCodeImageVersion_GEN1.MajorVersion;		product_info->FirmwareMinorVersion	= OperationalCodeImageVersion_GEN1.MinorVersion;		product_info->FirmwareBuildNumber	= OperationalCodeImageVersion_GEN1.BuildNumber;		product_info->iDownloadFile		= EDGE_DOWNLOAD_FILE_I930;	}	// Determine Product type and set appropriate flags	switch (DEVICE_ID_FROM_USB_PRODUCT_ID(product_info->ProductId)) {		case ION_DEVICE_ID_EDGEPORT_COMPATIBLE:		case ION_DEVICE_ID_EDGEPORT_4T:		case ION_DEVICE_ID_EDGEPORT_4:		case ION_DEVICE_ID_EDGEPORT_2:		case ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU:		case ION_DEVICE_ID_EDGEPORT_8:		case ION_DEVICE_ID_EDGEPORT_421:		case ION_DEVICE_ID_EDGEPORT_21:		case ION_DEVICE_ID_EDGEPORT_2_DIN:		case ION_DEVICE_ID_EDGEPORT_4_DIN:		case ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU:			product_info->IsRS232 = 1;			break;		case ION_DEVICE_ID_EDGEPORT_2I:				   // Edgeport/2 RS422/RS485			product_info->IsRS422 = 1;			product_info->IsRS485 = 1;			break;		case ION_DEVICE_ID_EDGEPORT_8I:				   // Edgeport/4 RS422		case ION_DEVICE_ID_EDGEPORT_4I:				   // Edgeport/4 RS422			product_info->IsRS422 = 1;			break;	}	// Dump Product Info structure	dbg("**Product Information:");	dbg("  ProductId             %x", product_info->ProductId );	dbg("  NumPorts              %d", product_info->NumPorts );	dbg("  ProdInfoVer           %d", product_info->ProdInfoVer );	dbg("  IsServer              %d", product_info->IsServer);	dbg("  IsRS232               %d", product_info->IsRS232 );	dbg("  IsRS422               %d", product_info->IsRS422 );	dbg("  IsRS485               %d", product_info->IsRS485 );	dbg("  RomSize               %d", product_info->RomSize );	dbg("  RamSize               %d", product_info->RamSize );	dbg("  CpuRev                %x", product_info->CpuRev  );	dbg("  BoardRev              %x", product_info->BoardRev);	dbg("  BootMajorVersion      %d.%d.%d", product_info->BootMajorVersion,	    product_info->BootMinorVersion,	    product_info->BootBuildNumber);	dbg("  FirmwareMajorVersion  %d.%d.%d", product_info->FirmwareMajorVersion,	    product_info->FirmwareMinorVersion,	    product_info->FirmwareBuildNumber);	dbg("  ManufactureDescDate   %d/%d/%d", product_info->ManufactureDescDate[0],	    product_info->ManufactureDescDate[1],	    product_info->ManufactureDescDate[2]+1900);	dbg("  iDownloadFile         0x%x",     product_info->iDownloadFile);}/************************************************************************//************************************************************************//*            U S B  C A L L B A C K   F U N C T I O N S                *//*            U S B  C A L L B A C K   F U N C T I O N S                *//************************************************************************//************************************************************************//***************************************************************************** * edge_interrupt_callback *	this is the callback function for when we have received data on the  *	interrupt endpoint. *****************************************************************************/static void edge_interrupt_callback (struct urb *urb){	struct edgeport_serial	*edge_serial = (struct edgeport_serial *)urb->context;	struct edgeport_port *edge_port;	struct usb_serial_port *port;	unsigned char *data = urb->transfer_buffer;	int length = urb->actual_length;	int bytes_avail;	int position;	int txCredits;	int portNumber;	int result;	dbg(__FUNCTION__);	if (serial_paranoia_check (edge_serial->serial, __FUNCTION__)) {		return;	}	if (urb->status) {		dbg(__FUNCTION__" - nonzero control read status received: %d", urb->status);		return;	}	// process this interrupt-read even if there are no ports open	if (length) {		usb_serial_debug_data (__FILE__, __FUNCTION__, length, data);		if (length > 1) {			bytes_avail = data[0] | (data[1] << 8);			if (bytes_avail) {				edge_serial->rxBytesAvail += bytes_avail;				dbg(__FUNCTION__" - bytes_avail = %d, rxBytesAvail %d", bytes_avail, edge_serial->rxBytesAvail);				if ((edge_serial->rxBytesAvail > 0) &&				    (edge_serial->read_urb->status != -EINPROGRESS)) {					dbg(" --- Posting a read");					/* we have pending bytes on the bulk in pipe, send a request */					edge_serial->read_urb->dev = edge_serial->serial->dev;					result = usb_submit_urb(edge_serial->read_urb);					if (result) {						dbg(__FUNCTION__" - usb_submit_urb(read bulk) failed with result = %d", result);					}				}			}		}		/* grab the txcredits for the ports if available */		position = 2;		portNumber = 0;		while ((position < length) && (portNumber < edge_serial->serial->num_ports)) {			txCredits = data[position] | (data[position+1] << 8);			if (txCredits) {				port = &edge_serial->serial->port[portNumber];				if (port_paranoia_check (port, __FUNCTION__) == 0) {					edge_port = (struct edgeport_port *)port->private;					if (edge_port->open) {						edge_port->txCredits += txCredits;						dbg(__FUNCTION__" - txcredits for port%d = %d", portNumber, edge_port->txCredits);						/* tell the tty driver that something has changed */						wake_up_interruptible(&edge_port->port->tty->write_wait);						// Since we have more credit, check if more data can be sent						send_more_port_data(edge_serial, edge_port);					}				}

⌨️ 快捷键说明

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