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

📄 io_ti.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		status = TIReadManufDescriptor (serial, (__u8 *)ti_manuf_desc);		if (status) {			kfree (ti_manuf_desc);			goto StayInBootMode;		}		// Check for version 2		if (!ignore_cpu_rev && TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev) < 2) {			dbg ("%s - Wrong CPU Rev %d (Must be 2)", __FUNCTION__,			     TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev));			kfree (ti_manuf_desc);			goto StayInBootMode;		}		kfree (ti_manuf_desc);		// 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.				/*		 * Do we really have to copy the whole firmware image,		 * or could we do this in place!		 */		// 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);		if (!buffer) {			dev_err (dev, "%s - out of memory\n", __FUNCTION__);			return -ENOMEM;		}				// Initialize the buffer to 0xff (pad the buffer)		memset (buffer, 0xff, buffer_size);		memcpy (buffer, &PagableOperationalCodeImage[0], PagableOperationalCodeSize);		for(i = sizeof(struct ti_i2c_image_header); i < buffer_size; i++) {			cs = (__u8)(cs + buffer[i]);		}				header = (struct ti_i2c_image_header *)buffer;				// update length and checksum after padding		header->Length 	 = cpu_to_le16((__u16)(buffer_size - sizeof(struct ti_i2c_image_header)));		header->CheckSum = cs;		// Download the operational code 		dbg ("%s - Downloading operational code image (TI UMP)", __FUNCTION__);		status = TIDownloadCodeImage (serial, buffer, buffer_size);		kfree (buffer);		if (status) {	  		dbg ("%s - Error downloading operational code image", __FUNCTION__);			return status;		}		// Device will reboot		serial->product_info.TiMode = TI_MODE_TRANSITIONING;  		dbg ("%s - Download successful -- Device rebooting...", __FUNCTION__);		/* return an error on purpose */		return -ENODEV;	}StayInBootMode:	// Eprom is invalid or blank stay in boot mode	dbg ("%s - <<<<<<<<<<<<<<<STAYING IN BOOT MODE>>>>>>>>>>>>", __FUNCTION__);	serial->product_info.TiMode = TI_MODE_BOOT;	return 0;}static int TISetDtr (struct edgeport_port *port){	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	port->shadow_mcr |= MCR_DTR;	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_DTR,				(__u8)(UMPM_UART1_PORT + port_number),				1,	/* set */				NULL,				0);}static int TIClearDtr (struct edgeport_port *port){	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	port->shadow_mcr &= ~MCR_DTR;	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_DTR,				(__u8)(UMPM_UART1_PORT + port_number),				0,	/* clear */				NULL,				0);}static int TISetRts (struct edgeport_port *port){	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	port->shadow_mcr |= MCR_RTS;	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_RTS,				(__u8)(UMPM_UART1_PORT + port_number),				1,	/* set */				NULL,				0);}static int TIClearRts (struct edgeport_port *port){	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	port->shadow_mcr &= ~MCR_RTS;	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_RTS,				(__u8)(UMPM_UART1_PORT + port_number),				0,	/* clear */				NULL,				0);}static int TISetLoopBack (struct edgeport_port *port){	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_LOOPBACK,				(__u8)(UMPM_UART1_PORT + port_number),				1,	/* set */				NULL,				0);}static int TIClearLoopBack (struct edgeport_port *port){	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_LOOPBACK,				(__u8)(UMPM_UART1_PORT + port_number),				0,	/* clear */				NULL,				0);}static int TISetBreak (struct edgeport_port *port){	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_BREAK,				(__u8)(UMPM_UART1_PORT + port_number),				1,	/* set */				NULL,				0);}static int TIClearBreak (struct edgeport_port *port){	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_BREAK,				(__u8)(UMPM_UART1_PORT + port_number),				0,	/* clear */				NULL,				0);}static int TIRestoreMCR (struct edgeport_port *port, __u8 mcr){	int status = 0;	dbg ("%s - %x", __FUNCTION__, mcr);	if (mcr & MCR_DTR)		status = TISetDtr (port);	else		status = TIClearDtr (port);	if (status)		return status;	if (mcr & MCR_RTS)		status = TISetRts (port);	else		status = TIClearRts (port);	if (status)		return status;	if (mcr & MCR_LOOPBACK)		status = TISetLoopBack (port);	else		status = TIClearLoopBack (port);	return status;}/* Convert TI LSR to standard UART flags */static __u8 MapLineStatus (__u8 ti_lsr){	__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 */	MAP_FLAG(UMP_UART_LSR_RX_MASK, LSR_RX_AVAIL)	/* receive data available */	MAP_FLAG(UMP_UART_LSR_TX_MASK, LSR_TX_EMPTY)	/* transmit holding register empty */#undef MAP_FLAG	return lsr;}static void handle_new_msr (struct edgeport_port *edge_port, __u8 msr){	struct async_icount *icount;	struct tty_struct *tty;	dbg ("%s - %02x", __FUNCTION__, msr);	if (msr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) {		icount = &edge_port->icount;		/* 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++;		wake_up_interruptible (&edge_port->delta_msr_wait);	}	/* Save the new modem status */	edge_port->shadow_msr = msr & 0xf0;	tty = edge_port->port->tty;	/* handle CTS flow control */	if (tty && C_CRTSCTS(tty)) {		if (msr & EDGEPORT_MSR_CTS) {			tty->hw_stopped = 0;			tty_wakeup(tty);		} else {			tty->hw_stopped = 1;		}	}	return;}static void handle_new_lsr (struct edgeport_port *edge_port, int lsr_data, __u8 lsr, __u8 data){	struct async_icount *icount;	__u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK));	dbg ("%s - %02x", __FUNCTION__, new_lsr);	edge_port->shadow_lsr = lsr;	if (new_lsr & LSR_BREAK) {		/*		 * 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 */	if (lsr_data && edge_port->port->tty)		edge_tty_recv(&edge_port->port->dev, edge_port->port->tty, &data, 1);	/* update input line counters */	icount = &edge_port->icount;	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++;}static void edge_interrupt_callback (struct urb *urb, struct pt_regs *regs){	struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context;	struct usb_serial_port *port;	struct edgeport_port *edge_port;	unsigned char *data = urb->transfer_buffer;	int length = urb->actual_length;	int port_number;	int function;	int status;	__u8 lsr;	__u8 msr;	dbg("%s", __FUNCTION__);	switch (urb->status) {	case 0:		/* success */		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		/* this urb is terminated, clean up */		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);		return;	default:		dev_err(&urb->dev->dev, "%s - nonzero urb status received: %d\n", __FUNCTION__, urb->status);		goto exit;	}	if (!length) {		dbg ("%s - no data in urb", __FUNCTION__);		goto exit;	}			usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __FUNCTION__, length, data);			if (length != 2) {		dbg ("%s - expecting packet of size 2, got %d", __FUNCTION__, length);		goto exit;	}	port_number = TIUMP_GET_PORT_FROM_CODE (data[0]);	function    = TIUMP_GET_FUNC_FROM_CODE (data[0]);	dbg ("%s - port_number %d, function %d, info 0x%x",	     __FUNCTION__, port_number, function, data[1]);	port = edge_serial->serial->port[port_number];	edge_port = usb_get_serial_port_data(port);	if (!edge_port) {		dbg ("%s - edge_port not found", __FUNCTION__);		return;	}	switch (function) {	case TIUMP_INTERRUPT_CODE_LSR:		lsr = MapLineStatus(data[1]);		if (lsr & UMP_UART_LSR_DATA_MASK) {			/* Save the LSR event for bulk read completion routine */			dbg ("%s - LSR Event Port %u LSR Status = %02x",			     __FUNCTION__, port_number, lsr);			edge_port->lsr_event = 1;			edge_port->lsr_mask = lsr;		} else {			dbg ("%s - ===== Port %d LSR Status = %02x ======",			     __FUNCTION__, port_number, lsr);			handle_new_lsr (edge_port, 0, lsr, 0);		}		break;	case TIUMP_INTERRUPT_CODE_MSR:	// MSR		/* Copy MSR from UMP */		msr = data[1];		dbg ("%s - ===== Port %u MSR Status = %02x ======\n",		     __FUNCTION__, port_number, msr);		handle_new_msr (edge_port, msr);		break;	default:		dev_err (&urb->dev->dev, "%s - Unknown Interrupt code from UMP %x\n",			 __FUNCTION__, data[1]);		break;			}exit:	status = usb_submit_urb (urb, GFP_ATOMIC);	if (status)		dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n",			 __FUNCTION__, status);}static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs){	struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;	unsigned char *data = urb->transfer_buffer;	struct tty_struct *tty;	int status = 0;	int port_number;	dbg("%s", __FUNCTION__);	switch (urb->status) {	case 0:		/* success */		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		/* this urb is terminated, clean up */		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);		return;	default:		dev_err (&urb->dev->dev,"%s - nonzero read bulk status received: %d\n",		     __FUNCTION__, urb->status );	}	if (urb->status == -EPIPE)		goto exit;	if (urb->status) {		dev_err(&urb->dev->dev,"%s - stopping read!\n", __FUNCTION__);		return;	}	port_number = edge_port->port->number - edge_port->port->serial->minor;	if (edge_port->lsr_event) {		edge_port->lsr_event = 0;		dbg ("%s ===== Port %u LSR Status = %02x, Data = %02x ======",		     __FUNCTION__, port_number, edge_port->lsr_mask, *data);		handle_new_lsr (edge_port, 1, edge_port->lsr_mask, *data);		/* Adjust buffer length/pointer */		--urb->actual_length;		++data;	}	tty = edge_port->port->tty;

⌨️ 快捷键说明

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