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

📄 io_ti.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
			return status;	}  	dbg ("%s - start_sddr = %x, length = %d", __FUNCTION__, start_address, length);	usb_serial_debug_data(debug, &serial->serial->dev->dev, __FUNCTION__, length, buffer);	return status;}/* Write edgeport I2C memory to TI chip	*/static int TIWriteDownloadI2C (struct edgeport_serial *serial, int start_address, int length, __u8 address_type, __u8 *buffer){	int status = 0;	int write_length;	__be16 be_start_address;	/* We can only send a maximum of 1 aligned byte page at a time */		/* calulate the number of bytes left in the first page */	write_length = EPROM_PAGE_SIZE - (start_address & (EPROM_PAGE_SIZE - 1));	if (write_length > length)		write_length = length;	dbg ("%s - BytesInFirstPage Addr = %x, length = %d", __FUNCTION__, start_address, write_length);	usb_serial_debug_data(debug, &serial->serial->dev->dev, __FUNCTION__, write_length, buffer);	/* Write first page */	be_start_address = cpu_to_be16 (start_address);	status = TISendVendorRequestSync (serial->serial->dev,					UMPC_MEMORY_WRITE,	// Request					(__u16)address_type,	// wValue					(__force __u16)be_start_address,	// wIndex					buffer,			// TransferBuffer					write_length);	if (status) {		dbg ("%s - ERROR %d", __FUNCTION__, status);		return status;	}	length		-= write_length;	start_address	+= write_length;	buffer		+= write_length;	/* We should be aligned now -- can write max page size bytes at a time */	while (length) {		if (length > EPROM_PAGE_SIZE)			write_length = EPROM_PAGE_SIZE;		else			write_length = length;		dbg ("%s - Page Write Addr = %x, length = %d", __FUNCTION__, start_address, write_length);		usb_serial_debug_data(debug, &serial->serial->dev->dev, __FUNCTION__, write_length, buffer);		/* Write next page */		be_start_address = cpu_to_be16 (start_address);		status = TISendVendorRequestSync (serial->serial->dev,						UMPC_MEMORY_WRITE,	// Request						(__u16)address_type,	// wValue						(__force __u16)be_start_address,	// wIndex						buffer,	  		// TransferBuffer						write_length);		// TransferBufferLength		if (status) {			dev_err (&serial->serial->dev->dev, "%s - ERROR %d\n", __FUNCTION__, status);			return status;		}				length		-= write_length;		start_address	+= write_length;		buffer		+= write_length;	}	return status;}/* Examine the UMP DMA registers and LSR *  * 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. */static int TIIsTxActive (struct edgeport_port *port){	int status;	struct out_endpoint_desc_block *oedb;	__u8 *lsr;	int bytes_left = 0;	oedb = kmalloc (sizeof (* oedb), GFP_KERNEL);	if (!oedb) {		dev_err (&port->port->dev, "%s - out of memory\n", __FUNCTION__);		return -ENOMEM;	}	lsr = kmalloc (1, GFP_KERNEL);	/* Sigh, that's right, just one byte,					   as not all platforms can do DMA					   from stack */	if (!lsr) {		kfree(oedb);		return -ENOMEM;	}	/* Read the DMA Count Registers */	status = TIReadRam (port->port->serial->dev,			    port->dma_address,			    sizeof( *oedb),			    (void *)oedb);	if (status)		goto exit_is_tx_active;	dbg ("%s - XByteCount    0x%X", __FUNCTION__, oedb->XByteCount);	/* and the LSR */	status = TIReadRam (port->port->serial->dev, 			    port->uart_base + UMPMEM_OFFS_UART_LSR,			    1,			    lsr);	if (status)		goto exit_is_tx_active;	dbg ("%s - LSR = 0x%X", __FUNCTION__, *lsr);		/* If either buffer has data or we are transmitting then return TRUE */	if ((oedb->XByteCount & 0x80 ) != 0 )		bytes_left += 64;	if ((*lsr & UMP_UART_LSR_TX_MASK ) == 0 )		bytes_left += 1;	/* We return Not Active if we get any kind of error */exit_is_tx_active:	dbg ("%s - return %d", __FUNCTION__, bytes_left );	kfree(lsr);	kfree(oedb);	return bytes_left;}static void TIChasePort(struct edgeport_port *port, unsigned long timeout, int flush){	int baud_rate;	struct tty_struct *tty = port->port->tty;	wait_queue_t wait;	unsigned long flags;	if (!timeout)		timeout = (HZ*EDGE_CLOSING_WAIT)/100;	/* wait for data to drain from the buffer */	spin_lock_irqsave(&port->ep_lock, flags);	init_waitqueue_entry(&wait, current);	add_wait_queue(&tty->write_wait, &wait);	for (;;) {		set_current_state(TASK_INTERRUPTIBLE);		if (edge_buf_data_avail(port->ep_out_buf) == 0		|| timeout == 0 || signal_pending(current)		|| !usb_get_intfdata(port->port->serial->interface))  /* disconnect */			break;		spin_unlock_irqrestore(&port->ep_lock, flags);		timeout = schedule_timeout(timeout);		spin_lock_irqsave(&port->ep_lock, flags);	}	set_current_state(TASK_RUNNING);	remove_wait_queue(&tty->write_wait, &wait);	if (flush)		edge_buf_clear(port->ep_out_buf);	spin_unlock_irqrestore(&port->ep_lock, flags);	/* wait for data to drain from the device */	timeout += jiffies;	while ((long)(jiffies - timeout) < 0 && !signal_pending(current)	&& usb_get_intfdata(port->port->serial->interface)) {  /* not disconnected */		if (!TIIsTxActive(port))			break;		msleep(10);	}	/* disconnected */	if (!usb_get_intfdata(port->port->serial->interface))		return;	/* wait one more character time, based on baud rate */	/* (TIIsTxActive doesn't seem to wait for the last byte) */	if ((baud_rate=port->baud_rate) == 0)		baud_rate = 50;	msleep(max(1,(10000+baud_rate-1)/baud_rate));}static int TIChooseConfiguration (struct usb_device *dev){	// 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.	dbg ("%s - Number of Interfaces = %d", __FUNCTION__, dev->config->desc.bNumInterfaces);	dbg ("%s - MAX Power            = %d", __FUNCTION__, dev->config->desc.bMaxPower*2);	if (dev->config->desc.bNumInterfaces != 1) {		dev_err (&dev->dev, "%s - bNumInterfaces is not 1, ERROR!\n", __FUNCTION__);		return -ENODEV;	}	return 0;}static int TIReadRom (struct edgeport_serial *serial, int start_address, int length, __u8 *buffer){	int status;	if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) {		status = TIReadDownloadMemory (serial->serial->dev,					       start_address,					       length,					       serial->TI_I2C_Type,					       buffer);	} else {		status = TIReadBootMemory (serial,					   start_address,					   length,					   buffer);	}	return status;}static int TIWriteRom (struct edgeport_serial *serial, int start_address, int length, __u8 *buffer){	if (serial->product_info.TiMode == TI_MODE_BOOT)		return TIWriteBootMemory (serial,					  start_address,					  length,					  buffer);	if (serial->product_info.TiMode == TI_MODE_DOWNLOAD)		return TIWriteDownloadI2C (serial,					   start_address,					   length,					   serial->TI_I2C_Type,					   buffer);	return -EINVAL;}/* Read a descriptor header from I2C based on type */static int TIGetDescriptorAddress (struct edgeport_serial *serial, int desc_type, struct ti_i2c_desc *rom_desc){	int start_address;	int status;	/* Search for requested descriptor in I2C */	start_address = 2;	do {		status = TIReadRom (serial,				   start_address,				   sizeof(struct ti_i2c_desc),				   (__u8 *)rom_desc );		if (status)			return 0;		if (rom_desc->Type == desc_type)			return start_address;		start_address = start_address + sizeof(struct ti_i2c_desc) +  rom_desc->Size;	} while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type);		return 0;}/* Validate descriptor checksum */static int ValidChecksum(struct ti_i2c_desc *rom_desc, __u8 *buffer){	__u16 i;	__u8 cs = 0;	for (i=0; i < rom_desc->Size; i++) {		cs = (__u8)(cs + buffer[i]);	}	if (cs != rom_desc->CheckSum) {		dbg ("%s - Mismatch %x - %x", __FUNCTION__, rom_desc->CheckSum, cs);		return -EINVAL;	}	return 0;}/* Make sure that the I2C image is good */static int TiValidateI2cImage (struct edgeport_serial *serial){	struct device *dev = &serial->serial->dev->dev;	int status = 0;	struct ti_i2c_desc *rom_desc;	int start_address = 2;	__u8 *buffer;	__u16 ttype;	rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL);	if (!rom_desc) {		dev_err (dev, "%s - out of memory\n", __FUNCTION__);		return -ENOMEM;	}	buffer = kmalloc (TI_MAX_I2C_SIZE, GFP_KERNEL);	if (!buffer) {		dev_err (dev, "%s - out of memory when allocating buffer\n", __FUNCTION__);		kfree (rom_desc);		return -ENOMEM;	}	// Read the first byte (Signature0) must be 0x52 or 0x10	status = TIReadRom (serial, 0, 1, buffer);	if (status)		goto ExitTiValidateI2cImage; 	if (*buffer != UMP5152 && *buffer != UMP3410) {		dev_err (dev, "%s - invalid buffer signature\n", __FUNCTION__);		status = -ENODEV;		goto ExitTiValidateI2cImage;	}	do {		// Validate the I2C		status = TIReadRom (serial,				start_address,				sizeof(struct ti_i2c_desc),				(__u8 *)rom_desc);		if (status)			break;		if ((start_address + sizeof(struct ti_i2c_desc) + rom_desc->Size) > TI_MAX_I2C_SIZE) {			status = -ENODEV;			dbg ("%s - structure too big, erroring out.", __FUNCTION__);			break;		}		dbg ("%s Type = 0x%x", __FUNCTION__, rom_desc->Type);		// Skip type 2 record		ttype = rom_desc->Type & 0x0f;		if ( ttype != I2C_DESC_TYPE_FIRMWARE_BASIC			&& ttype != I2C_DESC_TYPE_FIRMWARE_AUTO ) {			// Read the descriptor data			status = TIReadRom(serial,						start_address+sizeof(struct ti_i2c_desc),						rom_desc->Size,						buffer);			if (status)				break;			status = ValidChecksum(rom_desc, buffer);			if (status)				break;		}		start_address = start_address + sizeof(struct ti_i2c_desc) + rom_desc->Size;	} while ((rom_desc->Type != I2C_DESC_TYPE_ION) && (start_address < TI_MAX_I2C_SIZE));	if ((rom_desc->Type != I2C_DESC_TYPE_ION) || (start_address > TI_MAX_I2C_SIZE))		status = -ENODEV;ExitTiValidateI2cImage:		kfree (buffer);	kfree (rom_desc);	return status;}static int TIReadManufDescriptor (struct edgeport_serial *serial, __u8 *buffer){	int status;	int start_address;	struct ti_i2c_desc *rom_desc;	struct edge_ti_manuf_descriptor *desc;	rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL);	if (!rom_desc) {		dev_err (&serial->serial->dev->dev, "%s - out of memory\n", __FUNCTION__);		return -ENOMEM;	}	start_address = TIGetDescriptorAddress (serial, I2C_DESC_TYPE_ION, rom_desc);	if (!start_address) {		dbg ("%s - Edge Descriptor not found in I2C", __FUNCTION__);		status = -ENODEV;		goto exit;	}	// Read the descriptor data	status = TIReadRom (serial,				start_address+sizeof(struct ti_i2c_desc),				rom_desc->Size,				buffer);	if (status)		goto exit;		status = ValidChecksum(rom_desc, buffer);		desc = (struct edge_ti_manuf_descriptor *)buffer;	dbg ( "%s - IonConfig      0x%x", __FUNCTION__, desc->IonConfig 	);	dbg ( "%s - Version          %d", __FUNCTION__, desc->Version	  	);	dbg ( "%s - Cpu/Board      0x%x", __FUNCTION__, desc->CpuRev_BoardRev	);	dbg ( "%s - NumPorts         %d", __FUNCTION__, desc->NumPorts  	);		dbg ( "%s - NumVirtualPorts  %d", __FUNCTION__, desc->NumVirtualPorts	);		dbg ( "%s - TotalPorts       %d", __FUNCTION__, desc->TotalPorts  	);	exit:	kfree (rom_desc);	return status;}/* Build firmware header used for firmware update */static int BuildI2CFirmwareHeader (__u8 *header, struct device *dev){	__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;	// 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);	if (!buffer) {		dev_err (dev, "%s - out of memory\n", __FUNCTION__);		return -ENOMEM;	}		// Set entire image of 0xffs	memset (buffer, 0xff, buffer_size);	// Copy version number into firmware record	firmware_rec = (struct ti_i2c_firmware_rec *)buffer;	firmware_rec->Ver_Major	= OperationalCodeImageVersion.MajorVersion;	firmware_rec->Ver_Minor	= OperationalCodeImageVersion.MinorVersion;	// Pointer to fw_down memory image	img_header = (struct ti_i2c_image_header *)&PagableOperationalCodeImage[0];	memcpy (buffer + sizeof(struct ti_i2c_firmware_rec),		&PagableOperationalCodeImage[sizeof(struct ti_i2c_image_header)],		le16_to_cpu(img_header->Length));	for (i=0; i < buffer_size; i++) {		cs = (__u8)(cs + buffer[i]);	}	kfree (buffer);

⌨️ 快捷键说明

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