📄 io_ti.c
字号:
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){ int loops; int last_count; int write_size;restart_tx_loop: // Base the LoopTime on the baud rate if (port->baud_rate == 0) port->baud_rate = 1200; write_size = port->tx.count; loops = max(100, (100*write_size)/(port->baud_rate/10)); dbg ("%s - write_size %d, baud %d loop = %d", __FUNCTION__, write_size, port->baud_rate, loops); while (1) { // Save Last count last_count = port->tx.count; dbg ("%s - Tx Buffer Size = %d loops = %d", __FUNCTION__, last_count, loops); /* Is the Edgeport Buffer empty? */ if (port->tx.count == 0) break; /* Block the thread for 10ms */ wait_ms (10); if (last_count == port->tx.count) { /* No activity.. count down. */ --loops; if (loops == 0) { dbg ("%s - Wait for TxEmpty - TIMEOUT", __FUNCTION__); return; } } else { /* Reset timeout value back to a minimum of 1 second */ dbg ("%s - Wait for TxEmpty Reset Count", __FUNCTION__); goto restart_tx_loop; } } dbg ("%s - Local Tx Buffer Empty -- Waiting for TI UMP to EMPTY X/Y and FIFO", __FUNCTION__); write_size = TIIsTxActive (port); loops = max(50, (100*write_size)/(port->baud_rate/10)); dbg ("%s - write_size %d, baud %d loop = %d", __FUNCTION__, write_size, port->baud_rate, loops); while (1) { /* This function takes 4 ms; */ if (!TIIsTxActive (port)) { /* Delay a few char times */ wait_ms (50); dbg ("%s - Empty", __FUNCTION__); return; } --loops; if (loops == 0) { dbg ("%s - TIMEOUT", __FUNCTION__); return; } }}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->bNumInterfaces); dbg ("%s - MAX Power = %d", __FUNCTION__, dev->config->MaxPower*2); if (dev->config->bNumInterfaces != 1) { err ("%s - bNumInterfaces is not 1, ERROR!", __FUNCTION__); return -ENODEV; } return 0;}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;}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){ int status = 0; struct ti_i2c_desc *rom_desc; int start_address = 2; __u8 *buffer; rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL); if (!rom_desc) { err ("%s - out of memory", __FUNCTION__); return -ENOMEM; } buffer = kmalloc (TI_MAX_I2C_SIZE, GFP_KERNEL); if (!buffer) { err ("%s - out of memory when allocating buffer", __FUNCTION__); kfree (rom_desc); return -ENOMEM; } // Read the first byte (Signature0) must be 0x52 status = TIReadRom (serial, 0, 1, buffer); if (status) goto ExitTiValidateI2cImage; if (*buffer != 0x52) { err ("%s - invalid buffer signature", __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 if ((rom_desc->Type & 0x0f) != I2C_DESC_TYPE_FIRMWARE_BASIC) { // 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) { err ("%s - out of memory", __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){ __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) { err ("%s - out of memory", __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)], img_header->Length); for (i=0; i < buffer_size; i++) { cs = (__u8)(cs + buffer[i]); } kfree (buffer); // Build new header i2c_header = (struct ti_i2c_desc *)header; firmware_rec = (struct ti_i2c_firmware_rec*)i2c_header->Data; i2c_header->Type = I2C_DESC_TYPE_FIRMWARE_BLANK; i2c_header->Size = (__u16)buffer_size; i2c_header->CheckSum = cs; firmware_rec->Ver_Major = OperationalCodeImageVersion.MajorVersion; firmware_rec->Ver_Minor = OperationalCodeImageVersion.MinorVersion; return 0;}/* Try to figure out what type of I2c we have */static int TIGetI2cTypeInBootMode (struct edgeport_serial *serial){ int status; __u8 data; // Try to read type 2 status = TIReadVendorRequestSync (serial->serial->dev, UMPC_MEMORY_READ, // Request DTK_ADDR_SPACE_I2C_TYPE_II, // wValue (Address type) 0, // wIndex &data, // TransferBuffer 0x01); // TransferBufferLength if (status) dbg ("%s - read 2 status error = %d", __FUNCTION__, status); else dbg ("%s - read 2 data = 0x%x", __FUNCTION__, data); if ((!status) && data == 0x52) { dbg ("%s - ROM_TYPE_II", __FUNCTION__); serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; return 0; } // Try to read type 3 status = TIReadVendorRequestSync (serial->serial->dev, UMPC_MEMORY_READ, // Request DTK_ADDR_SPACE_I2C_TYPE_III, // wValue (Address type) 0, // wIndex &data, // TransferBuffer 0x01); // TransferBufferLength if (status) dbg ("%s - read 3 status error = %d", __FUNCTION__, status); else dbg ("%s - read 2 data = 0x%x", __FUNCTION__, data); if ((!status) && data == 0x52) { dbg ("%s - ROM_TYPE_III", __FUNCTION__); serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_III; return 0; } dbg ("%s - Unknown", __FUNCTION__); serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; return -ENODEV;}static int TISendBulkTransferSync (struct usb_serial *serial, void *buffer, int length, int *num_sent){ int status; status = usb_bulk_msg (serial->dev, usb_sndbulkpipe(serial->dev, serial->port[0].bulk_out_endpointAddress), buffer, length, num_sent, HZ); return status;}/* Download given firmware image to the device (IN BOOT MODE) */static int TIDownloadCodeImage (struct edgeport_serial *serial, __u8 *image, int image_length){ int status = 0; int pos; int transfer; int done; // Transfer firmware image for (pos = 0; pos < image_length; ) { // Read the next buffer from file transfer = image_length - pos; if (transfer > EDGE_FW_BULK_MAX_PACKET_SIZE) transfer = EDGE_FW_BULK_MAX_PACKET_SIZE; // Transfer data status = TISendBulkTransferSync (serial->serial, &image[pos], transfer, &done); if (status) break; // Advance buffer pointer pos += done; } return status;}// FIXME!!!static int TIConfigureBootDevice (struct usb_device *dev){ return 0;}/** * DownloadTIFirmware - Download run-time operating firmware to the TI5052 * * This routine downloads the main operating code into the TI5052, using the * boot code already burned into E2PROM or ROM. */static int TIDownloadFirmware (struct edgeport_serial *serial){ int status = 0; int start_address; struct edge_ti_manuf_descriptor *ti_manuf_desc; struct usb_interface_descriptor *interface;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -