📄 io_ti.c
字号:
// 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 == UMP5152 || data == UMP3410)) { 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 == UMP5152 || data == UMP3410)) { 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, 1000); 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){ struct device *dev = &serial->serial->dev->dev; int status = 0; int start_address; struct edge_ti_manuf_descriptor *ti_manuf_desc; struct usb_interface_descriptor *interface; int download_cur_ver; int download_new_ver; /* This routine is entered by both the BOOT mode and the Download mode * We can determine which code is running by the reading the config * descriptor and if we have only one bulk pipe it is in boot mode */ serial->product_info.hardware_type = HARDWARE_TYPE_TIUMP; /* Default to type 2 i2c */ serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; status = TIChooseConfiguration (serial->serial->dev); if (status) return status; interface = &serial->serial->interface->cur_altsetting->desc; if (!interface) { dev_err (dev, "%s - no interface set, error!\n", __FUNCTION__); return -ENODEV; } // Setup initial mode -- the default mode 0 is TI_MODE_CONFIGURING // if we have more than one endpoint we are definitely in download mode if (interface->bNumEndpoints > 1) serial->product_info.TiMode = TI_MODE_DOWNLOAD; else // Otherwise we will remain in configuring mode serial->product_info.TiMode = TI_MODE_CONFIGURING; // Save Download Version Number OperationalCodeImageVersion.MajorVersion = PagableOperationalCodeImageVersion.MajorVersion; OperationalCodeImageVersion.MinorVersion = PagableOperationalCodeImageVersion.MinorVersion; OperationalCodeImageVersion.BuildNumber = PagableOperationalCodeImageVersion.BuildNumber; /********************************************************************/ /* Download Mode */ /********************************************************************/ if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) { struct ti_i2c_desc *rom_desc; dbg ("%s - <<<<<<<<<<<<<<<RUNNING IN DOWNLOAD MODE>>>>>>>>>>", __FUNCTION__); status = TiValidateI2cImage (serial); if (status) { dbg ("%s - <<<<<<<<<<<<<<<DOWNLOAD MODE -- BAD I2C >>>>>>>>>>", __FUNCTION__); return status; } /* Validate Hardware version number * Read Manufacturing Descriptor from TI Based Edgeport */ ti_manuf_desc = kmalloc (sizeof (*ti_manuf_desc), GFP_KERNEL); if (!ti_manuf_desc) { dev_err (dev, "%s - out of memory.\n", __FUNCTION__); return -ENOMEM; } status = TIReadManufDescriptor (serial, (__u8 *)ti_manuf_desc); if (status) { kfree (ti_manuf_desc); return status; } // Check version number of ION descriptor 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); return -EINVAL; } rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL); if (!rom_desc) { dev_err (dev, "%s - out of memory.\n", __FUNCTION__); kfree (ti_manuf_desc); return -ENOMEM; } // Search for type 2 record (firmware record) if ((start_address = TIGetDescriptorAddress (serial, I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc)) != 0) { struct ti_i2c_firmware_rec *firmware_version; __u8 record; dbg ("%s - Found Type FIRMWARE (Type 2) record", __FUNCTION__); firmware_version = kmalloc (sizeof (*firmware_version), GFP_KERNEL); if (!firmware_version) { dev_err (dev, "%s - out of memory.\n", __FUNCTION__); kfree (rom_desc); kfree (ti_manuf_desc); return -ENOMEM; } // Validate version number // Read the descriptor data status = TIReadRom (serial, start_address+sizeof(struct ti_i2c_desc), sizeof(struct ti_i2c_firmware_rec), (__u8 *)firmware_version); if (status) { kfree (firmware_version); kfree (rom_desc); kfree (ti_manuf_desc); return status; } // Check version number of download with current version in I2c download_cur_ver = (firmware_version->Ver_Major << 8) + (firmware_version->Ver_Minor); download_new_ver = (OperationalCodeImageVersion.MajorVersion << 8) + (OperationalCodeImageVersion.MinorVersion); dbg ("%s - >>>Firmware Versions Device %d.%d Driver %d.%d", __FUNCTION__, firmware_version->Ver_Major, firmware_version->Ver_Minor, OperationalCodeImageVersion.MajorVersion, OperationalCodeImageVersion.MinorVersion); // Check if we have an old version in the I2C and update if necessary if (download_cur_ver != download_new_ver) { dbg ("%s - Update I2C Download from %d.%d to %d.%d", __FUNCTION__, firmware_version->Ver_Major, firmware_version->Ver_Minor, OperationalCodeImageVersion.MajorVersion, OperationalCodeImageVersion.MinorVersion); // 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. record = I2C_DESC_TYPE_FIRMWARE_BLANK; // Change the I2C Firmware record type to 0xf2 to trigger an update status = TIWriteRom (serial, start_address, sizeof(record), &record); if (status) { kfree (firmware_version); kfree (rom_desc); kfree (ti_manuf_desc); return status; } // verify the write -- must do this in order for write to // complete before we do the hardware reset status = TIReadRom (serial, start_address, sizeof(record), &record); if (status) { kfree (firmware_version); kfree (rom_desc); kfree (ti_manuf_desc); return status; } if (record != I2C_DESC_TYPE_FIRMWARE_BLANK) { dev_err (dev, "%s - error resetting device\n", __FUNCTION__); kfree (firmware_version); kfree (rom_desc); kfree (ti_manuf_desc); return -ENODEV; } dbg ("%s - HARDWARE RESET", __FUNCTION__); // Reset UMP -- Back to BOOT MODE status = TISendVendorRequestSync (serial->serial->dev, UMPC_HARDWARE_RESET, // Request 0, // wValue 0, // wIndex NULL, // TransferBuffer 0); // TransferBufferLength dbg ( "%s - HARDWARE RESET return %d", __FUNCTION__, status); /* return an error on purpose. */ kfree (firmware_version); kfree (rom_desc); kfree (ti_manuf_desc); return -ENODEV; } kfree (firmware_version); } // Search for type 0xF2 record (firmware blank record) else if ((start_address = TIGetDescriptorAddress (serial, I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc)) != 0) { #define HEADER_SIZE (sizeof(struct ti_i2c_desc) + sizeof(struct ti_i2c_firmware_rec)) __u8 *header; __u8 *vheader; header = kmalloc (HEADER_SIZE, GFP_KERNEL); if (!header) { dev_err (dev, "%s - out of memory.\n", __FUNCTION__); kfree (rom_desc); kfree (ti_manuf_desc); return -ENOMEM; } vheader = kmalloc (HEADER_SIZE, GFP_KERNEL); if (!vheader) { dev_err (dev, "%s - out of memory.\n", __FUNCTION__); kfree (header); kfree (rom_desc); kfree (ti_manuf_desc); return -ENOMEM; } dbg ("%s - Found Type BLANK FIRMWARE (Type F2) record", __FUNCTION__); // 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. status = BuildI2CFirmwareHeader(header, dev); if (status) { kfree (vheader); kfree (header); kfree (rom_desc); kfree (ti_manuf_desc); return status; } // Update I2C with type 0xf2 record with correct size and checksum status = TIWriteRom (serial, start_address, HEADER_SIZE, header); if (status) { kfree (vheader); kfree (header); kfree (rom_desc); kfree (ti_manuf_desc); return status; } // verify the write -- must do this in order for write to // complete before we do the hardware reset status = TIReadRom (serial, start_address, HEADER_SIZE, vheader); if (status) { dbg ("%s - can't read header back", __FUNCTION__); kfree (vheader); kfree (header); kfree (rom_desc); kfree (ti_manuf_desc); return status; } if (memcmp(vheader, header, HEADER_SIZE)) { dbg ("%s - write download record failed", __FUNCTION__); kfree (vheader); kfree (header); kfree (rom_desc); kfree (ti_manuf_desc); return status; } kfree (vheader); kfree (header); dbg ("%s - Start firmware update", __FUNCTION__); // Tell firmware to copy download image into I2C status = TISendVendorRequestSync (serial->serial->dev, UMPC_COPY_DNLD_TO_I2C, // Request 0, // wValue 0, // wIndex NULL, // TransferBuffer 0); // TransferBufferLength dbg ("%s - Update complete 0x%x", __FUNCTION__, status); if (status) { dev_err (dev, "%s - UMPC_COPY_DNLD_TO_I2C failed\n", __FUNCTION__); kfree (rom_desc); kfree (ti_manuf_desc); return status; } } // The device is running the download code kfree (rom_desc); kfree (ti_manuf_desc); return 0; } /********************************************************************/ /* Boot Mode */ /********************************************************************/ dbg ("%s - <<<<<<<<<<<<<<<RUNNING IN BOOT MODE>>>>>>>>>>>>>>>", __FUNCTION__); // Configure the TI device so we can use the BULK pipes for download status = TIConfigureBootDevice (serial->serial->dev); if (status) return status; if (le16_to_cpu(serial->serial->dev->descriptor.idVendor) != USB_VENDOR_ID_ION) { dbg ("%s - VID = 0x%x", __FUNCTION__, le16_to_cpu(serial->serial->dev->descriptor.idVendor)); serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; goto StayInBootMode; } // We have an ION device (I2c Must be programmed) // Determine I2C image type if (TIGetI2cTypeInBootMode(serial)) { goto StayInBootMode; } // Registry variable set? if (TIStayInBootMode) { dbg ("%s - TIStayInBootMode", __FUNCTION__); goto StayInBootMode; } // Check for ION Vendor ID and that the I2C is valid if (!TiValidateI2cImage(serial)) { struct ti_i2c_image_header *header; int i; __u8 cs = 0; __u8 *buffer; int buffer_size; /* Validate Hardware version number * Read Manufacturing Descriptor from TI Based Edgeport */ ti_manuf_desc = kmalloc (sizeof (*ti_manuf_desc), GFP_KERNEL); if (!ti_manuf_desc) { dev_err (dev, "%s - out of memory.\n", __FUNCTION__); return -ENOMEM;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -